Automated merge with file:///c:%5Ccode%5Cviewer-interesting-metrics
commit
433d53ea55
|
|
@ -161,7 +161,7 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer)
|
|||
|
||||
// ---------------- test methods ----------------
|
||||
|
||||
S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius)
|
||||
S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius, const LLPlane* planes)
|
||||
{
|
||||
static const LLVector4a scaler[] = {
|
||||
LLVector4a(-1,-1,-1),
|
||||
|
|
@ -174,6 +174,12 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius)
|
|||
LLVector4a( 1, 1, 1)
|
||||
};
|
||||
|
||||
if(!planes)
|
||||
{
|
||||
//use agent space
|
||||
planes = mAgentPlanes;
|
||||
}
|
||||
|
||||
U8 mask = 0;
|
||||
bool result = false;
|
||||
LLVector4a rscale, maxp, minp;
|
||||
|
|
@ -183,7 +189,7 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius)
|
|||
mask = mPlaneMask[i];
|
||||
if (mask != 0xff)
|
||||
{
|
||||
const LLPlane& p(mAgentPlanes[i]);
|
||||
const LLPlane& p(planes[i]);
|
||||
p.getAt<3>(d);
|
||||
rscale.setMul(radius, scaler[mask]);
|
||||
minp.setSub(center, rscale);
|
||||
|
|
@ -204,8 +210,14 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius)
|
|||
return result?1:2;
|
||||
}
|
||||
|
||||
//exactly same as the function AABBInFrustum(...)
|
||||
//except uses mRegionPlanes instead of mAgentPlanes.
|
||||
S32 LLCamera::AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius)
|
||||
{
|
||||
return AABBInFrustum(center, radius, mRegionPlanes);
|
||||
}
|
||||
|
||||
S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)
|
||||
S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes)
|
||||
{
|
||||
static const LLVector4a scaler[] = {
|
||||
LLVector4a(-1,-1,-1),
|
||||
|
|
@ -218,6 +230,12 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
|
|||
LLVector4a( 1, 1, 1)
|
||||
};
|
||||
|
||||
if(!planes)
|
||||
{
|
||||
//use agent space
|
||||
planes = mAgentPlanes;
|
||||
}
|
||||
|
||||
U8 mask = 0;
|
||||
bool result = false;
|
||||
LLVector4a rscale, maxp, minp;
|
||||
|
|
@ -227,7 +245,7 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
|
|||
mask = mPlaneMask[i];
|
||||
if ((i != 5) && (mask != 0xff))
|
||||
{
|
||||
const LLPlane& p(mAgentPlanes[i]);
|
||||
const LLPlane& p(planes[i]);
|
||||
p.getAt<3>(d);
|
||||
rscale.setMul(radius, scaler[mask]);
|
||||
minp.setSub(center, rscale);
|
||||
|
|
@ -248,6 +266,13 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
|
|||
return result?1:2;
|
||||
}
|
||||
|
||||
//exactly same as the function AABBInFrustumNoFarClip(...)
|
||||
//except uses mRegionPlanes instead of mAgentPlanes.
|
||||
S32 LLCamera::AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)
|
||||
{
|
||||
return AABBInFrustumNoFarClip(center, radius, mRegionPlanes);
|
||||
}
|
||||
|
||||
int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius)
|
||||
{
|
||||
LLVector3 dist = sphere_center-mFrustCenter;
|
||||
|
|
@ -584,6 +609,23 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
|
|||
}
|
||||
}
|
||||
|
||||
//calculate regional planes from mAgentPlanes.
|
||||
//vector "shift" is the vector of the region origin in the agent space.
|
||||
void LLCamera::calcRegionFrustumPlanes(const LLVector3& shift)
|
||||
{
|
||||
F32 d;
|
||||
LLVector3 n;
|
||||
for(S32 i = 0 ; i < 7; i++)
|
||||
{
|
||||
if (mPlaneMask[i] != 0xff)
|
||||
{
|
||||
n.setVec(mAgentPlanes[i][0], mAgentPlanes[i][1], mAgentPlanes[i][2]);
|
||||
d = mAgentPlanes[i][3] - n * shift;
|
||||
mRegionPlanes[i].setVec(n, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom)
|
||||
{
|
||||
LLVector3 a, b, c;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ public:
|
|||
|
||||
private:
|
||||
LL_ALIGN_16(LLPlane mAgentPlanes[7]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
|
||||
LL_ALIGN_16(LLPlane mRegionPlanes[7]); //frustum planes in a local region space, derived from mAgentPlanes
|
||||
U8 mPlaneMask[8]; // 8 for alignment
|
||||
|
||||
F32 mView; // angle between top and bottom frustum planes in radians.
|
||||
|
|
@ -178,6 +179,7 @@ public:
|
|||
// Return number of bytes copied.
|
||||
size_t readFrustumFromBuffer(const char *buffer);
|
||||
void calcAgentFrustumPlanes(LLVector3* frust);
|
||||
void calcRegionFrustumPlanes(const LLVector3& shift); //calculate regional planes from mAgentPlanes.
|
||||
void ignoreAgentFrustumPlane(S32 idx);
|
||||
|
||||
// Returns 1 if partly in, 2 if fully in.
|
||||
|
|
@ -186,8 +188,10 @@ public:
|
|||
S32 sphereInFrustum(const LLVector3 ¢er, const F32 radius) const;
|
||||
S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); }
|
||||
S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); }
|
||||
S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius);
|
||||
S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius);
|
||||
S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
|
||||
S32 AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius);
|
||||
S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
|
||||
S32 AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius);
|
||||
|
||||
//does a quick 'n dirty sphere-sphere check
|
||||
S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius);
|
||||
|
|
|
|||
|
|
@ -724,9 +724,14 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
|
|||
gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
|
||||
}
|
||||
|
||||
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
|
||||
void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color, const LLRectf& uv_rect)
|
||||
{
|
||||
if (NULL == image)
|
||||
gl_draw_scaled_rotated_image(x, y, width, height, 0.f, NULL, color, uv_rect, target);
|
||||
}
|
||||
|
||||
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect, LLRenderTarget* target)
|
||||
{
|
||||
if (!image && !target)
|
||||
{
|
||||
llwarns << "image == NULL; aborting function" << llendl;
|
||||
return;
|
||||
|
|
@ -734,8 +739,14 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
|||
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
|
||||
gGL.getTexUnit(0)->bind(image, true);
|
||||
if(image != NULL)
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(image, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(target);
|
||||
}
|
||||
|
||||
gGL.color4fv(color.mV);
|
||||
|
||||
|
|
@ -788,7 +799,14 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
|||
|
||||
LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
|
||||
|
||||
gGL.getTexUnit(0)->bind(image, true);
|
||||
if(image != NULL)
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(image, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(target);
|
||||
}
|
||||
|
||||
gGL.color4fv(color.mV);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ class LLUUID;
|
|||
class LLWindow;
|
||||
class LLView;
|
||||
class LLHelp;
|
||||
class LLRenderTarget;
|
||||
|
||||
// UI colors
|
||||
extern const LLColor4 UI_VERTEX_COLOR;
|
||||
|
|
@ -93,8 +94,9 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians,
|
|||
|
||||
void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), LLRenderTarget* target = NULL);
|
||||
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
|
||||
|
|
|
|||
|
|
@ -462,6 +462,7 @@ set(viewer_SOURCE_FILES
|
|||
llremoteparcelrequest.cpp
|
||||
llsavedsettingsglue.cpp
|
||||
llsaveoutfitcombobtn.cpp
|
||||
llscenemonitor.cpp
|
||||
llsceneview.cpp
|
||||
llscreenchannel.cpp
|
||||
llscriptfloater.cpp
|
||||
|
|
@ -586,6 +587,7 @@ set(viewer_SOURCE_FILES
|
|||
llviewernetwork.cpp
|
||||
llviewerobject.cpp
|
||||
llviewerobjectlist.cpp
|
||||
llvieweroctree.cpp
|
||||
llviewerparcelmedia.cpp
|
||||
llviewerparcelmediaautoplay.cpp
|
||||
llviewerparcelmgr.cpp
|
||||
|
|
@ -1028,6 +1030,7 @@ set(viewer_HEADER_FILES
|
|||
llrootview.h
|
||||
llsavedsettingsglue.h
|
||||
llsaveoutfitcombobtn.h
|
||||
llscenemonitor.h
|
||||
llsceneview.h
|
||||
llscreenchannel.h
|
||||
llscriptfloater.h
|
||||
|
|
@ -1152,6 +1155,7 @@ set(viewer_HEADER_FILES
|
|||
llviewernetwork.h
|
||||
llviewerobject.h
|
||||
llviewerobjectlist.h
|
||||
llvieweroctree.h
|
||||
llviewerparcelmedia.h
|
||||
llviewerparcelmediaautoplay.h
|
||||
llviewerparcelmgr.h
|
||||
|
|
|
|||
|
|
@ -6389,6 +6389,17 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>ObjectCacheViewCullingEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable the object cache view culling. Needs to restart viewer.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatAdvanced</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -9447,6 +9458,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SceneLoadingMonitorEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enabled scene loading monitor if set</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ScriptHelpFollowsCursor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10853,7 +10875,7 @@
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<integer>0.0</integer>
|
||||
<real>0.0</real>
|
||||
</map>
|
||||
<key>TextureFetchUpdateSkipLowPriority</key>
|
||||
<map>
|
||||
|
|
@ -12492,6 +12514,7 @@
|
|||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<array />
|
||||
</map>
|
||||
<key>VFSOldSize</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* @file onetexturefilterF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2D tex0;
|
||||
uniform float tolerance;
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
frag_color = texture2D(tex0, vary_texcoord0.xy);
|
||||
|
||||
if(frag_color[0] + frag_color[1] + frag_color[2] < tolerance)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
else
|
||||
{
|
||||
frag_color[3] = 0.95f;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* @file onetexturefilterV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_texcoord0 = texcoord0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @file twotexturecompareF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec2 vary_texcoord1;
|
||||
|
||||
void main()
|
||||
{
|
||||
frag_color = abs(texture2D(tex0, vary_texcoord0.xy) - texture2D(tex1, vary_texcoord0.xy));
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @file twotexturecompareV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
ATTRIBUTE vec2 texcoord1;
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec2 vary_texcoord1;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_texcoord0 = texcoord0;
|
||||
vary_texcoord1 = texcoord1;
|
||||
}
|
||||
|
||||
|
|
@ -3749,7 +3749,7 @@ U32 LLAppViewer::getObjectCacheVersion()
|
|||
{
|
||||
// Viewer object cache version, change if object update
|
||||
// format changes. JC
|
||||
const U32 INDRA_OBJECT_CACHE_VERSION = 14;
|
||||
const U32 INDRA_OBJECT_CACHE_VERSION = 15;
|
||||
|
||||
return INDRA_OBJECT_CACHE_VERSION;
|
||||
}
|
||||
|
|
@ -4333,11 +4333,6 @@ void LLAppViewer::idle()
|
|||
llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl;
|
||||
gObjectList.mNumDeadObjectUpdates = 0;
|
||||
}
|
||||
if (gObjectList.mNumUnknownKills)
|
||||
{
|
||||
llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl;
|
||||
gObjectList.mNumUnknownKills = 0;
|
||||
}
|
||||
if (gObjectList.mNumUnknownUpdates)
|
||||
{
|
||||
llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#include "llsceneview.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llfloaterreg.h"
|
||||
|
||||
#include "llscenemonitor.h"
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
|
@ -66,6 +66,7 @@ LLDebugView::~LLDebugView()
|
|||
gDebugView = NULL;
|
||||
gTextureView = NULL;
|
||||
gSceneView = NULL;
|
||||
gSceneMonitorView = NULL;
|
||||
}
|
||||
|
||||
void LLDebugView::init()
|
||||
|
|
@ -98,6 +99,13 @@ void LLDebugView::init()
|
|||
gSceneView->setVisible(FALSE);
|
||||
addChild(gSceneView);
|
||||
gSceneView->setRect(rect);
|
||||
|
||||
gSceneMonitorView = new LLSceneMonitorView(r);
|
||||
gSceneMonitorView->setFollowsTop();
|
||||
gSceneMonitorView->setFollowsLeft();
|
||||
gSceneMonitorView->setVisible(FALSE);
|
||||
addChild(gSceneMonitorView);
|
||||
gSceneMonitorView->setRect(rect);
|
||||
|
||||
r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f),
|
||||
(S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f));
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "llspatialpartition.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llvocache.h"
|
||||
|
||||
const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;
|
||||
const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
|
||||
|
|
@ -76,7 +77,6 @@ LLTrace::MemStat LLDrawable::sMemStat("LLDrawable");
|
|||
//
|
||||
|
||||
// static
|
||||
U32 LLDrawable::sCurVisible = 0;
|
||||
U32 LLDrawable::sNumZombieDrawables = 0;
|
||||
F32 LLDrawable::sCurPixelAngle = 0;
|
||||
LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
|
||||
|
|
@ -86,33 +86,59 @@ LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
|
|||
// static
|
||||
void LLDrawable::incrementVisible()
|
||||
{
|
||||
sCurVisible++;
|
||||
LLViewerOctreeEntryData::incrementVisible();
|
||||
sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView();
|
||||
}
|
||||
|
||||
void LLDrawable::init()
|
||||
LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry)
|
||||
: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE),
|
||||
mVObjp(vobj)
|
||||
{
|
||||
init(new_entry);
|
||||
}
|
||||
|
||||
void LLDrawable::init(bool new_entry)
|
||||
{
|
||||
// mXform
|
||||
mParent = NULL;
|
||||
mRenderType = 0;
|
||||
mCurrentScale = LLVector3(1,1,1);
|
||||
mDistanceWRTCamera = 0.0f;
|
||||
mPositionGroup.clear();
|
||||
mExtents[0].clear();
|
||||
mExtents[1].clear();
|
||||
|
||||
mDistanceWRTCamera = 0.0f;
|
||||
mState = 0;
|
||||
mVObjp = NULL;
|
||||
// mFaces
|
||||
mSpatialGroupp = NULL;
|
||||
mVisible = sCurVisible - 2;//invisible for the current frame and the last frame.
|
||||
mRadius = 0.f;
|
||||
|
||||
mGeneration = -1;
|
||||
mBinRadius = 1.f;
|
||||
mBinIndex = -1;
|
||||
|
||||
// mFaces
|
||||
mRadius = 0.f;
|
||||
mGeneration = -1;
|
||||
mSpatialBridge = NULL;
|
||||
|
||||
LLViewerOctreeEntry* entry = NULL;
|
||||
LLVOCacheEntry* vo_entry = NULL;
|
||||
if(!new_entry && mVObjp && getRegion() != NULL)
|
||||
{
|
||||
vo_entry = getRegion()->getCacheEntryForOctree(mVObjp->getLocalID());
|
||||
if(vo_entry)
|
||||
{
|
||||
entry = vo_entry->getEntry();
|
||||
}
|
||||
}
|
||||
setOctreeEntry(entry);
|
||||
if(vo_entry)
|
||||
{
|
||||
if(!entry)
|
||||
{
|
||||
vo_entry->setOctreeEntry(mEntry);
|
||||
}
|
||||
else if(vo_entry->getNumOfChildren() > 0)
|
||||
{
|
||||
getRegion()->addVisibleCacheEntry(vo_entry); //to load all children.
|
||||
}
|
||||
|
||||
getRegion()->addActiveCacheEntry(vo_entry);
|
||||
}
|
||||
|
||||
llassert(!vo_entry || vo_entry->getEntry() == mEntry);
|
||||
|
||||
initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -156,6 +182,7 @@ void LLDrawable::markDead()
|
|||
llwarns << "Warning! Marking dead multiple times!" << llendl;
|
||||
return;
|
||||
}
|
||||
setState(DEAD);
|
||||
|
||||
if (mSpatialBridge)
|
||||
{
|
||||
|
|
@ -165,8 +192,7 @@ void LLDrawable::markDead()
|
|||
|
||||
sNumZombieDrawables++;
|
||||
|
||||
// We're dead. Free up all of our references to other objects
|
||||
setState(DEAD);
|
||||
// We're dead. Free up all of our references to other objects
|
||||
cleanupReferences();
|
||||
// sDeadList.put(this);
|
||||
}
|
||||
|
|
@ -220,6 +246,8 @@ void LLDrawable::cleanupReferences()
|
|||
|
||||
gPipeline.unlinkDrawable(this);
|
||||
|
||||
removeFromOctree();
|
||||
|
||||
{
|
||||
LLFastTimer t(FTM_DEREF_DRAWABLE);
|
||||
// Cleanup references to other objects
|
||||
|
|
@ -228,6 +256,21 @@ void LLDrawable::cleanupReferences()
|
|||
}
|
||||
}
|
||||
|
||||
void LLDrawable::removeFromOctree()
|
||||
{
|
||||
if(!mEntry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mEntry->removeData(this);
|
||||
if(mEntry->hasVOCacheEntry())
|
||||
{
|
||||
getRegion()->removeActiveCacheEntry((LLVOCacheEntry*)mEntry->getVOCacheEntry(), this);
|
||||
}
|
||||
mEntry = NULL;
|
||||
}
|
||||
|
||||
void LLDrawable::cleanupDeadDrawables()
|
||||
{
|
||||
/*
|
||||
|
|
@ -428,7 +471,13 @@ void LLDrawable::makeActive()
|
|||
}
|
||||
updatePartition();
|
||||
}
|
||||
|
||||
else if (!isRoot() && !mParent->isActive()) //this should not happen, but occasionally it does...
|
||||
{
|
||||
mParent->makeActive();
|
||||
//NOTE: linked set will now NEVER become static
|
||||
mParent->setState(LLDrawable::ACTIVE_CHILD);
|
||||
}
|
||||
|
||||
llassert(isAvatar() || isRoot() || mParent->isActive());
|
||||
}
|
||||
|
||||
|
|
@ -717,7 +766,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
|
|||
LLVOVolume* volume = getVOVolume();
|
||||
if (volume)
|
||||
{
|
||||
if (getSpatialGroup())
|
||||
if (getGroup())
|
||||
{
|
||||
pos.set(getPositionGroup().getF32ptr());
|
||||
}
|
||||
|
|
@ -835,9 +884,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
|
|||
}
|
||||
}
|
||||
|
||||
mExtents[0].add(shift_vector);
|
||||
mExtents[1].add(shift_vector);
|
||||
mPositionGroup.add(shift_vector);
|
||||
shift(shift_vector);
|
||||
}
|
||||
else if (mSpatialBridge)
|
||||
{
|
||||
|
|
@ -845,9 +892,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
|
|||
}
|
||||
else if (isAvatar())
|
||||
{
|
||||
mExtents[0].add(shift_vector);
|
||||
mExtents[1].add(shift_vector);
|
||||
mPositionGroup.add(shift_vector);
|
||||
shift(shift_vector);
|
||||
}
|
||||
|
||||
mVObjp->onShift(shift_vector);
|
||||
|
|
@ -859,40 +904,24 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const
|
|||
return mXform.getPositionW();
|
||||
}
|
||||
|
||||
const LLVector4a* LLDrawable::getSpatialExtents() const
|
||||
{
|
||||
return mExtents;
|
||||
}
|
||||
|
||||
void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max)
|
||||
{
|
||||
mExtents[0].load3(min.mV);
|
||||
mExtents[1].load3(max.mV);
|
||||
}
|
||||
|
||||
void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max)
|
||||
{
|
||||
mExtents[0] = min;
|
||||
mExtents[1] = max;
|
||||
}
|
||||
|
||||
void LLDrawable::setPositionGroup(const LLVector4a& pos)
|
||||
{
|
||||
mPositionGroup = pos;
|
||||
}
|
||||
|
||||
void LLDrawable::updateSpatialExtents()
|
||||
{
|
||||
if (mVObjp)
|
||||
{
|
||||
mVObjp->updateSpatialExtents(mExtents[0], mExtents[1]);
|
||||
const LLVector4a* exts = getSpatialExtents();
|
||||
LLVector4a extents[2];
|
||||
extents[0] = exts[0];
|
||||
extents[1] = exts[1];
|
||||
|
||||
mVObjp->updateSpatialExtents(extents[0], extents[1]);
|
||||
setSpatialExtents(extents[0], extents[1]);
|
||||
}
|
||||
|
||||
updateBinRadius();
|
||||
|
||||
if (mSpatialBridge.notNull())
|
||||
{
|
||||
mPositionGroup.splat(0.f);
|
||||
getGroupPosition().splat(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -901,11 +930,11 @@ void LLDrawable::updateBinRadius()
|
|||
{
|
||||
if (mVObjp.notNull())
|
||||
{
|
||||
mBinRadius = llmin(mVObjp->getBinRadius(), 256.f);
|
||||
setBinRadius(llmin(mVObjp->getBinRadius(), 256.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
mBinRadius = llmin(getRadius()*4.f, 256.f);
|
||||
setBinRadius(llmin(getRadius()*4.f, 256.f));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -939,26 +968,56 @@ void LLDrawable::updateUVMinMax()
|
|||
{
|
||||
}
|
||||
|
||||
LLSpatialGroup* LLDrawable::getSpatialGroup() const
|
||||
{
|
||||
llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
|
||||
return mSpatialGroupp;
|
||||
//virtual
|
||||
bool LLDrawable::isVisible() const
|
||||
{
|
||||
if (LLViewerOctreeEntryData::isVisible())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
LLviewerOctreeGroup* group = mEntry->getGroup();
|
||||
if (group && group->isVisible())
|
||||
{
|
||||
LLViewerOctreeEntryData::setVisible();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
|
||||
//virtual
|
||||
bool LLDrawable::isRecentlyVisible() const
|
||||
{
|
||||
//precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this
|
||||
llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this));
|
||||
//currently visible or visible in the previous frame.
|
||||
bool vis = LLViewerOctreeEntryData::isRecentlyVisible();
|
||||
|
||||
if(!vis)
|
||||
{
|
||||
LLviewerOctreeGroup* group = getGroup();
|
||||
if (group && group->isRecentlyVisible())
|
||||
{
|
||||
LLViewerOctreeEntryData::setVisible();
|
||||
vis = TRUE ;
|
||||
}
|
||||
}
|
||||
|
||||
return vis ;
|
||||
}
|
||||
|
||||
void LLDrawable::setGroup(LLviewerOctreeGroup *groupp)
|
||||
{
|
||||
LLSpatialGroup* cur_groupp = (LLSpatialGroup*)getGroup();
|
||||
|
||||
//precondition: mGroupp MUST be null or DEAD or mGroupp MUST NOT contain this
|
||||
//llassert(!cur_groupp || cur_groupp->isDead() || !cur_groupp->hasElement(this));
|
||||
|
||||
//precondition: groupp MUST be null or groupp MUST contain this
|
||||
llassert(!groupp || groupp->hasElement(this));
|
||||
llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this));
|
||||
|
||||
/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
|
||||
{
|
||||
mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY);
|
||||
}*/
|
||||
|
||||
if (mSpatialGroupp != groupp && getVOVolume())
|
||||
if (cur_groupp != groupp && getVOVolume())
|
||||
{ //NULL out vertex buffer references for volumes on spatial group change to maintain
|
||||
//requirement that every face vertex buffer is either NULL or points to a vertex buffer
|
||||
//contained by its drawable's spatial group
|
||||
|
|
@ -974,10 +1033,10 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
|
|||
|
||||
//postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1
|
||||
//postcondition: if next group is NOT NULL, binIndex must not be -1
|
||||
llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 :
|
||||
getBinIndex() != -1);
|
||||
//llassert(groupp == NULL ? (cur_groupp == NULL || cur_groupp->isDead()) || (!getEntry() || getEntry()->getBinIndex() == -1) :
|
||||
// (getEntry() && getEntry()->getBinIndex() != -1));
|
||||
|
||||
mSpatialGroupp = groupp;
|
||||
LLViewerOctreeEntryData::setGroup(groupp);
|
||||
}
|
||||
|
||||
LLSpatialPartition* LLDrawable::getSpatialPartition()
|
||||
|
|
@ -996,11 +1055,11 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
|
|||
{
|
||||
if (mVObjp->isHUDAttachment())
|
||||
{
|
||||
setSpatialBridge(new LLHUDBridge(this));
|
||||
setSpatialBridge(new LLHUDBridge(this, getRegion()));
|
||||
}
|
||||
else
|
||||
{
|
||||
setSpatialBridge(new LLVolumeBridge(this));
|
||||
setSpatialBridge(new LLVolumeBridge(this, getRegion()));
|
||||
}
|
||||
}
|
||||
return mSpatialBridge->asPartition();
|
||||
|
|
@ -1019,89 +1078,26 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
|
|||
return retval;
|
||||
}
|
||||
|
||||
const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
|
||||
//static
|
||||
S32 LLDrawable::getMinVisFrameRange()
|
||||
//virtual
|
||||
S32 LLDrawable::getMinVisFrameRange() const
|
||||
{
|
||||
const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
|
||||
|
||||
return MIN_VIS_FRAME_RANGE ;
|
||||
}
|
||||
|
||||
BOOL LLDrawable::isRecentlyVisible() const
|
||||
{
|
||||
//currently visible or visible in the previous frame.
|
||||
BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ;
|
||||
|
||||
if(!vis)
|
||||
{
|
||||
LLSpatialGroup* group = getSpatialGroup();
|
||||
if (group && group->isRecentlyVisible())
|
||||
{
|
||||
mVisible = sCurVisible;
|
||||
vis = TRUE ;
|
||||
}
|
||||
}
|
||||
|
||||
return vis ;
|
||||
}
|
||||
|
||||
BOOL LLDrawable::isVisible() const
|
||||
{
|
||||
if (mVisible == sCurVisible)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//disabling this code fixes DEV-20105. Leaving in place in case some other bug pops up as a a result.
|
||||
//should be safe to just always ask the spatial group for visibility.
|
||||
if (isActive())
|
||||
{
|
||||
if (isRoot())
|
||||
{
|
||||
LLSpatialGroup* group = mSpatialBridge.notNull() ? mSpatialBridge->getSpatialGroup() :
|
||||
getSpatialGroup();
|
||||
if (group && group->isVisible())
|
||||
{
|
||||
mVisible = sCurVisible;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getParent()->isVisible())
|
||||
{
|
||||
mVisible = sCurVisible;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
LLSpatialGroup* group = getSpatialGroup();
|
||||
if (group && group->isVisible())
|
||||
{
|
||||
mVisible = sCurVisible;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=======================================
|
||||
// Spatial Partition Bridging Drawable
|
||||
//=======================================
|
||||
|
||||
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
|
||||
: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB)
|
||||
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) :
|
||||
LLDrawable(root->getVObj(), true),
|
||||
LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp)
|
||||
{
|
||||
mBridge = this;
|
||||
mDrawable = root;
|
||||
root->setSpatialBridge(this);
|
||||
|
||||
mBinIndex = -1;
|
||||
|
||||
mRenderType = mDrawable->mRenderType;
|
||||
mDrawableType = mDrawable->mRenderType;
|
||||
|
||||
|
|
@ -1122,10 +1118,13 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
|
|||
|
||||
LLSpatialBridge::~LLSpatialBridge()
|
||||
{
|
||||
LLSpatialGroup* group = getSpatialGroup();
|
||||
if (group)
|
||||
if(mEntry)
|
||||
{
|
||||
group->mSpatialPartition->remove(this, group);
|
||||
LLSpatialGroup* group = getSpatialGroup();
|
||||
if (group)
|
||||
{
|
||||
group->mSpatialPartition->remove(this, group);
|
||||
}
|
||||
}
|
||||
|
||||
//delete octree here so listeners will still be able to access bridge specific state
|
||||
|
|
@ -1147,8 +1146,9 @@ void LLSpatialBridge::updateSpatialExtents()
|
|||
root->rebound();
|
||||
}
|
||||
|
||||
const LLVector4a* root_bounds = root->getBounds();
|
||||
LLVector4a offset;
|
||||
LLVector4a size = root->mBounds[1];
|
||||
LLVector4a size = root_bounds[1];
|
||||
|
||||
//VECTORIZE THIS
|
||||
LLMatrix4a mat;
|
||||
|
|
@ -1160,7 +1160,7 @@ void LLSpatialBridge::updateSpatialExtents()
|
|||
LLVector4a center;
|
||||
mat.affineTransform(t, center);
|
||||
|
||||
mat.rotate(root->mBounds[0], offset);
|
||||
mat.rotate(root_bounds[0], offset);
|
||||
center.add(offset);
|
||||
|
||||
LLVector4a v[4];
|
||||
|
|
@ -1182,12 +1182,9 @@ void LLSpatialBridge::updateSpatialExtents()
|
|||
scale.mul(size);
|
||||
mat.rotate(scale, v[3]);
|
||||
|
||||
|
||||
LLVector4a& newMin = mExtents[0];
|
||||
LLVector4a& newMax = mExtents[1];
|
||||
|
||||
newMin = newMax = center;
|
||||
|
||||
LLVector4a newMin;
|
||||
LLVector4a newMax;
|
||||
newMin = newMax = center;
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
LLVector4a delta;
|
||||
|
|
@ -1200,19 +1197,21 @@ void LLSpatialBridge::updateSpatialExtents()
|
|||
newMin.setMin(newMin, min);
|
||||
newMax.setMax(newMax, max);
|
||||
}
|
||||
|
||||
setSpatialExtents(newMin, newMax);
|
||||
|
||||
LLVector4a diagonal;
|
||||
diagonal.setSub(newMax, newMin);
|
||||
mRadius = diagonal.getLength3().getF32() * 0.5f;
|
||||
|
||||
mPositionGroup.setAdd(newMin,newMax);
|
||||
mPositionGroup.mul(0.5f);
|
||||
LLVector4a& pos = getGroupPosition();
|
||||
pos.setAdd(newMin,newMax);
|
||||
pos.mul(0.5f);
|
||||
updateBinRadius();
|
||||
}
|
||||
|
||||
void LLSpatialBridge::updateBinRadius()
|
||||
{
|
||||
mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f);
|
||||
setBinRadius(llmin( mOctree->getSize()[0]*0.5f, 256.f));
|
||||
}
|
||||
|
||||
LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
|
||||
|
|
@ -1247,7 +1246,7 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
|
|||
|
||||
void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select)
|
||||
{
|
||||
mVisible = sCurVisible;
|
||||
LLViewerOctreeEntryData::setVisible();
|
||||
|
||||
#if 0 && !LL_RELEASE_FOR_DOWNLOAD
|
||||
//crazy paranoid rules checking
|
||||
|
|
@ -1282,21 +1281,21 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results,
|
|||
#endif
|
||||
}
|
||||
|
||||
class LLOctreeMarkNotCulled: public LLOctreeTraveler<LLDrawable>
|
||||
class LLOctreeMarkNotCulled: public OctreeTraveler
|
||||
{
|
||||
public:
|
||||
LLCamera* mCamera;
|
||||
|
||||
LLOctreeMarkNotCulled(LLCamera* camera_in) : mCamera(camera_in) { }
|
||||
|
||||
virtual void traverse(const LLOctreeNode<LLDrawable>* node)
|
||||
virtual void traverse(const OctreeNode* node)
|
||||
{
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
|
||||
group->setVisible();
|
||||
LLOctreeTraveler<LLDrawable>::traverse(node);
|
||||
OctreeTraveler::traverse(node);
|
||||
}
|
||||
|
||||
void visit(const LLOctreeNode<LLDrawable>* branch)
|
||||
void visit(const OctreeNode* branch)
|
||||
{
|
||||
gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera);
|
||||
}
|
||||
|
|
@ -1340,7 +1339,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
|
|||
}
|
||||
|
||||
if (!group ||
|
||||
LLDrawable::getCurrentFrame() - av->mVisible > 1 ||
|
||||
LLDrawable::getCurrentFrame() - av->getVisible() > 1 ||
|
||||
impostor ||
|
||||
!loaded)
|
||||
{
|
||||
|
|
@ -1354,16 +1353,17 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
|
|||
group->rebound();
|
||||
|
||||
LLVector4a center;
|
||||
center.setAdd(mExtents[0], mExtents[1]);
|
||||
const LLVector4a* exts = getSpatialExtents();
|
||||
center.setAdd(exts[0], exts[1]);
|
||||
center.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(mExtents[1], mExtents[0]);
|
||||
size.setSub(exts[1], exts[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) ||
|
||||
LLPipeline::sImpostorRender ||
|
||||
(camera_in.AABBInFrustumNoFarClip(center, size) &&
|
||||
AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)))
|
||||
AABBSphereIntersect(exts[0], exts[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)))
|
||||
{
|
||||
if (!LLPipeline::sImpostorRender &&
|
||||
!LLPipeline::sShadowRender &&
|
||||
|
|
@ -1478,9 +1478,7 @@ BOOL LLSpatialBridge::updateMove()
|
|||
|
||||
void LLSpatialBridge::shiftPos(const LLVector4a& vec)
|
||||
{
|
||||
mExtents[0].add(vec);
|
||||
mExtents[1].add(vec);
|
||||
mPositionGroup.add(vec);
|
||||
LLDrawable::shift(vec);
|
||||
}
|
||||
|
||||
void LLSpatialBridge::cleanupReferences()
|
||||
|
|
@ -1488,11 +1486,8 @@ void LLSpatialBridge::cleanupReferences()
|
|||
LLDrawable::cleanupReferences();
|
||||
if (mDrawable)
|
||||
{
|
||||
/*
|
||||
mDrawable->setGroup(NULL);
|
||||
|
||||
DON'T DO THIS -- this should happen through octree destruction
|
||||
|
||||
mDrawable->setSpatialGroup(NULL);
|
||||
if (mDrawable->getVObj())
|
||||
{
|
||||
LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
|
||||
|
|
@ -1503,10 +1498,10 @@ void LLSpatialBridge::cleanupReferences()
|
|||
LLDrawable* drawable = child->mDrawable;
|
||||
if (drawable)
|
||||
{
|
||||
drawable->setSpatialGroup(NULL);
|
||||
}
|
||||
drawable->setGroup(NULL);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
LLDrawable* drawablep = mDrawable;
|
||||
mDrawable = NULL;
|
||||
|
|
@ -1575,8 +1570,8 @@ void LLDrawable::updateFaceSize(S32 idx)
|
|||
}
|
||||
}
|
||||
|
||||
LLBridgePartition::LLBridgePartition()
|
||||
: LLSpatialPartition(0, FALSE, 0)
|
||||
LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp)
|
||||
: LLSpatialPartition(0, FALSE, 0, regionp)
|
||||
{
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
|
||||
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
|
||||
|
|
@ -1584,8 +1579,8 @@ LLBridgePartition::LLBridgePartition()
|
|||
mSlopRatio = 0.25f;
|
||||
}
|
||||
|
||||
LLHUDBridge::LLHUDBridge(LLDrawable* drawablep)
|
||||
: LLVolumeBridge(drawablep)
|
||||
LLHUDBridge::LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
|
||||
: LLVolumeBridge(drawablep, regionp)
|
||||
{
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_HUD;
|
||||
mPartitionType = LLViewerRegion::PARTITION_HUD;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "llviewerobject.h"
|
||||
#include "llrect.h"
|
||||
#include "llappviewer.h" // for gFrameTimeSeconds
|
||||
#include "llvieweroctree.h"
|
||||
|
||||
class LLCamera;
|
||||
class LLDrawPool;
|
||||
|
|
@ -60,11 +61,11 @@ const U32 SILHOUETTE_HIGHLIGHT = 0;
|
|||
// All data for new renderer goes into this class.
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLDrawable
|
||||
: public LLRefCount,
|
||||
public LLTrace::MemTrackable<LLDrawable, 16>
|
||||
: public LLViewerOctreeEntryData,
|
||||
public LLTrace::MemTrackable<LLDrawable>
|
||||
{
|
||||
public:
|
||||
LLDrawable(const LLDrawable& rhs)
|
||||
LLDrawable(const LLDrawable& rhs) : LLViewerOctreeEntryData(rhs)
|
||||
{
|
||||
*this = rhs;
|
||||
}
|
||||
|
|
@ -77,7 +78,7 @@ public:
|
|||
|
||||
static void initClass();
|
||||
|
||||
LLDrawable() { init(); }
|
||||
LLDrawable(LLViewerObject *vobj, bool new_entry = false);
|
||||
|
||||
void markDead(); // Mark this drawable as dead
|
||||
BOOL isDead() const { return isState(DEAD); }
|
||||
|
|
@ -85,11 +86,9 @@ public:
|
|||
|
||||
BOOL isLight() const;
|
||||
|
||||
BOOL isVisible() const;
|
||||
BOOL isRecentlyVisible() const;
|
||||
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
|
||||
|
||||
|
||||
LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();}
|
||||
LLViewerRegion* getRegion() const { return mVObjp->getRegion(); }
|
||||
const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); }
|
||||
LLPointer<LLViewerObject>& getVObj() { return mVObjp; }
|
||||
|
|
@ -102,16 +101,12 @@ public:
|
|||
const LLVector3& getPosition() const { return mXform.getPosition(); }
|
||||
const LLVector3& getWorldPosition() const { return mXform.getPositionW(); }
|
||||
const LLVector3 getPositionAgent() const;
|
||||
const LLVector4a& getPositionGroup() const { return mPositionGroup; }
|
||||
const LLVector3& getScale() const { return mCurrentScale; }
|
||||
void setScale(const LLVector3& scale) { mCurrentScale = scale; }
|
||||
const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); }
|
||||
const LLQuaternion& getRotation() const { return mXform.getRotation(); }
|
||||
F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); }
|
||||
S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; }
|
||||
F32 getBinRadius() const { return mBinRadius; }
|
||||
S32 getBinIndex() const { return mBinIndex; }
|
||||
void setBinIndex(S32 index) const { mBinIndex = index; }
|
||||
|
||||
void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }
|
||||
LLXformMatrix* getXform() { return &mXform; }
|
||||
|
|
@ -142,7 +137,7 @@ public:
|
|||
void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
|
||||
void mergeFaces(LLDrawable* src);
|
||||
|
||||
void init();
|
||||
void init(bool new_entry);
|
||||
void destroy();
|
||||
|
||||
void update();
|
||||
|
|
@ -173,8 +168,12 @@ public:
|
|||
BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; }
|
||||
void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); }
|
||||
|
||||
bool isVisible() const;
|
||||
bool isRecentlyVisible() const;
|
||||
|
||||
virtual void cleanupReferences();
|
||||
|
||||
void setGroup(LLviewerOctreeGroup* group);
|
||||
void setRadius(const F32 radius);
|
||||
F32 getRadius() const { return mRadius; }
|
||||
F32 getVisibilityRadius() const;
|
||||
|
|
@ -184,11 +183,6 @@ public:
|
|||
const LLVector3& getBounds(LLVector3& min, LLVector3& max) const;
|
||||
virtual void updateSpatialExtents();
|
||||
virtual void updateBinRadius();
|
||||
const LLVector4a* getSpatialExtents() const;
|
||||
void setSpatialExtents(const LLVector3& min, const LLVector3& max);
|
||||
void setSpatialExtents(const LLVector4a& min, const LLVector4a& max);
|
||||
|
||||
void setPositionGroup(const LLVector4a& pos);
|
||||
|
||||
void setRenderType(S32 type) { mRenderType = type; }
|
||||
BOOL isRenderType(S32 type) { return mRenderType == type; }
|
||||
|
|
@ -197,10 +191,14 @@ public:
|
|||
// Debugging methods
|
||||
S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators...
|
||||
|
||||
void setSpatialGroup(LLSpatialGroup *groupp);
|
||||
LLSpatialGroup *getSpatialGroup() const;
|
||||
LLSpatialPartition* getSpatialPartition();
|
||||
|
||||
virtual S32 getMinVisFrameRange()const;
|
||||
void removeFromOctree();
|
||||
|
||||
void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
|
||||
LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
|
||||
|
||||
// Statics
|
||||
static void incrementVisible();
|
||||
static void cleanupDeadDrawables();
|
||||
|
|
@ -285,10 +283,6 @@ public:
|
|||
ACTIVE_CHILD = 0x40000000,
|
||||
} EDrawableFlags;
|
||||
|
||||
private: //aligned members
|
||||
LL_ALIGN_16(LLVector4a mExtents[2]);
|
||||
LL_ALIGN_16(LLVector4a mPositionGroup);
|
||||
|
||||
public:
|
||||
LLXformMatrix mXform;
|
||||
|
||||
|
|
@ -297,12 +291,6 @@ public:
|
|||
|
||||
F32 mDistanceWRTCamera;
|
||||
|
||||
static S32 getCurrentFrame() { return sCurVisible; }
|
||||
static S32 getMinVisFrameRange();
|
||||
|
||||
void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
|
||||
LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
|
||||
|
||||
static F32 sCurPixelAngle; //current pixels per radian
|
||||
static LLTrace::MemStat sMemStat;
|
||||
|
||||
|
|
@ -313,18 +301,13 @@ private:
|
|||
S32 mRenderType;
|
||||
LLPointer<LLViewerObject> mVObjp;
|
||||
face_list_t mFaces;
|
||||
LLSpatialGroup* mSpatialGroupp;
|
||||
LLPointer<LLDrawable> mSpatialBridge;
|
||||
|
||||
mutable U32 mVisible;
|
||||
F32 mRadius;
|
||||
F32 mBinRadius;
|
||||
mutable S32 mBinIndex;
|
||||
S32 mGeneration;
|
||||
|
||||
LLVector3 mCurrentScale;
|
||||
|
||||
static U32 sCurVisible; // Counter for what value of mVisible means currently visible
|
||||
static U32 sNumZombieDrawables;
|
||||
static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList;
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,460 @@
|
|||
/**
|
||||
* @file llscenemonitor.cpp
|
||||
* @brief monitor the scene loading process.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llrendertarget.h"
|
||||
#include "llscenemonitor.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewerdisplay.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llui.h"
|
||||
#include "llstartup.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llwindow.h"
|
||||
#include "llpointer.h"
|
||||
#include "llspatialpartition.h"
|
||||
|
||||
LLSceneMonitorView* gSceneMonitorView = NULL;
|
||||
|
||||
//
|
||||
//The procedures of monitoring when the scene finishes loading visually,
|
||||
//i.e., no pixel differences among frames, are:
|
||||
//1, freeze all dynamic objects and avatars;
|
||||
//2, (?) disable all sky and water;
|
||||
//3, capture frames periodically, by calling "capture()";
|
||||
//4, compute pixel differences between two latest captured frames, by calling "compare()", results are stored at mDiff;
|
||||
//5, compute the number of pixels in mDiff above some tolerance threshold in GPU, by calling "queryDiff() -> calcDiffAggregate()";
|
||||
//6, use gl occlusion query to fetch the result from GPU, by calling "fetchQueryResult()";
|
||||
//END.
|
||||
//
|
||||
|
||||
LLSceneMonitor::LLSceneMonitor() :
|
||||
mEnabled(FALSE),
|
||||
mDiff(NULL),
|
||||
mDiffResult(0.f),
|
||||
mDiffTolerance(0.1f),
|
||||
mCurTarget(NULL),
|
||||
mNeedsUpdateDiff(FALSE),
|
||||
mHasNewDiff(FALSE),
|
||||
mHasNewQueryResult(FALSE),
|
||||
mDebugViewerVisible(FALSE),
|
||||
mQueryObject(0),
|
||||
mSamplingTime(1.0f),
|
||||
mDiffPixelRatio(0.5f)
|
||||
{
|
||||
mFrames[0] = NULL;
|
||||
mFrames[1] = NULL;
|
||||
}
|
||||
|
||||
LLSceneMonitor::~LLSceneMonitor()
|
||||
{
|
||||
destroyClass();
|
||||
}
|
||||
|
||||
void LLSceneMonitor::destroyClass()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void LLSceneMonitor::reset()
|
||||
{
|
||||
delete mFrames[0];
|
||||
delete mFrames[1];
|
||||
delete mDiff;
|
||||
|
||||
mFrames[0] = NULL;
|
||||
mFrames[1] = NULL;
|
||||
mDiff = NULL;
|
||||
mCurTarget = NULL;
|
||||
|
||||
unfreezeScene();
|
||||
|
||||
if(mQueryObject > 0)
|
||||
{
|
||||
release_occlusion_query_object_name(mQueryObject);
|
||||
mQueryObject = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLSceneMonitor::setDebugViewerVisible(BOOL visible)
|
||||
{
|
||||
mDebugViewerVisible = visible;
|
||||
}
|
||||
|
||||
bool LLSceneMonitor::preCapture()
|
||||
{
|
||||
static LLCachedControl<bool> monitor_enabled(gSavedSettings,"SceneLoadingMonitorEnabled");
|
||||
static LLFrameTimer timer;
|
||||
|
||||
mCurTarget = NULL;
|
||||
if (!LLGLSLShader::sNoFixedFunction)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL enabled = (BOOL)monitor_enabled || mDebugViewerVisible;
|
||||
if(mEnabled != enabled)
|
||||
{
|
||||
if(mEnabled)
|
||||
{
|
||||
reset();
|
||||
unfreezeScene();
|
||||
}
|
||||
else
|
||||
{
|
||||
freezeScene();
|
||||
}
|
||||
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
if(!mEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(timer.getElapsedTimeF32() < mSamplingTime)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
timer.reset();
|
||||
|
||||
S32 width = gViewerWindow->getWorldViewWidthRaw();
|
||||
S32 height = gViewerWindow->getWorldViewHeightRaw();
|
||||
|
||||
if(!mFrames[0])
|
||||
{
|
||||
mFrames[0] = new LLRenderTarget();
|
||||
mFrames[0]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
|
||||
gGL.getTexUnit(0)->bind(mFrames[0]);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
mCurTarget = mFrames[0];
|
||||
}
|
||||
else if(!mFrames[1])
|
||||
{
|
||||
mFrames[1] = new LLRenderTarget();
|
||||
mFrames[1]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
|
||||
gGL.getTexUnit(0)->bind(mFrames[1]);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
mCurTarget = mFrames[1];
|
||||
}
|
||||
else //swap
|
||||
{
|
||||
mCurTarget = mFrames[0];
|
||||
mFrames[0] = mFrames[1];
|
||||
mFrames[1] = mCurTarget;
|
||||
}
|
||||
|
||||
if(mCurTarget->getWidth() != width || mCurTarget->getHeight() != height) //size changed
|
||||
{
|
||||
mCurTarget->resize(width, height, GL_RGB);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLSceneMonitor::freezeAvatar(LLCharacter* avatarp)
|
||||
{
|
||||
mAvatarPauseHandles.push_back(avatarp->requestPause());
|
||||
}
|
||||
|
||||
void LLSceneMonitor::freezeScene()
|
||||
{
|
||||
//freeze all avatars
|
||||
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
|
||||
iter != LLCharacter::sInstances.end(); ++iter)
|
||||
{
|
||||
freezeAvatar((LLCharacter*)(*iter));
|
||||
}
|
||||
|
||||
// freeze everything else
|
||||
gSavedSettings.setBOOL("FreezeTime", TRUE);
|
||||
}
|
||||
|
||||
void LLSceneMonitor::unfreezeScene()
|
||||
{
|
||||
//thaw all avatars
|
||||
mAvatarPauseHandles.clear();
|
||||
|
||||
// thaw everything else
|
||||
gSavedSettings.setBOOL("FreezeTime", FALSE);
|
||||
}
|
||||
|
||||
void LLSceneMonitor::capture()
|
||||
{
|
||||
static U32 last_capture_time = 0;
|
||||
|
||||
if(last_capture_time == gFrameCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
last_capture_time = gFrameCount;
|
||||
|
||||
preCapture();
|
||||
|
||||
if(!mCurTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
U32 old_FBO = LLRenderTarget::sCurFBO;
|
||||
|
||||
gGL.getTexUnit(0)->bind(mCurTarget);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); //point to the main frame buffer.
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, mCurTarget->getWidth(), mCurTarget->getHeight()); //copy the content
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, old_FBO);
|
||||
|
||||
mCurTarget = NULL;
|
||||
mNeedsUpdateDiff = TRUE;
|
||||
}
|
||||
|
||||
bool LLSceneMonitor::needsUpdate() const
|
||||
{
|
||||
return mNeedsUpdateDiff;
|
||||
}
|
||||
|
||||
void LLSceneMonitor::compare()
|
||||
{
|
||||
if(!mNeedsUpdateDiff)
|
||||
{
|
||||
return;
|
||||
}
|
||||
mNeedsUpdateDiff = FALSE;
|
||||
|
||||
if(!mFrames[0] || !mFrames[1])
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(mFrames[0]->getWidth() != mFrames[1]->getWidth() || mFrames[0]->getHeight() != mFrames[1]->getHeight())
|
||||
{
|
||||
return; //size does not match
|
||||
}
|
||||
|
||||
S32 width = gViewerWindow->getWindowWidthRaw();
|
||||
S32 height = gViewerWindow->getWindowHeightRaw();
|
||||
if(!mDiff)
|
||||
{
|
||||
mDiff = new LLRenderTarget();
|
||||
mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true);
|
||||
}
|
||||
else if(mDiff->getWidth() != width || mDiff->getHeight() != height)
|
||||
{
|
||||
mDiff->resize(width, height, GL_RGBA);
|
||||
}
|
||||
|
||||
mDiff->bindTarget();
|
||||
mDiff->clear();
|
||||
|
||||
gTwoTextureCompareProgram.bind();
|
||||
|
||||
gGL.getTexUnit(0)->activate();
|
||||
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(0)->bind(mFrames[0]);
|
||||
gGL.getTexUnit(0)->activate();
|
||||
|
||||
gGL.getTexUnit(1)->activate();
|
||||
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(1)->bind(mFrames[1]);
|
||||
gGL.getTexUnit(1)->activate();
|
||||
|
||||
gl_rect_2d_simple_tex(width, height);
|
||||
|
||||
mDiff->flush();
|
||||
|
||||
gTwoTextureCompareProgram.unbind();
|
||||
|
||||
gGL.getTexUnit(0)->disable();
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(1)->disable();
|
||||
gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
mHasNewDiff = TRUE;
|
||||
|
||||
//send out the query request.
|
||||
queryDiff();
|
||||
}
|
||||
|
||||
void LLSceneMonitor::queryDiff()
|
||||
{
|
||||
if(mDebugViewerVisible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
calcDiffAggregate();
|
||||
}
|
||||
|
||||
//calculate Diff aggregate information in GPU, and enable gl occlusion query to capture it.
|
||||
void LLSceneMonitor::calcDiffAggregate()
|
||||
{
|
||||
if(!mHasNewDiff && !mDebugViewerVisible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!mQueryObject)
|
||||
{
|
||||
mQueryObject = get_new_occlusion_query_object_name();
|
||||
}
|
||||
|
||||
LLGLDepthTest depth(true, false, GL_ALWAYS);
|
||||
if(!mDebugViewerVisible)
|
||||
{
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
}
|
||||
|
||||
LLGLSLShader* cur_shader = NULL;
|
||||
|
||||
cur_shader = LLGLSLShader::sCurBoundShaderPtr;
|
||||
gOneTextureFilterProgram.bind();
|
||||
gOneTextureFilterProgram.uniform1f("tolerance", mDiffTolerance);
|
||||
|
||||
if(mHasNewDiff)
|
||||
{
|
||||
glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject);
|
||||
}
|
||||
|
||||
gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff);
|
||||
|
||||
if(mHasNewDiff)
|
||||
{
|
||||
glEndQueryARB(GL_SAMPLES_PASSED_ARB);
|
||||
mHasNewDiff = FALSE;
|
||||
mHasNewQueryResult = TRUE;
|
||||
}
|
||||
|
||||
gOneTextureFilterProgram.unbind();
|
||||
|
||||
if(cur_shader != NULL)
|
||||
{
|
||||
cur_shader->bind();
|
||||
}
|
||||
|
||||
if(!mDebugViewerVisible)
|
||||
{
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLSceneMonitor::fetchQueryResult()
|
||||
{
|
||||
if(!mHasNewQueryResult)
|
||||
{
|
||||
return;
|
||||
}
|
||||
mHasNewQueryResult = FALSE;
|
||||
|
||||
GLuint available = 0;
|
||||
glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available);
|
||||
if(!available)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint count = 0;
|
||||
glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_ARB, &count);
|
||||
|
||||
mDiffResult = count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio); //0.5 -> (front face + back face)
|
||||
|
||||
//llinfos << count << " : " << mDiffResult << llendl;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------
|
||||
//definition of class LLSceneMonitorView
|
||||
//-------------------------------------------------------------------------------------------------------------
|
||||
LLSceneMonitorView::LLSceneMonitorView(const LLRect& rect)
|
||||
: LLFloater(LLSD())
|
||||
{
|
||||
setRect(rect);
|
||||
setVisible(FALSE);
|
||||
|
||||
setCanMinimize(false);
|
||||
setCanClose(true);
|
||||
}
|
||||
|
||||
void LLSceneMonitorView::onClickCloseBtn()
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void LLSceneMonitorView::setVisible(BOOL visible)
|
||||
{
|
||||
LLSceneMonitor::getInstance()->setDebugViewerVisible(visible);
|
||||
|
||||
LLView::setVisible(visible);
|
||||
}
|
||||
|
||||
void LLSceneMonitorView::draw()
|
||||
{
|
||||
const LLRenderTarget* target = LLSceneMonitor::getInstance()->getDiffTarget();
|
||||
if(!target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
F32 ratio = LLSceneMonitor::getInstance()->getDiffPixelRatio();
|
||||
S32 height = (S32)(target->getHeight() * ratio);
|
||||
S32 width = (S32)(target->getWidth() * ratio);
|
||||
//S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.5f);
|
||||
//S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.5f);
|
||||
|
||||
LLRect new_rect;
|
||||
new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height);
|
||||
setRect(new_rect);
|
||||
|
||||
//draw background
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
|
||||
|
||||
LLSceneMonitor::getInstance()->calcDiffAggregate();
|
||||
|
||||
//show some texts
|
||||
LLColor4 color = LLColor4::white;
|
||||
S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
|
||||
|
||||
S32 lines = 0;
|
||||
std::string num_str = llformat("Frame difference: %.6f", LLSceneMonitor::getInstance()->getDiffResult());
|
||||
LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
lines++;
|
||||
|
||||
num_str = llformat("Pixel tolerance: (R+G+B) < %.4f", LLSceneMonitor::getInstance()->getDiffTolerance());
|
||||
LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
lines++;
|
||||
|
||||
num_str = llformat("Sampling time: %.3f seconds", LLSceneMonitor::getInstance()->getSamplingTime());
|
||||
LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
LLView::draw();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* @file llscenemonitor.h
|
||||
* @brief monitor the process of scene loading
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLSCENE_MONITOR_H
|
||||
#define LL_LLSCENE_MONITOR_H
|
||||
|
||||
#include "llsingleton.h"
|
||||
#include "llmath.h"
|
||||
#include "llfloater.h"
|
||||
#include "llcharacter.h"
|
||||
|
||||
class LLCharacter;
|
||||
class LLRenderTarget;
|
||||
|
||||
class LLSceneMonitor : public LLSingleton<LLSceneMonitor>
|
||||
{
|
||||
public:
|
||||
LLSceneMonitor();
|
||||
~LLSceneMonitor();
|
||||
|
||||
void destroyClass();
|
||||
|
||||
void freezeAvatar(LLCharacter* avatarp);
|
||||
void setDebugViewerVisible(BOOL visible);
|
||||
|
||||
void capture(); //capture the main frame buffer
|
||||
void compare(); //compare the stored two buffers.
|
||||
void queryDiff();
|
||||
void fetchQueryResult();
|
||||
void calcDiffAggregate();
|
||||
void setDiffTolerance(F32 tol) {mDiffTolerance = tol;}
|
||||
|
||||
const LLRenderTarget* getDiffTarget() const {return mDiff;}
|
||||
F32 getDiffTolerance() const {return mDiffTolerance;}
|
||||
F32 getDiffResult() const { return mDiffResult;}
|
||||
F32 getSamplingTime() const { return mSamplingTime;}
|
||||
F32 getDiffPixelRatio() const { return mDiffPixelRatio;}
|
||||
bool isEnabled()const {return mEnabled;}
|
||||
bool needsUpdate() const;
|
||||
|
||||
private:
|
||||
void freezeScene();
|
||||
void unfreezeScene();
|
||||
void reset();
|
||||
bool preCapture();
|
||||
|
||||
private:
|
||||
BOOL mEnabled;
|
||||
BOOL mNeedsUpdateDiff;
|
||||
BOOL mHasNewDiff;
|
||||
BOOL mHasNewQueryResult;
|
||||
BOOL mDebugViewerVisible;
|
||||
|
||||
LLRenderTarget* mFrames[2];
|
||||
LLRenderTarget* mDiff;
|
||||
LLRenderTarget* mCurTarget;
|
||||
|
||||
GLuint mQueryObject; //used for glQuery
|
||||
F32 mDiffResult; //aggregate results of mDiff.
|
||||
F32 mDiffTolerance; //pixels are filtered out when R+G+B < mDiffTolerance
|
||||
|
||||
F32 mSamplingTime; //time interval to capture frames, in seconds
|
||||
F32 mDiffPixelRatio; //ratio of pixels used for comparison against the original mDiff size along one dimension
|
||||
|
||||
std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
|
||||
};
|
||||
|
||||
class LLSceneMonitorView : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLSceneMonitorView(const LLRect& rect);
|
||||
|
||||
virtual void draw();
|
||||
virtual void setVisible(BOOL visible);
|
||||
|
||||
protected:
|
||||
virtual void onClickCloseBtn();
|
||||
};
|
||||
|
||||
extern LLSceneMonitorView* gSceneMonitorView;
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -45,22 +45,21 @@
|
|||
#define SG_STATE_INHERIT_MASK (OCCLUDED)
|
||||
#define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY)
|
||||
|
||||
class LLViewerOctreePartition;
|
||||
class LLSpatialPartition;
|
||||
class LLSpatialBridge;
|
||||
class LLSpatialGroup;
|
||||
class LLTextureAtlas;
|
||||
class LLTextureAtlasSlot;
|
||||
class LLViewerRegion;
|
||||
|
||||
S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad);
|
||||
S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared);
|
||||
|
||||
S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad);
|
||||
S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared);
|
||||
void pushVerts(LLFace* face, U32 mask);
|
||||
|
||||
// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera
|
||||
U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
|
||||
U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center);
|
||||
GLuint get_new_occlusion_query_object_name();
|
||||
void release_occlusion_query_object_name(GLuint name);
|
||||
|
||||
class LLDrawInfo : public LLRefCount
|
||||
{
|
||||
|
|
@ -192,13 +191,13 @@ public:
|
|||
};
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLSpatialGroup : public LLOctreeListener<LLDrawable>
|
||||
class LLSpatialGroup : public LLviewerOctreeGroup
|
||||
{
|
||||
friend class LLSpatialPartition;
|
||||
friend class LLOctreeStateCheck;
|
||||
public:
|
||||
|
||||
LLSpatialGroup(const LLSpatialGroup& rhs)
|
||||
LLSpatialGroup(const LLSpatialGroup& rhs) : LLviewerOctreeGroup(rhs)
|
||||
{
|
||||
*this = rhs;
|
||||
}
|
||||
|
|
@ -229,16 +228,7 @@ public:
|
|||
typedef std::map<U32, drawmap_elem_t > draw_map_t;
|
||||
typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t;
|
||||
typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t;
|
||||
typedef std::map<U32, buffer_texture_map_t> buffer_map_t;
|
||||
|
||||
typedef LLOctreeListener<LLDrawable> BaseType;
|
||||
typedef LLOctreeListener<LLDrawable> OctreeListener;
|
||||
typedef LLTreeNode<LLDrawable> TreeNode;
|
||||
typedef LLOctreeNode<LLDrawable> OctreeNode;
|
||||
typedef LLOctreeRoot<LLDrawable> OctreeRoot;
|
||||
typedef LLOctreeTraveler<LLDrawable> OctreeTraveler;
|
||||
typedef LLOctreeNode<LLDrawable>::element_iter element_iter;
|
||||
typedef LLOctreeNode<LLDrawable>::element_list element_list;
|
||||
typedef std::map<U32, buffer_texture_map_t> buffer_map_t;
|
||||
|
||||
struct CompareDistanceGreater
|
||||
{
|
||||
|
|
@ -275,18 +265,15 @@ public:
|
|||
|
||||
typedef enum
|
||||
{
|
||||
DEAD = 0x00000001,
|
||||
DIRTY = 0x00000002,
|
||||
OBJECT_DIRTY = 0x00000004,
|
||||
GEOM_DIRTY = 0x00000008,
|
||||
ALPHA_DIRTY = 0x00000010,
|
||||
SKIP_FRUSTUM_CHECK = 0x00000020,
|
||||
IN_IMAGE_QUEUE = 0x00000040,
|
||||
IMAGE_DIRTY = 0x00000080,
|
||||
MESH_DIRTY = 0x00000100,
|
||||
NEW_DRAWINFO = 0x00000200,
|
||||
IN_BUILD_Q1 = 0x00000400,
|
||||
IN_BUILD_Q2 = 0x00000800,
|
||||
DEAD = LLviewerOctreeGroup::INVALID_STATE,
|
||||
GEOM_DIRTY = (DEAD << 1),
|
||||
ALPHA_DIRTY = (GEOM_DIRTY << 1),
|
||||
IN_IMAGE_QUEUE = (ALPHA_DIRTY << 1),
|
||||
IMAGE_DIRTY = (IN_IMAGE_QUEUE << 1),
|
||||
MESH_DIRTY = (IMAGE_DIRTY << 1),
|
||||
NEW_DRAWINFO = (MESH_DIRTY << 1),
|
||||
IN_BUILD_Q1 = (NEW_DRAWINFO << 1),
|
||||
IN_BUILD_Q2 = (IN_BUILD_Q1 << 1),
|
||||
STATE_MASK = 0x0000FFFF,
|
||||
} eSpatialState;
|
||||
|
||||
|
|
@ -301,12 +288,8 @@ public:
|
|||
LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
|
||||
|
||||
BOOL isHUDGroup() ;
|
||||
BOOL isDead() { return isState(DEAD); }
|
||||
BOOL isState(U32 state) const;
|
||||
BOOL isDead() { return hasState(DEAD); }
|
||||
BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; }
|
||||
U32 getState() { return mState; }
|
||||
void setState(U32 state);
|
||||
void clearState(U32 state);
|
||||
|
||||
void clearDrawMap();
|
||||
void validate();
|
||||
|
|
@ -315,23 +298,18 @@ public:
|
|||
|
||||
void setState(U32 state, S32 mode);
|
||||
void clearState(U32 state, S32 mode);
|
||||
void clearState(U32 state) {mState &= ~state;}
|
||||
|
||||
void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE);
|
||||
void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE);
|
||||
|
||||
LLSpatialGroup* getParent();
|
||||
|
||||
|
||||
BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE);
|
||||
BOOL addObject(LLDrawable *drawablep);
|
||||
BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
|
||||
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
|
||||
BOOL isVisible() const;
|
||||
BOOL isRecentlyVisible() const;
|
||||
void setVisible();
|
||||
void shift(const LLVector4a &offset);
|
||||
BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax);
|
||||
void unbound();
|
||||
BOOL rebound();
|
||||
void checkOcclusion(); //read back last occlusion query (if any)
|
||||
void doOcclusion(LLCamera* camera); //issue occlusion query
|
||||
void destroyGL(bool keep_occlusion = false);
|
||||
|
|
@ -343,28 +321,18 @@ public:
|
|||
void rebuildGeom();
|
||||
void rebuildMesh();
|
||||
|
||||
void setState(U32 state) {mState |= state;}
|
||||
void dirtyGeom() { setState(GEOM_DIRTY); }
|
||||
void dirtyMesh() { setState(MESH_DIRTY); }
|
||||
|
||||
//octree wrappers to make code more readable
|
||||
element_list& getData() { return mOctreeNode->getData(); }
|
||||
element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
|
||||
element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
|
||||
bool hasElement(LLDrawable* drawablep) { return std::find(mOctreeNode->getDataBegin(), mOctreeNode->getDataEnd(), drawablep) != mOctreeNode->getDataEnd(); }
|
||||
|
||||
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
|
||||
bool isEmpty() const { return mOctreeNode->isEmpty(); }
|
||||
void dirtyMesh() { setState(MESH_DIRTY); }
|
||||
|
||||
void drawObjectBox(LLColor4 col);
|
||||
|
||||
//LISTENER FUNCTIONS
|
||||
virtual void handleInsertion(const TreeNode* node, LLDrawable* face);
|
||||
virtual void handleRemoval(const TreeNode* node, LLDrawable* face);
|
||||
virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face);
|
||||
virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face);
|
||||
virtual void handleDestruction(const TreeNode* node);
|
||||
virtual void handleStateChange(const TreeNode* node);
|
||||
virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
|
||||
virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);
|
||||
|
||||
|
||||
//-------------------
|
||||
//for atlas use
|
||||
//-------------------
|
||||
|
|
@ -386,21 +354,6 @@ public:
|
|||
|
||||
public:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BOUNDS = 0,
|
||||
EXTENTS = 2,
|
||||
OBJECT_BOUNDS = 4,
|
||||
OBJECT_EXTENTS = 6,
|
||||
VIEW_ANGLE = 8,
|
||||
LAST_VIEW_ANGLE = 9,
|
||||
V4_COUNT = 10
|
||||
} eV4Index;
|
||||
|
||||
LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
|
||||
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
|
||||
LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node
|
||||
LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node
|
||||
LL_ALIGN_16(LLVector4a mViewAngle);
|
||||
LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
|
||||
|
||||
|
|
@ -421,7 +374,6 @@ private:
|
|||
protected:
|
||||
virtual ~LLSpatialGroup();
|
||||
|
||||
U32 mState;
|
||||
U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS];
|
||||
U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS];
|
||||
|
||||
|
|
@ -436,7 +388,6 @@ public:
|
|||
F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node
|
||||
|
||||
F32 mBuilt;
|
||||
OctreeNode* mOctreeNode;
|
||||
LLSpatialPartition* mSpatialPartition;
|
||||
|
||||
LLPointer<LLVertexBuffer> mVertexBuffer;
|
||||
|
|
@ -444,8 +395,7 @@ public:
|
|||
|
||||
U32 mBufferUsage;
|
||||
draw_map_t mDrawMap;
|
||||
|
||||
S32 mVisible[LLViewerCamera::NUM_CAMERAS];
|
||||
|
||||
F32 mDistance;
|
||||
F32 mDepth;
|
||||
F32 mLastUpdateDistance;
|
||||
|
|
@ -468,10 +418,10 @@ public:
|
|||
virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
|
||||
};
|
||||
|
||||
class LLSpatialPartition: public LLGeometryManager
|
||||
class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager
|
||||
{
|
||||
public:
|
||||
LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage);
|
||||
LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp);
|
||||
virtual ~LLSpatialPartition();
|
||||
|
||||
LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);
|
||||
|
|
@ -498,7 +448,8 @@ public:
|
|||
virtual void rebuildMesh(LLSpatialGroup* group);
|
||||
|
||||
BOOL visibleObjectsInFrustum(LLCamera& camera);
|
||||
S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum
|
||||
/*virtual*/ S32 cull(LLCamera &camera); // Cull on arbitrary frustum
|
||||
S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select); // Cull on arbitrary frustum
|
||||
|
||||
BOOL isVisible(const LLVector3& v);
|
||||
bool isHUDPartition() ;
|
||||
|
|
@ -513,23 +464,21 @@ public:
|
|||
void resetVertexBuffers();
|
||||
BOOL isOcclusionEnabled();
|
||||
BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);
|
||||
|
||||
|
||||
public:
|
||||
LLSpatialGroup::OctreeNode* mOctree;
|
||||
LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this
|
||||
// use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe
|
||||
// to call asBridge() from the destructor
|
||||
BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed
|
||||
BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane
|
||||
U32 mBufferUsage;
|
||||
U32 mDrawableType;
|
||||
const BOOL mRenderByGroup;
|
||||
U32 mLODSeed;
|
||||
U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed)
|
||||
U32 mVertexDataMask;
|
||||
F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
|
||||
BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
|
||||
U32 mDrawableType;
|
||||
U32 mPartitionType;
|
||||
BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
|
||||
};
|
||||
|
||||
// class for creating bridges between spatial partitions
|
||||
|
|
@ -541,7 +490,7 @@ protected:
|
|||
public:
|
||||
typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t;
|
||||
|
||||
LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask);
|
||||
LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp);
|
||||
|
||||
void destroyTree();
|
||||
|
||||
|
|
@ -564,7 +513,7 @@ public:
|
|||
|
||||
};
|
||||
|
||||
class LLCullResult
|
||||
class LLCullResult
|
||||
{
|
||||
public:
|
||||
LLCullResult();
|
||||
|
|
@ -663,7 +612,7 @@ private:
|
|||
class LLWaterPartition : public LLSpatialPartition
|
||||
{
|
||||
public:
|
||||
LLWaterPartition();
|
||||
LLWaterPartition(LLViewerRegion* regionp);
|
||||
virtual void getGeometry(LLSpatialGroup* group) { }
|
||||
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
|
||||
};
|
||||
|
|
@ -672,14 +621,14 @@ public:
|
|||
class LLVoidWaterPartition : public LLWaterPartition
|
||||
{
|
||||
public:
|
||||
LLVoidWaterPartition();
|
||||
LLVoidWaterPartition(LLViewerRegion* regionp);
|
||||
};
|
||||
|
||||
//spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp)
|
||||
class LLTerrainPartition : public LLSpatialPartition
|
||||
{
|
||||
public:
|
||||
LLTerrainPartition();
|
||||
LLTerrainPartition(LLViewerRegion* regionp);
|
||||
virtual void getGeometry(LLSpatialGroup* group);
|
||||
virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
|
||||
};
|
||||
|
|
@ -688,7 +637,7 @@ public:
|
|||
class LLTreePartition : public LLSpatialPartition
|
||||
{
|
||||
public:
|
||||
LLTreePartition();
|
||||
LLTreePartition(LLViewerRegion* regionp);
|
||||
virtual void getGeometry(LLSpatialGroup* group) { }
|
||||
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
|
||||
|
||||
|
|
@ -698,7 +647,7 @@ public:
|
|||
class LLParticlePartition : public LLSpatialPartition
|
||||
{
|
||||
public:
|
||||
LLParticlePartition();
|
||||
LLParticlePartition(LLViewerRegion* regionp);
|
||||
virtual void rebuildGeom(LLSpatialGroup* group);
|
||||
virtual void getGeometry(LLSpatialGroup* group);
|
||||
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
|
||||
|
|
@ -710,14 +659,14 @@ protected:
|
|||
class LLHUDParticlePartition : public LLParticlePartition
|
||||
{
|
||||
public:
|
||||
LLHUDParticlePartition();
|
||||
LLHUDParticlePartition(LLViewerRegion* regionp);
|
||||
};
|
||||
|
||||
//spatial partition for grass (implemented in LLVOGrass.cpp)
|
||||
class LLGrassPartition : public LLSpatialPartition
|
||||
{
|
||||
public:
|
||||
LLGrassPartition();
|
||||
LLGrassPartition(LLViewerRegion* regionp);
|
||||
virtual void getGeometry(LLSpatialGroup* group);
|
||||
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
|
||||
protected:
|
||||
|
|
@ -747,7 +696,7 @@ class LLVolumeGeometryManager: public LLGeometryManager
|
|||
class LLVolumePartition : public LLSpatialPartition, public LLVolumeGeometryManager
|
||||
{
|
||||
public:
|
||||
LLVolumePartition();
|
||||
LLVolumePartition(LLViewerRegion* regionp);
|
||||
virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
|
||||
virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
|
||||
virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); }
|
||||
|
|
@ -758,7 +707,7 @@ public:
|
|||
class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager
|
||||
{
|
||||
public:
|
||||
LLVolumeBridge(LLDrawable* drawable);
|
||||
LLVolumeBridge(LLDrawable* drawable, LLViewerRegion* regionp);
|
||||
virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
|
||||
virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
|
||||
virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); }
|
||||
|
|
@ -768,7 +717,7 @@ public:
|
|||
class LLHUDBridge : public LLVolumeBridge
|
||||
{
|
||||
public:
|
||||
LLHUDBridge(LLDrawable* drawablep);
|
||||
LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
|
||||
virtual void shiftPos(const LLVector4a& vec);
|
||||
virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
|
||||
};
|
||||
|
|
@ -777,7 +726,7 @@ public:
|
|||
class LLBridgePartition : public LLSpatialPartition
|
||||
{
|
||||
public:
|
||||
LLBridgePartition();
|
||||
LLBridgePartition(LLViewerRegion* regionp);
|
||||
virtual void getGeometry(LLSpatialGroup* group) { }
|
||||
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
|
||||
};
|
||||
|
|
@ -785,7 +734,7 @@ public:
|
|||
class LLHUDPartition : public LLBridgePartition
|
||||
{
|
||||
public:
|
||||
LLHUDPartition();
|
||||
LLHUDPartition(LLViewerRegion* regionp);
|
||||
virtual void shift(const LLVector4a &offset);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2358,6 +2358,10 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
|||
mHttpMetricsHeaders = new LLCore::HttpHeaders;
|
||||
mHttpMetricsHeaders->mHeaders.push_back("Content-Type: application/llsd+xml");
|
||||
mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault();
|
||||
|
||||
//reset the texture timer.
|
||||
gTextureTimer.reset();
|
||||
gTextureTimer.pause();
|
||||
}
|
||||
|
||||
LLTextureFetch::~LLTextureFetch()
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@
|
|||
#include "llviewertexturelist.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llworld.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
|
||||
// For avatar texture view
|
||||
#include "llvoavatarself.h"
|
||||
|
|
@ -517,6 +519,9 @@ void LLGLTexMemBar::draw()
|
|||
LLUnit<LLUnits::Bytes, F32> total_texture_downloaded = gTotalTextureData;
|
||||
LLUnit<LLUnits::Bytes, F32> total_object_downloaded = gTotalObjectData;
|
||||
U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ;
|
||||
U32 total_active_cached_objects = LLWorld::getInstance()->getNumOfActiveCachedObjects();
|
||||
U32 total_objects = gObjectList.getNumObjects();
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
LLGLSUIDefault gls_ui;
|
||||
LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
|
||||
|
|
@ -549,9 +554,11 @@ void LLGLTexMemBar::draw()
|
|||
U32 cache_read(0U), cache_write(0U), res_wait(0U);
|
||||
LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait);
|
||||
|
||||
text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u",
|
||||
text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB #Objs/#Cached: %d/%d Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u",
|
||||
total_texture_downloaded.value(),
|
||||
total_object_downloaded.value(),
|
||||
total_objects,
|
||||
total_active_cached_objects,
|
||||
total_http_requests,
|
||||
cache_read,
|
||||
cache_write,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@
|
|||
#include "llwlparammanager.h"
|
||||
#include "llwaterparammanager.h"
|
||||
#include "llpostprocess.h"
|
||||
#include "llscenemonitor.h"
|
||||
|
||||
extern LLPointer<LLViewerTexture> gStartTexture;
|
||||
extern bool gShiftFrame;
|
||||
|
|
@ -991,6 +992,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
|
||||
LLPipeline::sUnderWaterRender = FALSE;
|
||||
|
||||
{
|
||||
//capture the frame buffer.
|
||||
LLSceneMonitor::getInstance()->capture();
|
||||
}
|
||||
|
||||
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
|
||||
if (!for_snapshot)
|
||||
{
|
||||
|
|
@ -1224,6 +1230,15 @@ void render_ui(F32 zoom_factor, int subfield)
|
|||
glh_set_current_modelview(glh_copy_matrix(gGLLastModelView));
|
||||
}
|
||||
|
||||
if(LLSceneMonitor::getInstance()->needsUpdate())
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gViewerWindow->setup2DRender();
|
||||
LLSceneMonitor::getInstance()->compare();
|
||||
gViewerWindow->setup3DRender();
|
||||
gGL.popMatrix();
|
||||
}
|
||||
|
||||
{
|
||||
BOOL to_texture = gPipeline.canUseVertexShaders() &&
|
||||
LLPipeline::sRenderGlow;
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@
|
|||
#include "llwindow.h"
|
||||
#include "llpathfindingmanager.h"
|
||||
#include "boost/unordered_map.hpp"
|
||||
#include "llscenemonitor.h"
|
||||
|
||||
using namespace LLVOAvatarDefines;
|
||||
|
||||
|
|
@ -529,7 +530,10 @@ class LLAdvancedToggleConsole : public view_listener_t
|
|||
{
|
||||
toggle_visibility( (void*)gSceneView);
|
||||
}
|
||||
|
||||
else if ("scene monitor" == console_type)
|
||||
{
|
||||
toggle_visibility( (void*)gSceneMonitorView);
|
||||
}
|
||||
#if MEM_TRACK_MEM
|
||||
else if ("memory view" == console_type)
|
||||
{
|
||||
|
|
@ -557,9 +561,9 @@ class LLAdvancedCheckConsole : public view_listener_t
|
|||
{
|
||||
new_value = LLFloaterReg::instanceVisible("fast_timers");
|
||||
}
|
||||
else if ("scene view" == console_type)
|
||||
else if ("scene monitor" == console_type)
|
||||
{
|
||||
new_value = get_visibility( (void*) gSceneView);
|
||||
new_value = get_visibility( (void*) gSceneMonitorView);
|
||||
}
|
||||
#if MEM_TRACK_MEM
|
||||
else if ("memory view" == console_type)
|
||||
|
|
|
|||
|
|
@ -4483,30 +4483,42 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
|
|||
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Kill Objects");
|
||||
|
||||
const U32 KILLOBJECT_DELETE_OPCODE = 0;
|
||||
|
||||
|
||||
void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
|
||||
{
|
||||
LLFastTimer t(FTM_PROCESS_OBJECTS);
|
||||
|
||||
LLUUID id;
|
||||
U32 local_id;
|
||||
S32 i;
|
||||
S32 num_objects;
|
||||
LLUUID id;
|
||||
|
||||
num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
|
||||
|
||||
for (i = 0; i < num_objects; i++)
|
||||
U32 ip = mesgsys->getSenderIP();
|
||||
U32 port = mesgsys->getSenderPort();
|
||||
LLViewerRegion* regionp = NULL;
|
||||
{
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
|
||||
LLHost host(ip, port);
|
||||
regionp = LLWorld::getInstance()->getRegion(host);
|
||||
}
|
||||
|
||||
LLViewerObjectList::getUUIDFromLocal(id,
|
||||
local_id,
|
||||
gMessageSystem->getSenderIP(),
|
||||
gMessageSystem->getSenderPort());
|
||||
bool delete_object = false;
|
||||
S32 num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
|
||||
for (S32 i = 0; i < num_objects; ++i)
|
||||
{
|
||||
U32 local_id;
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
|
||||
if (local_id == KILLOBJECT_DELETE_OPCODE)
|
||||
{
|
||||
// This local_id is invalid, but was sent by the server to flag
|
||||
// all subsequent local_id's as objects that were actually deleted
|
||||
// rather than unsubscribed from interestlist.
|
||||
delete_object = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
LLViewerObjectList::getUUIDFromLocal(id, local_id, ip, port);
|
||||
if (id == LLUUID::null)
|
||||
{
|
||||
LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL;
|
||||
gObjectList.mNumUnknownKills++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
|
@ -4514,34 +4526,35 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
|
|||
LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;
|
||||
}
|
||||
|
||||
// ...don't kill the avatar
|
||||
if (!(id == gAgentID))
|
||||
if (id == gAgentID)
|
||||
{
|
||||
LLViewerObject *objectp = gObjectList.findObject(id);
|
||||
if (objectp)
|
||||
{
|
||||
// Display green bubble on kill
|
||||
if ( gShowObjectUpdates )
|
||||
{
|
||||
LLColor4 color(0.f,1.f,0.f,1.f);
|
||||
gPipeline.addDebugBlip(objectp->getPositionAgent(), color);
|
||||
}
|
||||
// never kill our avatar
|
||||
continue;
|
||||
}
|
||||
|
||||
// Do the kill
|
||||
gObjectList.killObject(objectp);
|
||||
}
|
||||
else
|
||||
LLViewerObject *objectp = gObjectList.findObject(id);
|
||||
if (objectp)
|
||||
{
|
||||
// Display green bubble on kill
|
||||
if ( gShowObjectUpdates )
|
||||
{
|
||||
LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL;
|
||||
gObjectList.mNumUnknownKills++;
|
||||
LLColor4 color(0.f,1.f,0.f,1.f);
|
||||
gPipeline.addDebugBlip(objectp->getPositionAgent(), color);
|
||||
}
|
||||
|
||||
// Do the kill
|
||||
gObjectList.killObject(objectp);
|
||||
}
|
||||
|
||||
if(delete_object)
|
||||
{
|
||||
regionp->killCacheEntry(local_id);
|
||||
}
|
||||
|
||||
// We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab,
|
||||
// which is using the object, release the mouse capture correctly when the object dies.
|
||||
// See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical().
|
||||
LLSelectMgr::getInstance()->removeObjectFromSelections(id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@
|
|||
#include "lltrans.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llmediaentry.h"
|
||||
#include "llvocache.h"
|
||||
|
||||
//#define DEBUG_UPDATE_TYPE
|
||||
|
||||
|
|
@ -326,6 +327,22 @@ void LLViewerObject::deleteTEImages()
|
|||
mTEImages = NULL;
|
||||
}
|
||||
|
||||
//if enabled, add this object to vo cache tree when removed from rendering.
|
||||
void LLViewerObject::EnableToCacheTree(bool enabled)
|
||||
{
|
||||
if(mDrawable.notNull() && mDrawable->getEntry() && mDrawable->getEntry()->hasVOCacheEntry())
|
||||
{
|
||||
if(enabled)
|
||||
{
|
||||
((LLVOCacheEntry*)mDrawable->getEntry()->getVOCacheEntry())->addState(LLVOCacheEntry::ADD_TO_CACHE_TREE);
|
||||
}
|
||||
else
|
||||
{
|
||||
((LLVOCacheEntry*)mDrawable->getEntry()->getVOCacheEntry())->clearState(LLVOCacheEntry::ADD_TO_CACHE_TREE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::markDead()
|
||||
{
|
||||
if (!mDead)
|
||||
|
|
@ -348,7 +365,7 @@ void LLViewerObject::markDead()
|
|||
childp = mChildList.back();
|
||||
if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
|
||||
{
|
||||
//llinfos << "Marking child " << childp->getLocalID() << " as dead." << llendl;
|
||||
//llinfos << "Marking child " << childp->getLocalID() << " as dead." << llendl;
|
||||
childp->setParent(NULL); // LLViewerObject::markDead 1
|
||||
childp->markDead();
|
||||
}
|
||||
|
|
@ -889,10 +906,11 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
}
|
||||
|
||||
// Coordinates of objects on simulators are region-local.
|
||||
U64 region_handle;
|
||||
mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
|
||||
U64 region_handle = 0;
|
||||
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
|
||||
LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
|
||||
if(regionp != mRegionp && regionp && mRegionp)//region cross
|
||||
{
|
||||
|
|
@ -918,11 +936,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
return retval;
|
||||
}
|
||||
|
||||
U16 time_dilation16;
|
||||
mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
|
||||
F32 time_dilation = ((F32) time_dilation16) / 65535.f;
|
||||
mTimeDilation = time_dilation;
|
||||
mRegionp->setTimeDilation(time_dilation);
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
U16 time_dilation16;
|
||||
mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
|
||||
F32 time_dilation = ((F32) time_dilation16) / 65535.f;
|
||||
mTimeDilation = time_dilation;
|
||||
mRegionp->setTimeDilation(time_dilation);
|
||||
}
|
||||
|
||||
// this will be used to determine if we've really changed position
|
||||
// Use getPosition, not getPositionRegion, since this is what we're comparing directly against.
|
||||
|
|
@ -1695,13 +1716,16 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
// Preload these five flags for every object.
|
||||
// Finer shades require the object to be selected, and the selection manager
|
||||
// stores the extended permission info.
|
||||
U32 flags;
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
|
||||
// keep local flags and overwrite remote-controlled flags
|
||||
mFlags = (mFlags & FLAGS_LOCAL) | flags;
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
U32 flags;
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
|
||||
// keep local flags and overwrite remote-controlled flags
|
||||
mFlags = (mFlags & FLAGS_LOCAL) | flags;
|
||||
|
||||
// ...new objects that should come in selected need to be added to the selected list
|
||||
mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
|
||||
mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1729,10 +1753,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
{
|
||||
// No parent now, new parent in message -> attach to that parent if possible
|
||||
LLUUID parent_uuid;
|
||||
LLViewerObjectList::getUUIDFromLocal(parent_uuid,
|
||||
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
LLViewerObjectList::getUUIDFromLocal(parent_uuid,
|
||||
parent_id,
|
||||
mesgsys->getSenderIP(),
|
||||
mesgsys->getSenderPort());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerObjectList::getUUIDFromLocal(parent_uuid,
|
||||
parent_id,
|
||||
mRegionp->getHost().getAddress(),
|
||||
mRegionp->getHost().getPort());
|
||||
}
|
||||
|
||||
LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid);
|
||||
|
||||
|
|
@ -1808,9 +1843,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
//
|
||||
|
||||
//parent_id
|
||||
U32 ip = mesgsys->getSenderIP();
|
||||
U32 port = mesgsys->getSenderPort();
|
||||
U32 ip, port;
|
||||
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
ip = mesgsys->getSenderIP();
|
||||
port = mesgsys->getSenderPort();
|
||||
}
|
||||
else
|
||||
{
|
||||
ip = mRegionp->getHost().getAddress();
|
||||
port = mRegionp->getHost().getPort();
|
||||
}
|
||||
gObjectList.orphanize(this, parent_id, ip, port);
|
||||
|
||||
// Hide particles, icon and HUD
|
||||
|
|
@ -1848,10 +1892,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
else
|
||||
{
|
||||
LLUUID parent_uuid;
|
||||
LLViewerObjectList::getUUIDFromLocal(parent_uuid,
|
||||
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
LLViewerObjectList::getUUIDFromLocal(parent_uuid,
|
||||
parent_id,
|
||||
gMessageSystem->getSenderIP(),
|
||||
gMessageSystem->getSenderPort());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerObjectList::getUUIDFromLocal(parent_uuid,
|
||||
parent_id,
|
||||
mRegionp->getHost().getAddress(),
|
||||
mRegionp->getHost().getPort());
|
||||
}
|
||||
sent_parentp = gObjectList.findObject(parent_uuid);
|
||||
|
||||
if (isAvatar())
|
||||
|
|
@ -1872,8 +1927,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
//
|
||||
// Switching parents, but we don't know the new parent.
|
||||
//
|
||||
U32 ip = mesgsys->getSenderIP();
|
||||
U32 port = mesgsys->getSenderPort();
|
||||
U32 ip, port;
|
||||
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
ip = mesgsys->getSenderIP();
|
||||
port = mesgsys->getSenderPort();
|
||||
}
|
||||
else
|
||||
{
|
||||
ip = mRegionp->getHost().getAddress();
|
||||
port = mRegionp->getHost().getPort();
|
||||
}
|
||||
|
||||
// We're an orphan, flag things appropriately.
|
||||
gObjectList.orphanize(this, parent_id, ip, port);
|
||||
|
|
@ -1957,7 +2022,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
|
||||
new_rot.normQuat();
|
||||
|
||||
if (sPingInterpolate)
|
||||
if (sPingInterpolate && mesgsys != NULL)
|
||||
{
|
||||
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
|
||||
if (cdp)
|
||||
|
|
@ -1980,16 +2045,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
|
||||
// If we're going to skip this message, why are we
|
||||
// doing all the parenting, etc above?
|
||||
U32 packet_id = mesgsys->getCurrentRecvPacketID();
|
||||
if (packet_id < mLatestRecvPacketID &&
|
||||
mLatestRecvPacketID - packet_id < 65536)
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
//skip application of this message, it's old
|
||||
return retval;
|
||||
U32 packet_id = mesgsys->getCurrentRecvPacketID();
|
||||
if (packet_id < mLatestRecvPacketID &&
|
||||
mLatestRecvPacketID - packet_id < 65536)
|
||||
{
|
||||
//skip application of this message, it's old
|
||||
return retval;
|
||||
}
|
||||
mLatestRecvPacketID = packet_id;
|
||||
}
|
||||
|
||||
mLatestRecvPacketID = packet_id;
|
||||
|
||||
// Set the change flags for scale
|
||||
if (new_scale != getScale())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ public:
|
|||
BOOL isDead() const {return mDead;}
|
||||
BOOL isOrphaned() const { return mOrphaned; }
|
||||
BOOL isParticleSource() const;
|
||||
void EnableToCacheTree(bool enabled);
|
||||
|
||||
virtual LLVOAvatar* asAvatar();
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
#include "object_flags.h"
|
||||
|
||||
#include "llappviewer.h"
|
||||
#include "llvocache.h"
|
||||
|
||||
extern F32 gMinObjectDistance;
|
||||
extern BOOL gAnimateTextures;
|
||||
|
|
@ -106,7 +107,6 @@ LLViewerObjectList::LLViewerObjectList()
|
|||
mNumNewObjects = 0;
|
||||
mWasPaused = FALSE;
|
||||
mNumDeadObjectUpdates = 0;
|
||||
mNumUnknownKills = 0;
|
||||
mNumUnknownUpdates = 0;
|
||||
}
|
||||
|
||||
|
|
@ -228,9 +228,15 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
|
|||
U32 i,
|
||||
const EObjectUpdateType update_type,
|
||||
LLDataPacker* dpp,
|
||||
BOOL just_created)
|
||||
bool just_created,
|
||||
bool from_cache)
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
LLMessageSystem* msg = NULL;
|
||||
|
||||
if(!from_cache)
|
||||
{
|
||||
msg = gMessageSystem;
|
||||
}
|
||||
|
||||
// ignore returned flags
|
||||
objectp->processUpdateMessage(msg, user_data, i, update_type, dpp);
|
||||
|
|
@ -254,7 +260,18 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
|
|||
// RN: this must be called after we have a drawable
|
||||
// (from gPipeline.addObject)
|
||||
// so that the drawable parent is set properly
|
||||
findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort());
|
||||
if(msg != NULL)
|
||||
{
|
||||
findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerRegion* regionp = objectp->getRegion();
|
||||
if(regionp != NULL)
|
||||
{
|
||||
findOrphans(objectp, regionp->getHost().getAddress(), regionp->getHost().getPort());
|
||||
}
|
||||
}
|
||||
|
||||
// If we're just wandering around, don't create new objects selected.
|
||||
if (just_created
|
||||
|
|
@ -277,10 +294,88 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
|
|||
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
|
||||
|
||||
LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp)
|
||||
{
|
||||
LLDataPacker *cached_dpp = entry->getDP();
|
||||
|
||||
if (!cached_dpp)
|
||||
{
|
||||
return NULL; //nothing cached.
|
||||
}
|
||||
|
||||
LLViewerObject *objectp;
|
||||
U32 local_id;
|
||||
LLPCode pcode = 0;
|
||||
LLUUID fullid;
|
||||
LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance();
|
||||
|
||||
// Cache Hit.
|
||||
cached_dpp->reset();
|
||||
cached_dpp->unpackUUID(fullid, "ID");
|
||||
cached_dpp->unpackU32(local_id, "LocalID");
|
||||
cached_dpp->unpackU8(pcode, "PCode");
|
||||
|
||||
objectp = findObject(fullid);
|
||||
|
||||
if (objectp)
|
||||
{
|
||||
if(!objectp->isDead() && (objectp->mLocalID != entry->getLocalID() ||
|
||||
objectp->getRegion() != regionp))
|
||||
{
|
||||
removeFromLocalIDTable(objectp);
|
||||
setUUIDAndLocal(fullid, entry->getLocalID(),
|
||||
regionp->getHost().getAddress(),
|
||||
regionp->getHost().getPort());
|
||||
|
||||
if (objectp->mLocalID != entry->getLocalID())
|
||||
{ // Update local ID in object with the one sent from the region
|
||||
objectp->mLocalID = entry->getLocalID();
|
||||
}
|
||||
|
||||
if (objectp->getRegion() != regionp)
|
||||
{ // Object changed region, so update it
|
||||
objectp->updateRegion(regionp); // for LLVOAvatar
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return objectp; //already loaded.
|
||||
}
|
||||
}
|
||||
|
||||
bool justCreated = false;
|
||||
if (!objectp)
|
||||
{
|
||||
objectp = createObjectFromCache(pcode, regionp, fullid, entry->getLocalID());
|
||||
|
||||
if (!objectp)
|
||||
{
|
||||
llinfos << "createObject failure for object: " << fullid << llendl;
|
||||
recorder.objectUpdateFailure(entry->getLocalID(), OUT_FULL_CACHED, 0);
|
||||
return NULL;
|
||||
}
|
||||
justCreated = true;
|
||||
mNumNewObjects++;
|
||||
sCacheHitRate.sample(100.f);
|
||||
}
|
||||
|
||||
if (objectp->isDead())
|
||||
{
|
||||
llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl;
|
||||
}
|
||||
|
||||
processUpdateCore(objectp, NULL, 0, OUT_FULL_CACHED, cached_dpp, justCreated, true);
|
||||
|
||||
recorder.log(0.2f);
|
||||
LLVOAvatar::cullAvatarsByPixelArea();
|
||||
|
||||
return objectp;
|
||||
}
|
||||
|
||||
void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
||||
void **user_data,
|
||||
const EObjectUpdateType update_type,
|
||||
bool cached, bool compressed)
|
||||
bool compressed)
|
||||
{
|
||||
LLFastTimer t(FTM_PROCESS_OBJECTS);
|
||||
|
||||
|
|
@ -299,7 +394,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
|
||||
|
||||
// I don't think this case is ever hit. TODO* Test this.
|
||||
if (!cached && !compressed && update_type != OUT_FULL)
|
||||
if (!compressed && update_type != OUT_FULL)
|
||||
{
|
||||
//llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;
|
||||
gTerseObjectUpdates += num_objects;
|
||||
|
|
@ -343,7 +438,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
|
||||
U8 compressed_dpbuffer[2048];
|
||||
LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048);
|
||||
LLDataPacker *cached_dpp = NULL;
|
||||
LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance();
|
||||
|
||||
for (i = 0; i < num_objects; i++)
|
||||
|
|
@ -353,43 +447,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
BOOL justCreated = FALSE;
|
||||
S32 msg_size = 0;
|
||||
|
||||
if (cached)
|
||||
if (compressed)
|
||||
{
|
||||
U32 id;
|
||||
U32 crc;
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
|
||||
msg_size += sizeof(U32) * 2;
|
||||
|
||||
// Lookup data packer and add this id to cache miss lists if necessary.
|
||||
U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
|
||||
cached_dpp = regionp->getDP(id, crc, cache_miss_type);
|
||||
if (cached_dpp)
|
||||
{
|
||||
// Cache Hit.
|
||||
cached_dpp->reset();
|
||||
cached_dpp->unpackUUID(fullid, "ID");
|
||||
cached_dpp->unpackU32(local_id, "LocalID");
|
||||
cached_dpp->unpackU8(pcode, "PCode");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cache Miss.
|
||||
recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
|
||||
|
||||
continue; // no data packer, skip this object
|
||||
}
|
||||
}
|
||||
else if (compressed)
|
||||
{
|
||||
S32 uncompressed_length = 2048;
|
||||
compressed_dp.reset();
|
||||
|
||||
U32 flags = 0;
|
||||
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
|
||||
{
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
|
||||
}
|
||||
S32 uncompressed_length = 2048;
|
||||
compressed_dp.reset();
|
||||
|
||||
uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
|
||||
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
|
||||
|
|
@ -485,9 +546,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
else if (cached) // Cache hit only?
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (update_type != OUT_FULL)
|
||||
|
|
@ -520,8 +578,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
}
|
||||
justCreated = TRUE;
|
||||
mNumNewObjects++;
|
||||
sCacheHitRate.sample(cached ? 100.f : 0.f);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -540,16 +596,17 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated);
|
||||
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
|
||||
{
|
||||
bCached = true;
|
||||
LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
|
||||
recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size);
|
||||
U32 flags = 0;
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
|
||||
|
||||
if(!(flags & FLAGS_TEMPORARY_ON_REZ))
|
||||
{
|
||||
bCached = true;
|
||||
LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
|
||||
recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cached) // Cache hit only?
|
||||
{
|
||||
objectp->mLocalID = local_id;
|
||||
processUpdateCore(objectp, user_data, i, update_type, cached_dpp, justCreated);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (update_type == OUT_FULL)
|
||||
|
|
@ -572,14 +629,51 @@ void LLViewerObjectList::processCompressedObjectUpdate(LLMessageSystem *mesgsys,
|
|||
void **user_data,
|
||||
const EObjectUpdateType update_type)
|
||||
{
|
||||
processObjectUpdate(mesgsys, user_data, update_type, false, true);
|
||||
processObjectUpdate(mesgsys, user_data, update_type, true);
|
||||
}
|
||||
|
||||
void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,
|
||||
void **user_data,
|
||||
const EObjectUpdateType update_type)
|
||||
{
|
||||
processObjectUpdate(mesgsys, user_data, update_type, true, false);
|
||||
//processObjectUpdate(mesgsys, user_data, update_type, true, false);
|
||||
|
||||
S32 num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
|
||||
gFullObjectUpdates += num_objects;
|
||||
|
||||
U64 region_handle;
|
||||
mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
|
||||
LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
|
||||
if (!regionp)
|
||||
{
|
||||
llwarns << "Object update from unknown region! " << region_handle << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance();
|
||||
|
||||
for (S32 i = 0; i < num_objects; i++)
|
||||
{
|
||||
S32 msg_size = 0;
|
||||
U32 id;
|
||||
U32 crc;
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
|
||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
|
||||
msg_size += sizeof(U32) * 2;
|
||||
|
||||
// Lookup data packer and add this id to cache miss lists if necessary.
|
||||
U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
|
||||
if(!regionp->probeCache(id, crc, cache_miss_type))
|
||||
{
|
||||
// Cache Miss.
|
||||
recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
|
||||
|
||||
continue; // no data packer, skip this object
|
||||
}
|
||||
sCacheHitRate.sample(100.f);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void LLViewerObjectList::dirtyAllObjectInventory()
|
||||
|
|
@ -1230,7 +1324,7 @@ void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
|
||||
BOOL LLViewerObjectList::killObject(LLViewerObject *objectp, bool cache_enabled)
|
||||
{
|
||||
// Don't ever kill gAgentAvatarp, just force it to the agent's region
|
||||
// unless region is NULL which is assumed to mean you are logging out.
|
||||
|
|
@ -1245,16 +1339,8 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
|
|||
|
||||
if (objectp)
|
||||
{
|
||||
if (objectp->isDead())
|
||||
{
|
||||
// This object is already dead. Don't need to do more.
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
objectp->markDead();
|
||||
}
|
||||
|
||||
objectp->EnableToCacheTree(cache_enabled); //enable to add to VO cache tree if set.
|
||||
objectp->markDead(); // does the right thing if object already dead
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1890,7 +1976,30 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi
|
|||
return objectp;
|
||||
}
|
||||
|
||||
LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id)
|
||||
{
|
||||
llassert_always(uuid.notNull());
|
||||
|
||||
LLViewerObject *objectp = LLViewerObject::createObject(uuid, pcode, regionp);
|
||||
if (!objectp)
|
||||
{
|
||||
// llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << " id:" << fullid << llendl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
objectp->mLocalID = local_id;
|
||||
mUUIDObjectMap[uuid] = objectp;
|
||||
setUUIDAndLocal(uuid,
|
||||
local_id,
|
||||
regionp->getHost().getAddress(),
|
||||
regionp->getHost().getPort());
|
||||
mObjects.push_back(objectp);
|
||||
|
||||
updateActive(objectp);
|
||||
|
||||
return objectp;
|
||||
}
|
||||
|
||||
LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,
|
||||
const LLUUID &uuid, const U32 local_id, const LLHost &sender)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
class LLCamera;
|
||||
class LLNetMap;
|
||||
class LLDebugBeacon;
|
||||
class LLVOCacheEntry;
|
||||
|
||||
const U32 CLOSE_BIN_SIZE = 10;
|
||||
const U32 NUM_BINS = 128;
|
||||
|
|
@ -65,12 +66,13 @@ public:
|
|||
|
||||
inline LLViewerObject *findObject(const LLUUID &id);
|
||||
LLViewerObject *createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp); // Create a viewer-side object
|
||||
LLViewerObject *createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id);
|
||||
LLViewerObject *createObject(const LLPCode pcode, LLViewerRegion *regionp,
|
||||
const LLUUID &uuid, const U32 local_id, const LLHost &sender);
|
||||
|
||||
LLViewerObject *replaceObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); // TomY: hack to switch VO instances on the fly
|
||||
|
||||
BOOL killObject(LLViewerObject *objectp);
|
||||
BOOL killObject(LLViewerObject *objectp, bool cache_enabled = false);
|
||||
void killObjects(LLViewerRegion *regionp); // Kill all objects owned by a particular region.
|
||||
void killAllObjects();
|
||||
void removeDrawable(LLDrawable* drawablep);
|
||||
|
|
@ -78,8 +80,10 @@ public:
|
|||
void cleanDeadObjects(const BOOL use_timer = TRUE); // Clean up the dead object list.
|
||||
|
||||
// Simulator and viewer side object updates...
|
||||
void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type, LLDataPacker* dpp, BOOL justCreated);
|
||||
void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool cached=false, bool compressed=false);
|
||||
void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type,
|
||||
LLDataPacker* dpp, bool justCreated, bool from_cache = false);
|
||||
LLViewerObject* processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp);
|
||||
void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool compressed=false);
|
||||
void processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
|
||||
void processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
|
||||
void updateApparentAngles(LLAgent &agent);
|
||||
|
|
@ -188,7 +192,6 @@ public:
|
|||
|
||||
S32 mNumUnknownUpdates;
|
||||
S32 mNumDeadObjectUpdates;
|
||||
S32 mNumUnknownKills;
|
||||
S32 mNumDeadObjects;
|
||||
protected:
|
||||
std::vector<U64> mOrphanParents; // LocalID/ip,port of orphaned objects
|
||||
|
|
|
|||
|
|
@ -0,0 +1,800 @@
|
|||
/**
|
||||
* @file llvieweroctree.cpp
|
||||
* @brief LLViewerOctreeGroup class implementation and supporting functions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llvieweroctree.h"
|
||||
#include "llviewerregion.h"
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//static variables definitions
|
||||
//-----------------------------------------------------------------------------------
|
||||
U32 LLViewerOctreeEntryData::sCurVisible = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//some global functions definitions
|
||||
//-----------------------------------------------------------------------------------
|
||||
S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad)
|
||||
{
|
||||
return AABBSphereIntersectR2(min, max, origin, rad*rad);
|
||||
}
|
||||
|
||||
S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r)
|
||||
{
|
||||
F32 d = 0.f;
|
||||
F32 t;
|
||||
|
||||
if ((min-origin).magVecSquared() < r &&
|
||||
(max-origin).magVecSquared() < r)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (origin.mV[i] < min.mV[i])
|
||||
{
|
||||
t = min.mV[i] - origin.mV[i];
|
||||
d += t*t;
|
||||
}
|
||||
else if (origin.mV[i] > max.mV[i])
|
||||
{
|
||||
t = origin.mV[i] - max.mV[i];
|
||||
d += t*t;
|
||||
}
|
||||
|
||||
if (d > r)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad)
|
||||
{
|
||||
return AABBSphereIntersectR2(min, max, origin, rad*rad);
|
||||
}
|
||||
|
||||
S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r)
|
||||
{
|
||||
F32 d = 0.f;
|
||||
F32 t;
|
||||
|
||||
LLVector4a origina;
|
||||
origina.load3(origin.mV);
|
||||
|
||||
LLVector4a v;
|
||||
v.setSub(min, origina);
|
||||
|
||||
if (v.dot3(v) < r)
|
||||
{
|
||||
v.setSub(max, origina);
|
||||
if (v.dot3(v) < r)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (origin.mV[i] < min[i])
|
||||
{
|
||||
t = min[i] - origin.mV[i];
|
||||
d += t*t;
|
||||
}
|
||||
else if (origin.mV[i] > max[i])
|
||||
{
|
||||
t = origin.mV[i] - max[i];
|
||||
d += t*t;
|
||||
}
|
||||
|
||||
if (d > r)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//class LLViewerOctreeEntry definitions
|
||||
//-----------------------------------------------------------------------------------
|
||||
LLViewerOctreeEntry::LLViewerOctreeEntry()
|
||||
: mGroup(NULL),
|
||||
mBinRadius(0.f),
|
||||
mBinIndex(-1)
|
||||
{
|
||||
mPositionGroup.clear();
|
||||
mExtents[0].clear();
|
||||
mExtents[1].clear();
|
||||
|
||||
for(S32 i = 0; i < NUM_DATA_TYPE; i++)
|
||||
{
|
||||
mData[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerOctreeEntry::~LLViewerOctreeEntry()
|
||||
{
|
||||
llassert(!mGroup);
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntry::addData(LLViewerOctreeEntryData* data)
|
||||
{
|
||||
//llassert(mData[data->getDataType()] == NULL);
|
||||
llassert(data != NULL);
|
||||
|
||||
mData[data->getDataType()] = data;
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntry::removeData(LLViewerOctreeEntryData* data)
|
||||
{
|
||||
//llassert(data->getDataType() != LLVOCACHEENTRY); //can not remove VOCache entry
|
||||
|
||||
if(!mData[data->getDataType()])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mData[data->getDataType()] = NULL;
|
||||
|
||||
if(mGroup != NULL && !mData[LLDRAWABLE])
|
||||
{
|
||||
LLviewerOctreeGroup* group = mGroup;
|
||||
mGroup = NULL;
|
||||
group->removeFromGroup(data);
|
||||
|
||||
llassert(mBinIndex == -1);
|
||||
}
|
||||
}
|
||||
|
||||
//called by group handleDestruction() ONLY when group is destroyed by octree.
|
||||
void LLViewerOctreeEntry::nullGroup()
|
||||
{
|
||||
mGroup = NULL;
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntry::setGroup(LLviewerOctreeGroup* group)
|
||||
{
|
||||
if(mGroup == group)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(mGroup)
|
||||
{
|
||||
LLviewerOctreeGroup* group = mGroup;
|
||||
mGroup = NULL;
|
||||
group->removeFromGroup(this);
|
||||
|
||||
llassert(mBinIndex == -1);
|
||||
}
|
||||
|
||||
mGroup = group;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//class LLViewerOctreeEntryData definitions
|
||||
//-----------------------------------------------------------------------------------
|
||||
LLViewerOctreeEntryData::~LLViewerOctreeEntryData()
|
||||
{
|
||||
if(mEntry)
|
||||
{
|
||||
mEntry->removeData(this);
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerOctreeEntryData::LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type)
|
||||
: mDataType(data_type),
|
||||
mEntry(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry)
|
||||
{
|
||||
if(mEntry.notNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!entry)
|
||||
{
|
||||
mEntry = new LLViewerOctreeEntry();
|
||||
}
|
||||
else
|
||||
{
|
||||
mEntry = entry;
|
||||
}
|
||||
mEntry->addData(this);
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntryData::setSpatialExtents(const LLVector3& min, const LLVector3& max)
|
||||
{
|
||||
mEntry->mExtents[0].load3(min.mV);
|
||||
mEntry->mExtents[1].load3(max.mV);
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntryData::setSpatialExtents(const LLVector4a& min, const LLVector4a& max)
|
||||
{
|
||||
mEntry->mExtents[0] = min;
|
||||
mEntry->mExtents[1] = max;
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntryData::setPositionGroup(const LLVector4a& pos)
|
||||
{
|
||||
mEntry->mPositionGroup = pos;
|
||||
}
|
||||
|
||||
const LLVector4a* LLViewerOctreeEntryData::getSpatialExtents() const
|
||||
{
|
||||
return mEntry->getSpatialExtents();
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerOctreeEntryData::setGroup(LLviewerOctreeGroup* group)
|
||||
{
|
||||
mEntry->setGroup(group);
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntryData::shift(const LLVector4a &shift_vector)
|
||||
{
|
||||
mEntry->mExtents[0].add(shift_vector);
|
||||
mEntry->mExtents[1].add(shift_vector);
|
||||
mEntry->mPositionGroup.add(shift_vector);
|
||||
}
|
||||
|
||||
LLviewerOctreeGroup* LLViewerOctreeEntryData::getGroup()const
|
||||
{
|
||||
return mEntry.notNull() ? mEntry->mGroup : NULL;
|
||||
}
|
||||
|
||||
const LLVector4a& LLViewerOctreeEntryData::getPositionGroup() const
|
||||
{
|
||||
return mEntry->getPositionGroup();
|
||||
}
|
||||
|
||||
//virtual
|
||||
bool LLViewerOctreeEntryData::isVisible() const
|
||||
{
|
||||
if(mEntry)
|
||||
{
|
||||
return mEntry->mVisible == sCurVisible;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//virtual
|
||||
bool LLViewerOctreeEntryData::isRecentlyVisible() const
|
||||
{
|
||||
if(!mEntry)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(isVisible())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(getGroup() && getGroup()->isRecentlyVisible())
|
||||
{
|
||||
setVisible();
|
||||
return true;
|
||||
}
|
||||
|
||||
return (sCurVisible - mEntry->mVisible < getMinVisFrameRange());
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntryData::setVisible() const
|
||||
{
|
||||
if(mEntry)
|
||||
{
|
||||
mEntry->mVisible = sCurVisible;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//class LLviewerOctreeGroup definitions
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
LLviewerOctreeGroup::~LLviewerOctreeGroup()
|
||||
{
|
||||
if(LLViewerRegion::sCurRegionp && isVisible())
|
||||
{
|
||||
LLViewerRegion::sCurRegionp->clearVisibleGroup(this);
|
||||
}
|
||||
}
|
||||
|
||||
LLviewerOctreeGroup::LLviewerOctreeGroup(OctreeNode* node) :
|
||||
mOctreeNode(node),
|
||||
mState(CLEAN)
|
||||
{
|
||||
LLVector4a tmp;
|
||||
tmp.splat(0.f);
|
||||
mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =
|
||||
mObjectExtents[0] = mObjectExtents[1] = tmp;
|
||||
|
||||
mBounds[0] = node->getCenter();
|
||||
mBounds[1] = node->getSize();
|
||||
|
||||
mOctreeNode->addListener(this);
|
||||
}
|
||||
|
||||
bool LLviewerOctreeGroup::hasElement(LLViewerOctreeEntryData* data)
|
||||
{
|
||||
if(!data->getEntry())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return std::find(getDataBegin(), getDataEnd(), data->getEntry()) != getDataEnd();
|
||||
}
|
||||
|
||||
bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntryData* data)
|
||||
{
|
||||
return removeFromGroup(data->getEntry());
|
||||
}
|
||||
|
||||
bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntry* entry)
|
||||
{
|
||||
llassert(entry != NULL);
|
||||
llassert(!entry->getGroup());
|
||||
|
||||
unbound();
|
||||
if (mOctreeNode)
|
||||
{
|
||||
if (!mOctreeNode->remove(entry))
|
||||
{
|
||||
OCT_ERRS << "Could not remove LLVOCacheEntry from LLVOCacheOctreeGroup" << llendl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
setState(OBJECT_DIRTY);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLviewerOctreeGroup::unbound()
|
||||
{
|
||||
if (isDirty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setState(DIRTY);
|
||||
|
||||
//all the parent nodes need to rebound this child
|
||||
if (mOctreeNode)
|
||||
{
|
||||
OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent();
|
||||
while (parent != NULL)
|
||||
{
|
||||
LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) parent->getListener(0);
|
||||
if (!group || group->isDirty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
group->setState(DIRTY);
|
||||
parent = (OctreeNode*) parent->getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLviewerOctreeGroup::rebound()
|
||||
{
|
||||
if (!isDirty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0)
|
||||
{
|
||||
LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0);
|
||||
group->rebound();
|
||||
|
||||
//copy single child's bounding box
|
||||
mBounds[0] = group->mBounds[0];
|
||||
mBounds[1] = group->mBounds[1];
|
||||
mExtents[0] = group->mExtents[0];
|
||||
mExtents[1] = group->mExtents[1];
|
||||
|
||||
group->setState(SKIP_FRUSTUM_CHECK);
|
||||
}
|
||||
else if (mOctreeNode->isLeaf())
|
||||
{ //copy object bounding box if this is a leaf
|
||||
boundObjects(TRUE, mExtents[0], mExtents[1]);
|
||||
mBounds[0] = mObjectBounds[0];
|
||||
mBounds[1] = mObjectBounds[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVector4a& newMin = mExtents[0];
|
||||
LLVector4a& newMax = mExtents[1];
|
||||
LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0);
|
||||
group->clearState(SKIP_FRUSTUM_CHECK);
|
||||
group->rebound();
|
||||
//initialize to first child
|
||||
newMin = group->mExtents[0];
|
||||
newMax = group->mExtents[1];
|
||||
|
||||
//first, rebound children
|
||||
for (U32 i = 1; i < mOctreeNode->getChildCount(); i++)
|
||||
{
|
||||
group = (LLviewerOctreeGroup*) mOctreeNode->getChild(i)->getListener(0);
|
||||
group->clearState(SKIP_FRUSTUM_CHECK);
|
||||
group->rebound();
|
||||
const LLVector4a& max = group->mExtents[1];
|
||||
const LLVector4a& min = group->mExtents[0];
|
||||
|
||||
newMax.setMax(newMax, max);
|
||||
newMin.setMin(newMin, min);
|
||||
}
|
||||
|
||||
boundObjects(FALSE, newMin, newMax);
|
||||
|
||||
mBounds[0].setAdd(newMin, newMax);
|
||||
mBounds[0].mul(0.5f);
|
||||
mBounds[1].setSub(newMax, newMin);
|
||||
mBounds[1].mul(0.5f);
|
||||
}
|
||||
|
||||
clearState(DIRTY);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLviewerOctreeGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj)
|
||||
{
|
||||
obj->setGroup(this);
|
||||
unbound();
|
||||
setState(OBJECT_DIRTY);
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLviewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj)
|
||||
{
|
||||
obj->setGroup(NULL);
|
||||
unbound();
|
||||
setState(OBJECT_DIRTY);
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLviewerOctreeGroup::handleDestruction(const TreeNode* node)
|
||||
{
|
||||
for (OctreeNode::element_iter i = mOctreeNode->getDataBegin(); i != mOctreeNode->getDataEnd(); ++i)
|
||||
{
|
||||
LLViewerOctreeEntry* obj = *i;
|
||||
if (obj && obj->getGroup() == this)
|
||||
{
|
||||
obj->nullGroup();
|
||||
//obj->setGroup(NULL);
|
||||
}
|
||||
}
|
||||
mOctreeNode = NULL;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLviewerOctreeGroup::handleStateChange(const TreeNode* node)
|
||||
{
|
||||
//drop bounding box upon state change
|
||||
if (mOctreeNode != node)
|
||||
{
|
||||
mOctreeNode = (OctreeNode*) node;
|
||||
}
|
||||
unbound();
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLviewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
|
||||
{
|
||||
if (child->getListenerCount() == 0)
|
||||
{
|
||||
new LLviewerOctreeGroup(child);
|
||||
}
|
||||
else
|
||||
{
|
||||
OCT_ERRS << "LLSpatialGroup redundancy detected." << llendl;
|
||||
}
|
||||
|
||||
unbound();
|
||||
|
||||
//((LLviewerOctreeGroup*)child->getListener(0))->unbound();
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLviewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child)
|
||||
{
|
||||
unbound();
|
||||
}
|
||||
|
||||
LLviewerOctreeGroup* LLviewerOctreeGroup::getParent()
|
||||
{
|
||||
if(!mOctreeNode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OctreeNode* parent = mOctreeNode->getOctParent();
|
||||
|
||||
if (parent)
|
||||
{
|
||||
return (LLviewerOctreeGroup*) parent->getListener(0);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//virtual
|
||||
bool LLviewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut)
|
||||
{
|
||||
const OctreeNode* node = mOctreeNode;
|
||||
|
||||
if (node->isEmpty())
|
||||
{ //don't do anything if there are no objects
|
||||
if (empty && mOctreeNode->getParent())
|
||||
{ //only root is allowed to be empty
|
||||
OCT_ERRS << "Empty leaf found in octree." << llendl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LLVector4a& newMin = mObjectExtents[0];
|
||||
LLVector4a& newMax = mObjectExtents[1];
|
||||
|
||||
if (hasState(OBJECT_DIRTY))
|
||||
{ //calculate new bounding box
|
||||
clearState(OBJECT_DIRTY);
|
||||
|
||||
//initialize bounding box to first element
|
||||
OctreeNode::const_element_iter i = node->getDataBegin();
|
||||
LLViewerOctreeEntry* entry = *i;
|
||||
const LLVector4a* minMax = entry->getSpatialExtents();
|
||||
|
||||
newMin = minMax[0];
|
||||
newMax = minMax[1];
|
||||
|
||||
for (++i; i != node->getDataEnd(); ++i)
|
||||
{
|
||||
entry = *i;
|
||||
minMax = entry->getSpatialExtents();
|
||||
|
||||
update_min_max(newMin, newMax, minMax[0]);
|
||||
update_min_max(newMin, newMax, minMax[1]);
|
||||
}
|
||||
|
||||
mObjectBounds[0].setAdd(newMin, newMax);
|
||||
mObjectBounds[0].mul(0.5f);
|
||||
mObjectBounds[1].setSub(newMax, newMin);
|
||||
mObjectBounds[1].mul(0.5f);
|
||||
}
|
||||
|
||||
if (empty)
|
||||
{
|
||||
minOut = newMin;
|
||||
maxOut = newMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
minOut.setMin(minOut, newMin);
|
||||
maxOut.setMax(maxOut, newMax);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLviewerOctreeGroup::isVisible() const
|
||||
{
|
||||
return mVisible[LLViewerCamera::sCurCameraID] >= LLViewerOctreeEntryData::getCurrentFrame() ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLviewerOctreeGroup::isRecentlyVisible() const
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLviewerOctreeGroup::setVisible()
|
||||
{
|
||||
mVisible[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame();
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
//class LLViewerOctreePartition definitions
|
||||
//-----------------------------------------------------------------------------------
|
||||
LLViewerOctreePartition::LLViewerOctreePartition() : mRegionp(NULL)
|
||||
{
|
||||
LLVector4a center, size;
|
||||
center.splat(0.f);
|
||||
size.splat(1.f);
|
||||
|
||||
mOctree = new OctreeRoot(center,size, NULL);
|
||||
}
|
||||
|
||||
LLViewerOctreePartition::~LLViewerOctreePartition()
|
||||
{
|
||||
delete mOctree;
|
||||
mOctree = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//class LLViewerOctreeCull definitions
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
//virtual
|
||||
bool LLViewerOctreeCull::earlyFail(LLviewerOctreeGroup* group)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerOctreeCull::traverse(const OctreeNode* n)
|
||||
{
|
||||
LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) n->getListener(0);
|
||||
|
||||
if (earlyFail(group))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mRes == 2 ||
|
||||
(mRes && group->hasState(LLviewerOctreeGroup::SKIP_FRUSTUM_CHECK)))
|
||||
{ //fully in, just add everything
|
||||
OctreeTraveler::traverse(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
mRes = frustumCheck(group);
|
||||
|
||||
if (mRes)
|
||||
{ //at least partially in, run on down
|
||||
OctreeTraveler::traverse(n);
|
||||
}
|
||||
|
||||
mRes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
//agent space group culling
|
||||
S32 LLViewerOctreeCull::AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]);
|
||||
}
|
||||
|
||||
S32 LLViewerOctreeCull::AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist);
|
||||
}
|
||||
|
||||
S32 LLViewerOctreeCull::AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]);
|
||||
}
|
||||
//------------------------------------------
|
||||
|
||||
//------------------------------------------
|
||||
//agent space object set culling
|
||||
S32 LLViewerOctreeCull::AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]);
|
||||
}
|
||||
|
||||
S32 LLViewerOctreeCull::AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist);
|
||||
}
|
||||
|
||||
S32 LLViewerOctreeCull::AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]);
|
||||
}
|
||||
//------------------------------------------
|
||||
|
||||
//------------------------------------------
|
||||
//local regional space group culling
|
||||
S32 LLViewerOctreeCull::AABBInRegionFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return mCamera->AABBInRegionFrustumNoFarClip(group->mBounds[0], group->mBounds[1]);
|
||||
}
|
||||
|
||||
S32 LLViewerOctreeCull::AABBInRegionFrustumGroupBounds(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return mCamera->AABBInRegionFrustum(group->mBounds[0], group->mBounds[1]);
|
||||
}
|
||||
|
||||
S32 LLViewerOctreeCull::AABBRegionSphereIntersectGroupExtents(const LLviewerOctreeGroup* group, const LLVector3& shift)
|
||||
{
|
||||
return AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin() - shift, mCamera->mFrustumCornerDist);
|
||||
}
|
||||
//------------------------------------------
|
||||
|
||||
//------------------------------------------
|
||||
//local regional space object culling
|
||||
S32 LLViewerOctreeCull::AABBInRegionFrustumObjectBounds(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return mCamera->AABBInRegionFrustum(group->mObjectBounds[0], group->mObjectBounds[1]);
|
||||
}
|
||||
|
||||
S32 LLViewerOctreeCull::AABBInRegionFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
return mCamera->AABBInRegionFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]);
|
||||
}
|
||||
|
||||
S32 LLViewerOctreeCull::AABBRegionSphereIntersectObjectExtents(const LLviewerOctreeGroup* group, const LLVector3& shift)
|
||||
{
|
||||
return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin() - shift, mCamera->mFrustumCornerDist);
|
||||
}
|
||||
//------------------------------------------
|
||||
|
||||
//virtual
|
||||
bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group)
|
||||
{
|
||||
if (branch->getElementCount() == 0) //no elements
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerOctreeCull::preprocess(LLviewerOctreeGroup* group)
|
||||
{
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerOctreeCull::processGroup(LLviewerOctreeGroup* group)
|
||||
{
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerOctreeCull::visit(const OctreeNode* branch)
|
||||
{
|
||||
LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) branch->getListener(0);
|
||||
|
||||
preprocess(group);
|
||||
|
||||
if (checkObjects(branch, group))
|
||||
{
|
||||
processGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,327 @@
|
|||
/**
|
||||
* @file llvieweroctree.h
|
||||
* @brief LLViewerObjectOctree.cpp header file, defining all supporting classes.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_VIEWEROCTREE_H
|
||||
#define LL_VIEWEROCTREE_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "v2math.h"
|
||||
#include "v3math.h"
|
||||
#include "v4math.h"
|
||||
#include "m4math.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llquaternion.h"
|
||||
#include "lloctree.h"
|
||||
#include "llviewercamera.h"
|
||||
|
||||
class LLViewerRegion;
|
||||
class LLViewerOctreeEntryData;
|
||||
class LLviewerOctreeGroup;
|
||||
class LLViewerOctreeEntry;
|
||||
|
||||
typedef LLOctreeListener<LLViewerOctreeEntry> OctreeListener;
|
||||
typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
|
||||
typedef LLOctreeNode<LLViewerOctreeEntry> OctreeNode;
|
||||
typedef LLOctreeRoot<LLViewerOctreeEntry> OctreeRoot;
|
||||
typedef LLOctreeTraveler<LLViewerOctreeEntry> OctreeTraveler;
|
||||
|
||||
S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad);
|
||||
S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared);
|
||||
|
||||
S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad);
|
||||
S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared);
|
||||
|
||||
//defines data needed for octree of an entry
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLViewerOctreeEntry : public LLRefCount
|
||||
{
|
||||
friend class LLViewerOctreeEntryData;
|
||||
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
LLDRAWABLE = 0,
|
||||
LLVOCACHEENTRY,
|
||||
NUM_DATA_TYPE
|
||||
}eEntryDataType_t;
|
||||
|
||||
~LLViewerOctreeEntry();
|
||||
public:
|
||||
LLViewerOctreeEntry();
|
||||
|
||||
void nullGroup(); //called by group handleDestruction() only
|
||||
void setGroup(LLviewerOctreeGroup* group);
|
||||
void removeData(LLViewerOctreeEntryData* data);
|
||||
|
||||
LLViewerOctreeEntryData* getData(U32 data_type)const {return mData[data_type];}
|
||||
bool hasData(U32 data_type)const {return mData[data_type] != NULL;}
|
||||
|
||||
LLViewerOctreeEntryData* getDrawable() const {return mData[LLDRAWABLE];}
|
||||
bool hasDrawable() const {return mData[LLDRAWABLE] != NULL;}
|
||||
LLViewerOctreeEntryData* getVOCacheEntry() const {return mData[LLVOCACHEENTRY];}
|
||||
bool hasVOCacheEntry() const {return mData[LLVOCACHEENTRY] != NULL;}
|
||||
|
||||
const LLVector4a* getSpatialExtents() const {return mExtents;}
|
||||
const LLVector4a& getPositionGroup() const {return mPositionGroup;}
|
||||
LLviewerOctreeGroup* getGroup()const {return mGroup;}
|
||||
|
||||
F32 getBinRadius() const {return mBinRadius;}
|
||||
S32 getBinIndex() const {return mBinIndex; }
|
||||
void setBinIndex(S32 index) const {mBinIndex = index; }
|
||||
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return ll_aligned_malloc_16(size);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr)
|
||||
{
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
void addData(LLViewerOctreeEntryData* data);
|
||||
|
||||
private:
|
||||
LLViewerOctreeEntryData* mData[NUM_DATA_TYPE]; //do not use LLPointer here.
|
||||
LLviewerOctreeGroup* mGroup;
|
||||
|
||||
//aligned members
|
||||
LL_ALIGN_16(LLVector4a mExtents[2]);
|
||||
LL_ALIGN_16(LLVector4a mPositionGroup);
|
||||
F32 mBinRadius;
|
||||
mutable S32 mBinIndex;
|
||||
mutable U32 mVisible;
|
||||
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
//defines an abstract class for entry data
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLViewerOctreeEntryData : public LLRefCount
|
||||
{
|
||||
protected:
|
||||
~LLViewerOctreeEntryData();
|
||||
|
||||
public:
|
||||
LLViewerOctreeEntryData(const LLViewerOctreeEntryData& rhs)
|
||||
{
|
||||
*this = rhs;
|
||||
}
|
||||
LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type);
|
||||
|
||||
LLViewerOctreeEntry::eEntryDataType_t getDataType() const {return mDataType;}
|
||||
LLViewerOctreeEntry* getEntry() {return mEntry;}
|
||||
|
||||
virtual void setOctreeEntry(LLViewerOctreeEntry* entry);
|
||||
|
||||
virtual S32 getMinVisFrameRange()const = 0;
|
||||
|
||||
F32 getBinRadius() const {return mEntry->getBinRadius();}
|
||||
const LLVector4a* getSpatialExtents() const;
|
||||
LLviewerOctreeGroup* getGroup()const;
|
||||
const LLVector4a& getPositionGroup() const;
|
||||
|
||||
void setBinRadius(F32 rad) {mEntry->mBinRadius = rad;}
|
||||
void setSpatialExtents(const LLVector3& min, const LLVector3& max);
|
||||
void setSpatialExtents(const LLVector4a& min, const LLVector4a& max);
|
||||
void setPositionGroup(const LLVector4a& pos);
|
||||
|
||||
virtual void setGroup(LLviewerOctreeGroup* group);
|
||||
void shift(const LLVector4a &shift_vector);
|
||||
|
||||
U32 getVisible() const {return mEntry ? mEntry->mVisible : 0;}
|
||||
void setVisible() const;
|
||||
virtual bool isVisible() const;
|
||||
virtual bool isRecentlyVisible() const;
|
||||
|
||||
static S32 getCurrentFrame() { return sCurVisible; }
|
||||
|
||||
protected:
|
||||
LLVector4a& getGroupPosition() {return mEntry->mPositionGroup;}
|
||||
void initVisible(U32 visible) {mEntry->mVisible = visible;}
|
||||
|
||||
static void incrementVisible() {sCurVisible++;}
|
||||
protected:
|
||||
LLPointer<LLViewerOctreeEntry> mEntry;
|
||||
LLViewerOctreeEntry::eEntryDataType_t mDataType;
|
||||
static U32 sCurVisible; // Counter for what value of mVisible means currently visible
|
||||
}LL_ALIGN_POSTFIX(16);
|
||||
|
||||
|
||||
//defines an octree group for an octree node, which contains multiple entries.
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLviewerOctreeGroup : public LLOctreeListener<LLViewerOctreeEntry>
|
||||
{
|
||||
friend class LLViewerOctreeCull;
|
||||
protected:
|
||||
~LLviewerOctreeGroup();
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
CLEAN = 0x00000000,
|
||||
DIRTY = 0x00000001,
|
||||
OBJECT_DIRTY = 0x00000002,
|
||||
SKIP_FRUSTUM_CHECK = 0x00000004,
|
||||
INVALID_STATE = 0x00000008,
|
||||
};
|
||||
|
||||
public:
|
||||
typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter;
|
||||
typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list;
|
||||
|
||||
LLviewerOctreeGroup(OctreeNode* node);
|
||||
LLviewerOctreeGroup(const LLviewerOctreeGroup& rhs)
|
||||
{
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return ll_aligned_malloc_16(size);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr)
|
||||
{
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
|
||||
bool removeFromGroup(LLViewerOctreeEntryData* data);
|
||||
bool removeFromGroup(LLViewerOctreeEntry* entry);
|
||||
|
||||
virtual void unbound();
|
||||
virtual void rebound();
|
||||
|
||||
void setVisible();
|
||||
BOOL isVisible() const;
|
||||
virtual BOOL isRecentlyVisible() const;
|
||||
bool isEmpty() const { return mOctreeNode->isEmpty(); }
|
||||
|
||||
U32 getState() {return mState; }
|
||||
bool isDirty() const {return mState & DIRTY;}
|
||||
bool hasState(U32 state) const {return mState & state;}
|
||||
void setState(U32 state) {mState |= state;}
|
||||
void clearState(U32 state) {mState &= ~state;}
|
||||
|
||||
//LISTENER FUNCTIONS
|
||||
virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj);
|
||||
virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj);
|
||||
virtual void handleDestruction(const TreeNode* node);
|
||||
virtual void handleStateChange(const TreeNode* node);
|
||||
virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
|
||||
virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);
|
||||
|
||||
OctreeNode* getOctreeNode() {return mOctreeNode;}
|
||||
LLviewerOctreeGroup* getParent();
|
||||
|
||||
const LLVector4a* getBounds() const {return mBounds;}
|
||||
const LLVector4a* getExtents() const {return mExtents;}
|
||||
const LLVector4a* getObjectBounds() const {return mObjectBounds;}
|
||||
const LLVector4a* getObjectExtents() const {return mObjectExtents;}
|
||||
|
||||
//octree wrappers to make code more readable
|
||||
element_list& getData() { return mOctreeNode->getData(); }
|
||||
element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
|
||||
element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
|
||||
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
|
||||
bool hasElement(LLViewerOctreeEntryData* data);
|
||||
|
||||
private:
|
||||
virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut);
|
||||
|
||||
protected:
|
||||
U32 mState;
|
||||
OctreeNode* mOctreeNode;
|
||||
|
||||
LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
|
||||
LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node
|
||||
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
|
||||
LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node
|
||||
|
||||
public:
|
||||
S32 mVisible[LLViewerCamera::NUM_CAMERAS];
|
||||
}LL_ALIGN_POSTFIX(16);
|
||||
|
||||
class LLViewerOctreePartition
|
||||
{
|
||||
public:
|
||||
LLViewerOctreePartition();
|
||||
virtual ~LLViewerOctreePartition();
|
||||
|
||||
// Cull on arbitrary frustum
|
||||
virtual S32 cull(LLCamera &camera) = 0;
|
||||
|
||||
public:
|
||||
U32 mPartitionType;
|
||||
OctreeNode* mOctree;
|
||||
LLViewerRegion* mRegionp; // the region this partition belongs to.
|
||||
};
|
||||
|
||||
class LLViewerOctreeCull : public OctreeTraveler
|
||||
{
|
||||
public:
|
||||
LLViewerOctreeCull(LLCamera* camera)
|
||||
: mCamera(camera), mRes(0) { }
|
||||
|
||||
virtual bool earlyFail(LLviewerOctreeGroup* group);
|
||||
virtual void traverse(const OctreeNode* n);
|
||||
|
||||
//agent space group cull
|
||||
S32 AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group);
|
||||
S32 AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group);
|
||||
S32 AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group);
|
||||
|
||||
//agent space object set cull
|
||||
S32 AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group);
|
||||
S32 AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group);
|
||||
S32 AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group);
|
||||
|
||||
//local region space group cull
|
||||
S32 AABBInRegionFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group);
|
||||
S32 AABBInRegionFrustumGroupBounds(const LLviewerOctreeGroup* group);
|
||||
S32 AABBRegionSphereIntersectGroupExtents(const LLviewerOctreeGroup* group, const LLVector3& shift);
|
||||
|
||||
//local region space object set cull
|
||||
S32 AABBInRegionFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group);
|
||||
S32 AABBInRegionFrustumObjectBounds(const LLviewerOctreeGroup* group);
|
||||
S32 AABBRegionSphereIntersectObjectExtents(const LLviewerOctreeGroup* group, const LLVector3& shift);
|
||||
|
||||
virtual S32 frustumCheck(const LLviewerOctreeGroup* group) = 0;
|
||||
virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) = 0;
|
||||
|
||||
virtual bool checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group);
|
||||
virtual void preprocess(LLviewerOctreeGroup* group);
|
||||
virtual void processGroup(LLviewerOctreeGroup* group);
|
||||
virtual void visit(const OctreeNode* branch);
|
||||
|
||||
protected:
|
||||
LLCamera *mCamera;
|
||||
S32 mRes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -151,8 +151,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo
|
|||
|
||||
if (group != NULL)
|
||||
{
|
||||
LLVector3 center(group->mOctreeNode->getCenter().getF32ptr());
|
||||
LLVector3 size(group->mOctreeNode->getSize().getF32ptr());
|
||||
LLVector3 center(group->getOctreeNode()->getCenter().getF32ptr());
|
||||
LLVector3 size(group->getOctreeNode()->getSize().getF32ptr());
|
||||
size += LLVector3(0.01f, 0.01f, 0.01f);
|
||||
mMinObjPos = center - size;
|
||||
mMaxObjPos = center + size;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
#include "stringize.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llvieweroctree.h"
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
#pragma warning(disable:4355)
|
||||
|
|
@ -85,6 +86,9 @@ const F32 CAP_REQUEST_TIMEOUT = 18;
|
|||
// Even though we gave up on login, keep trying for caps after we are logged in:
|
||||
const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
|
||||
|
||||
LLViewerRegion* LLViewerRegion::sCurRegionp = NULL;
|
||||
BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE;
|
||||
|
||||
typedef std::map<std::string, std::string> CapabilityMap;
|
||||
|
||||
class LLViewerRegionImpl {
|
||||
|
|
@ -97,6 +101,8 @@ public:
|
|||
mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
|
||||
mSeedCapAttempts(0),
|
||||
mHttpResponderID(0),
|
||||
mLastCameraUpdate(0),
|
||||
mLastCameraOrigin(),
|
||||
// I'd prefer to set the LLCapabilityListener name to match the region
|
||||
// name -- it's disappointing that's not available at construction time.
|
||||
// We could instead store an LLCapabilityListener*, making
|
||||
|
|
@ -133,7 +139,14 @@ public:
|
|||
// Misc
|
||||
LLVLComposition *mCompositionp; // Composition layer for the surface
|
||||
|
||||
LLVOCacheEntry::vocache_entry_map_t mCacheMap;
|
||||
LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries
|
||||
LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries;
|
||||
LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated.
|
||||
std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible groupa
|
||||
LLVOCachePartition* mVOCachePartition;
|
||||
LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation.
|
||||
LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation.
|
||||
|
||||
// time?
|
||||
// LRU info?
|
||||
|
||||
|
|
@ -157,7 +170,10 @@ public:
|
|||
LLCapabilityListener mCapabilityListener;
|
||||
|
||||
//spatial partitions for objects in this region
|
||||
std::vector<LLSpatialPartition*> mObjectPartition;
|
||||
std::vector<LLViewerOctreePartition*> mObjectPartition;
|
||||
|
||||
LLVector3 mLastCameraOrigin;
|
||||
U32 mLastCameraUpdate;
|
||||
};
|
||||
|
||||
// support for secondlife:///app/region/{REGION} SLapps
|
||||
|
|
@ -292,7 +308,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
|
|||
mReleaseNotesRequested(FALSE),
|
||||
mCapabilitiesReceived(false),
|
||||
mBitsReceived(0.f),
|
||||
mPacketsReceived(0.f)
|
||||
mPacketsReceived(0.f),
|
||||
mDead(FALSE)
|
||||
{
|
||||
mWidth = region_width_meters;
|
||||
mImpl->mOriginGlobal = from_region_handle(handle);
|
||||
|
|
@ -324,17 +341,20 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
|
|||
|
||||
//create object partitions
|
||||
//MUST MATCH declaration of eObjectPartitions
|
||||
mImpl->mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD
|
||||
mImpl->mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN
|
||||
mImpl->mObjectPartition.push_back(new LLVoidWaterPartition()); //PARTITION_VOIDWATER
|
||||
mImpl->mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER
|
||||
mImpl->mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE
|
||||
mImpl->mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE
|
||||
mImpl->mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS
|
||||
mImpl->mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME
|
||||
mImpl->mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE
|
||||
mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
|
||||
mImpl->mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD
|
||||
mImpl->mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN
|
||||
mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER
|
||||
mImpl->mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER
|
||||
mImpl->mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE
|
||||
mImpl->mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE
|
||||
mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS
|
||||
mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME
|
||||
mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE
|
||||
mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE
|
||||
mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE
|
||||
mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE
|
||||
|
||||
mImpl->mVOCachePartition = getVOCachePartition();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -355,6 +375,12 @@ void LLViewerRegion::initStats()
|
|||
|
||||
LLViewerRegion::~LLViewerRegion()
|
||||
{
|
||||
mDead = TRUE;
|
||||
mImpl->mActiveSet.clear();
|
||||
mImpl->mVisibleEntries.clear();
|
||||
mImpl->mVisibleGroups.clear();
|
||||
mImpl->mWaitingSet.clear();
|
||||
|
||||
gVLManager.cleanupData(this);
|
||||
// Can't do this on destruction, because the neighbor pointers might be invalid.
|
||||
// This should be reference counted...
|
||||
|
|
@ -367,12 +393,12 @@ LLViewerRegion::~LLViewerRegion()
|
|||
delete mParcelOverlay;
|
||||
delete mImpl->mLandp;
|
||||
delete mImpl->mEventPoll;
|
||||
LLHTTPSender::clearSender(mImpl->mHost);
|
||||
|
||||
saveObjectCache();
|
||||
LLHTTPSender::clearSender(mImpl->mHost);
|
||||
|
||||
std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
|
||||
|
||||
saveObjectCache();
|
||||
|
||||
delete mImpl;
|
||||
mImpl = NULL;
|
||||
}
|
||||
|
|
@ -438,10 +464,6 @@ void LLViewerRegion::saveObjectCache()
|
|||
mCacheDirty = FALSE;
|
||||
}
|
||||
|
||||
for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
|
||||
{
|
||||
delete iter->second;
|
||||
}
|
||||
mImpl->mCacheMap.clear();
|
||||
}
|
||||
|
||||
|
|
@ -719,8 +741,354 @@ void LLViewerRegion::dirtyHeights()
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry)
|
||||
{
|
||||
U32 state = LLVOCacheEntry::INACTIVE;
|
||||
|
||||
if(old_entry)
|
||||
{
|
||||
old_entry->copyTo(new_entry);
|
||||
state = old_entry->getState();
|
||||
killCacheEntry(old_entry);
|
||||
}
|
||||
|
||||
mImpl->mCacheMap[new_entry->getLocalID()] = new_entry;
|
||||
|
||||
if(state == LLVOCacheEntry::ACTIVE)
|
||||
{
|
||||
llassert(new_entry->getEntry()->hasDrawable());
|
||||
mImpl->mActiveSet.insert(new_entry);
|
||||
}
|
||||
else if(state == LLVOCacheEntry::WAITING)
|
||||
{
|
||||
mImpl->mWaitingSet.insert(new_entry);
|
||||
}
|
||||
else if(old_entry && new_entry->getEntry())
|
||||
{
|
||||
addToVOCacheTree(new_entry);
|
||||
}
|
||||
new_entry->setState(state);
|
||||
}
|
||||
|
||||
//physically delete the cache entry
|
||||
void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry)
|
||||
{
|
||||
if(!entry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//remove from active list and waiting list
|
||||
if(entry->isState(LLVOCacheEntry::ACTIVE))
|
||||
{
|
||||
mImpl->mActiveSet.erase(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(entry->isState(LLVOCacheEntry::WAITING))
|
||||
{
|
||||
mImpl->mWaitingSet.erase(entry);
|
||||
}
|
||||
|
||||
//remove from mVOCachePartition
|
||||
removeFromVOCacheTree(entry);
|
||||
}
|
||||
|
||||
//remove from the forced visible list
|
||||
mImpl->mVisibleEntries.erase(entry);
|
||||
|
||||
//kill LLViewerObject if exists
|
||||
//this should be done by the rendering pipeline automatically.
|
||||
|
||||
entry->setState(LLVOCacheEntry::INACTIVE);
|
||||
|
||||
//remove from mCacheMap, real deletion
|
||||
mImpl->mCacheMap.erase(entry->getLocalID());
|
||||
}
|
||||
|
||||
//physically delete the cache entry
|
||||
void LLViewerRegion::killCacheEntry(U32 local_id)
|
||||
{
|
||||
killCacheEntry(getCacheEntry(local_id));
|
||||
}
|
||||
|
||||
U32 LLViewerRegion::getNumOfActiveCachedObjects() const
|
||||
{
|
||||
return mImpl->mActiveSet.size();
|
||||
}
|
||||
|
||||
void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry)
|
||||
{
|
||||
if(!entry || mDead)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(entry->isState(LLVOCacheEntry::WAITING))
|
||||
{
|
||||
mImpl->mWaitingSet.erase(entry);
|
||||
}
|
||||
|
||||
entry->setState(LLVOCacheEntry::ACTIVE);
|
||||
entry->setVisible();
|
||||
|
||||
llassert(entry->getEntry()->hasDrawable());
|
||||
mImpl->mActiveSet.insert(entry);
|
||||
}
|
||||
|
||||
void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep)
|
||||
{
|
||||
if(mDead)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(drawablep->getParent()) //child object
|
||||
{
|
||||
LLViewerOctreeEntry* parent_oct_entry = drawablep->getParent()->getEntry();
|
||||
if(parent_oct_entry && parent_oct_entry->hasVOCacheEntry())
|
||||
{
|
||||
LLVOCacheEntry* parent = (LLVOCacheEntry*)parent_oct_entry->getVOCacheEntry();
|
||||
parent->addChild(entry);
|
||||
}
|
||||
}
|
||||
else //insert to vo cache tree.
|
||||
{
|
||||
//shift to the local regional space from agent space
|
||||
const LLVector3 pos = drawablep->getVObj()->getPositionRegion();
|
||||
LLVector4a vec(pos[0], pos[1], pos[2]);
|
||||
LLVector4a shift;
|
||||
shift.setSub(vec, entry->getPositionGroup());
|
||||
entry->shift(shift);
|
||||
|
||||
addToVOCacheTree(entry);
|
||||
}
|
||||
|
||||
mImpl->mVisibleEntries.erase(entry);
|
||||
mImpl->mActiveSet.erase(entry);
|
||||
mImpl->mWaitingSet.erase(entry);
|
||||
entry->setState(LLVOCacheEntry::INACTIVE);
|
||||
}
|
||||
|
||||
void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group)
|
||||
{
|
||||
if(mDead || group->isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
group->setVisible();
|
||||
mImpl->mVisibleGroups.insert(group);
|
||||
}
|
||||
|
||||
void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
|
||||
{
|
||||
if(!sVOCacheCullingEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(mDead || !entry || !entry->getEntry())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(entry->getGroup()) //already in octree.
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!entry->hasState(LLVOCacheEntry::ADD_TO_CACHE_TREE))
|
||||
{
|
||||
return; //can not add to vo cache tree.
|
||||
}
|
||||
|
||||
mImpl->mVOCachePartition->addEntry(entry->getEntry());
|
||||
}
|
||||
|
||||
void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry)
|
||||
{
|
||||
if(mDead || !entry || !entry->getEntry())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!entry->getGroup())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mImpl->mVOCachePartition->removeEntry(entry->getEntry());
|
||||
}
|
||||
|
||||
//add the visible entries
|
||||
void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry)
|
||||
{
|
||||
if(mDead || !entry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(entry->isState(LLVOCacheEntry::IN_QUEUE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(entry->isState(LLVOCacheEntry::INACTIVE))
|
||||
{
|
||||
entry->setState(LLVOCacheEntry::IN_QUEUE);
|
||||
}
|
||||
mImpl->mVisibleEntries.insert(entry);
|
||||
}
|
||||
|
||||
void LLViewerRegion::clearVisibleGroup(LLviewerOctreeGroup* group)
|
||||
{
|
||||
if(mDead)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
llassert(!group->getOctreeNode() || group->isEmpty());
|
||||
|
||||
mImpl->mVisibleGroups.erase(group);
|
||||
}
|
||||
|
||||
F32 LLViewerRegion::updateVisibleEntries(F32 max_time)
|
||||
{
|
||||
if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty())
|
||||
{
|
||||
return max_time;
|
||||
}
|
||||
|
||||
LLTimer update_timer;
|
||||
|
||||
const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin();
|
||||
const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame();
|
||||
bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f);
|
||||
|
||||
//process visible entries
|
||||
max_time *= 0.5f; //only use up to half available time to update entries.
|
||||
|
||||
#if 1
|
||||
for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();)
|
||||
{
|
||||
LLVOCacheEntry* vo_entry = *iter;
|
||||
vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate);
|
||||
|
||||
if(vo_entry->getState() < LLVOCacheEntry::WAITING)
|
||||
{
|
||||
mImpl->mWaitingList.insert(vo_entry);
|
||||
}
|
||||
|
||||
LLVOCacheEntry* child;
|
||||
S32 num_child = vo_entry->getNumOfChildren();
|
||||
S32 num_done = 0;
|
||||
for(S32 i = 0; i < num_child; i++)
|
||||
{
|
||||
child = vo_entry->getChild(i);
|
||||
if(child->getState() < LLVOCacheEntry::WAITING)
|
||||
{
|
||||
child->setSceneContribution(vo_entry->getSceneContribution());
|
||||
mImpl->mWaitingList.insert(child);
|
||||
}
|
||||
else
|
||||
{
|
||||
num_done++;
|
||||
}
|
||||
}
|
||||
if(num_done == num_child)
|
||||
{
|
||||
vo_entry->clearChildrenList();
|
||||
}
|
||||
|
||||
if(!vo_entry->getNumOfChildren())
|
||||
{
|
||||
if(vo_entry->getState() >= LLVOCacheEntry::WAITING)
|
||||
{
|
||||
iter = mImpl->mVisibleEntries.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
|
||||
//if(update_timer.getElapsedTimeF32() > max_time)
|
||||
//{
|
||||
// break;
|
||||
//}
|
||||
}
|
||||
#endif
|
||||
|
||||
//process visible groups
|
||||
std::set< LLviewerOctreeGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin();
|
||||
for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter)
|
||||
{
|
||||
LLviewerOctreeGroup* group = *group_iter;
|
||||
if(!group->getOctreeNode() || group->isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
|
||||
{
|
||||
if((*i)->hasVOCacheEntry())
|
||||
{
|
||||
LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry();
|
||||
|
||||
vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate);
|
||||
mImpl->mWaitingList.insert(vo_entry);
|
||||
}
|
||||
}
|
||||
|
||||
//if(update_timer.getElapsedTimeF32() > max_time)
|
||||
//{
|
||||
// break;
|
||||
//}
|
||||
}
|
||||
mImpl->mVisibleGroups.clear();
|
||||
|
||||
if(needs_update)
|
||||
{
|
||||
mImpl->mLastCameraOrigin = camera_origin;
|
||||
mImpl->mLastCameraUpdate = cur_frame;
|
||||
}
|
||||
|
||||
return 2.0f * max_time - update_timer.getElapsedTimeF32();
|
||||
}
|
||||
|
||||
F32 LLViewerRegion::createVisibleObjects(F32 max_time)
|
||||
{
|
||||
if(mImpl->mWaitingList.empty())
|
||||
{
|
||||
return max_time;
|
||||
}
|
||||
|
||||
LLTimer update_timer;
|
||||
S32 max_num_objects = 64; //minimum number of new objects to be added
|
||||
for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin();
|
||||
iter != mImpl->mWaitingList.end(); ++iter)
|
||||
{
|
||||
LLVOCacheEntry* vo_entry = *iter;
|
||||
|
||||
if(vo_entry->getState() < LLVOCacheEntry::WAITING)
|
||||
{
|
||||
addNewObject(vo_entry);
|
||||
if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mImpl->mWaitingList.clear();
|
||||
|
||||
return max_time - update_timer.getElapsedTimeF32();
|
||||
}
|
||||
|
||||
BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
|
||||
{
|
||||
LLTimer update_timer;
|
||||
|
||||
// did_update returns TRUE if we did at least one significant update
|
||||
BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);
|
||||
|
||||
|
|
@ -730,9 +1098,98 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
|
|||
mParcelOverlay->idleUpdate();
|
||||
}
|
||||
|
||||
max_update_time -= update_timer.getElapsedTimeF32();
|
||||
if(max_update_time < 0.f || mImpl->mCacheMap.empty())
|
||||
{
|
||||
return did_update;
|
||||
}
|
||||
|
||||
sCurRegionp = this;
|
||||
|
||||
//kill invisible objects
|
||||
max_update_time = killInvisibleObjects(max_update_time);
|
||||
|
||||
max_update_time = updateVisibleEntries(max_update_time);
|
||||
createVisibleObjects(max_update_time);
|
||||
|
||||
mImpl->mVisibleGroups.clear();
|
||||
mImpl->mWaitingList.clear();
|
||||
|
||||
sCurRegionp = NULL;
|
||||
return did_update;
|
||||
}
|
||||
|
||||
F32 LLViewerRegion::killInvisibleObjects(F32 max_time)
|
||||
{
|
||||
if(!sVOCacheCullingEnabled)
|
||||
{
|
||||
return max_time;
|
||||
}
|
||||
|
||||
std::vector<LLDrawable*> delete_list;
|
||||
for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin();
|
||||
iter != mImpl->mActiveSet.end(); ++iter)
|
||||
{
|
||||
if(!(*iter)->isRecentlyVisible())
|
||||
{
|
||||
killObject((*iter), delete_list);
|
||||
}
|
||||
}
|
||||
for(S32 i = 0; i < delete_list.size(); i++)
|
||||
{
|
||||
gObjectList.killObject(delete_list[i]->getVObj(), true);
|
||||
}
|
||||
delete_list.clear();
|
||||
|
||||
return max_time;
|
||||
}
|
||||
|
||||
void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list)
|
||||
{
|
||||
//kill the object.
|
||||
LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable();
|
||||
llassert(drawablep);
|
||||
|
||||
if(!drawablep->getParent())
|
||||
{
|
||||
LLViewerObject::const_child_list_t& child_list = drawablep->getVObj()->getChildren();
|
||||
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
|
||||
iter != child_list.end(); iter++)
|
||||
{
|
||||
LLViewerObject* child = *iter;
|
||||
if(child->mDrawable->isRecentlyVisible())
|
||||
{
|
||||
//set the parent group visible if any of its children visible.
|
||||
((LLViewerOctreeEntryData*)drawablep)->setVisible();
|
||||
return;
|
||||
}
|
||||
}
|
||||
delete_list.push_back(drawablep);
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
|
||||
{
|
||||
LLViewerObject* obj = NULL;
|
||||
if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet
|
||||
{
|
||||
//add the object
|
||||
obj = gObjectList.processObjectUpdateFromCache(entry, this);
|
||||
if(obj)
|
||||
{
|
||||
if(!entry->isState(LLVOCacheEntry::ACTIVE))
|
||||
{
|
||||
mImpl->mWaitingSet.insert(entry);
|
||||
entry->setState(LLVOCacheEntry::WAITING);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Object is already created." << llendl;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
// As above, but forcibly do the update.
|
||||
void LLViewerRegion::forceUpdate()
|
||||
|
|
@ -1191,8 +1648,9 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec
|
|||
{
|
||||
U32 local_id = objectp->getLocalID();
|
||||
U32 crc = objectp->getCRC();
|
||||
eCacheUpdateResult result;
|
||||
|
||||
LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
|
||||
LLVOCacheEntry* entry = getCacheEntry(local_id);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
|
|
@ -1201,41 +1659,72 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec
|
|||
{
|
||||
// Record a hit
|
||||
entry->recordDupe();
|
||||
return CACHE_UPDATE_DUPE;
|
||||
result = CACHE_UPDATE_DUPE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the cache entry
|
||||
LLPointer<LLVOCacheEntry> new_entry = new LLVOCacheEntry(local_id, crc, dp);
|
||||
replaceCacheEntry(entry, new_entry);
|
||||
entry = new_entry;
|
||||
|
||||
// Update the cache entry
|
||||
mImpl->mCacheMap.erase(local_id);
|
||||
delete entry;
|
||||
entry = new LLVOCacheEntry(local_id, crc, dp);
|
||||
mImpl->mCacheMap[local_id] = entry;
|
||||
return CACHE_UPDATE_CHANGED;
|
||||
result = CACHE_UPDATE_CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
// we haven't seen this object before
|
||||
|
||||
// Create new entry and add to map
|
||||
eCacheUpdateResult result = CACHE_UPDATE_ADDED;
|
||||
if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)
|
||||
else
|
||||
{
|
||||
delete mImpl->mCacheMap.begin()->second ;
|
||||
mImpl->mCacheMap.erase(mImpl->mCacheMap.begin());
|
||||
result = CACHE_UPDATE_REPLACED;
|
||||
|
||||
}
|
||||
entry = new LLVOCacheEntry(local_id, crc, dp);
|
||||
// we haven't seen this object before
|
||||
// Create new entry and add to map
|
||||
result = CACHE_UPDATE_ADDED;
|
||||
//if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)
|
||||
//{
|
||||
// delete mImpl->mCacheMap.begin()->second ;
|
||||
// mImpl->mCacheMap.erase(mImpl->mCacheMap.begin());
|
||||
// result = CACHE_UPDATE_REPLACED;
|
||||
//
|
||||
//}
|
||||
entry = new LLVOCacheEntry(local_id, crc, dp);
|
||||
|
||||
mImpl->mCacheMap[local_id] = entry;
|
||||
}
|
||||
|
||||
if(objectp->mDrawable.notNull() && !entry->getEntry())
|
||||
{
|
||||
entry->setOctreeEntry(objectp->mDrawable->getEntry());
|
||||
}
|
||||
if(entry->getEntry() && entry->getEntry()->hasDrawable() && entry->isState(LLVOCacheEntry::INACTIVE))
|
||||
{
|
||||
addActiveCacheEntry(entry);
|
||||
}
|
||||
|
||||
mImpl->mCacheMap[local_id] = entry;
|
||||
return result;
|
||||
}
|
||||
|
||||
LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id)
|
||||
{
|
||||
LLVOCacheEntry* entry = getCacheEntry(local_id);
|
||||
removeFromVOCacheTree(entry);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id)
|
||||
{
|
||||
LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id);
|
||||
if(iter != mImpl->mCacheMap.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get data packer for this object, if we have cached data
|
||||
// AND the CRC matches. JC
|
||||
LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)
|
||||
bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type)
|
||||
{
|
||||
//llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18
|
||||
|
||||
LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
|
||||
LLVOCacheEntry* entry = getCacheEntry(local_id);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
|
|
@ -1244,24 +1733,31 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)
|
|||
{
|
||||
// Record a hit
|
||||
entry->recordHit();
|
||||
cache_miss_type = CACHE_MISS_TYPE_NONE;
|
||||
return entry->getDP(crc);
|
||||
cache_miss_type = CACHE_MISS_TYPE_NONE;
|
||||
|
||||
if(entry->getGroup() || !entry->isState(LLVOCacheEntry::INACTIVE))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
addVisibleCacheEntry(entry);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// llinfos << "CRC miss for " << local_id << llendl;
|
||||
cache_miss_type = CACHE_MISS_TYPE_CRC;
|
||||
cache_miss_type = CACHE_MISS_TYPE_CRC;
|
||||
mCacheMissCRC.put(local_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// llinfos << "Cache miss for " << local_id << llendl;
|
||||
cache_miss_type = CACHE_MISS_TYPE_FULL;
|
||||
cache_miss_type = CACHE_MISS_TYPE_FULL;
|
||||
mCacheMissFull.put(local_id);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLViewerRegion::addCacheMissFull(const U32 local_id)
|
||||
|
|
@ -1784,9 +2280,18 @@ void LLViewerRegion::logActiveCapabilities() const
|
|||
|
||||
LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
|
||||
{
|
||||
if (type < mImpl->mObjectPartition.size())
|
||||
if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE)
|
||||
{
|
||||
return mImpl->mObjectPartition[type];
|
||||
return (LLSpatialPartition*)mImpl->mObjectPartition[type];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLVOCachePartition* LLViewerRegion::getVOCachePartition()
|
||||
{
|
||||
if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size())
|
||||
{
|
||||
return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,8 +65,11 @@ class LLDataPacker;
|
|||
class LLDataPackerBinaryBuffer;
|
||||
class LLHost;
|
||||
class LLBBox;
|
||||
|
||||
class LLSpatialGroup;
|
||||
class LLDrawable;
|
||||
class LLViewerRegionImpl;
|
||||
class LLviewerOctreeGroup;
|
||||
class LLVOCachePartition;
|
||||
|
||||
class LLViewerRegion: public LLCapabilityProvider // implements this interface
|
||||
{
|
||||
|
|
@ -83,7 +86,8 @@ public:
|
|||
PARTITION_GRASS,
|
||||
PARTITION_VOLUME,
|
||||
PARTITION_BRIDGE,
|
||||
PARTITION_HUD_PARTICLE,
|
||||
PARTITION_HUD_PARTICLE,
|
||||
PARTITION_VO_CACHE,
|
||||
PARTITION_NONE,
|
||||
NUM_PARTITIONS
|
||||
} eObjectPartitions;
|
||||
|
|
@ -215,6 +219,12 @@ public:
|
|||
F32 getWidth() const { return mWidth; }
|
||||
|
||||
BOOL idleUpdate(F32 max_update_time);
|
||||
void addVisibleGroup(LLviewerOctreeGroup* group);
|
||||
void addVisibleCacheEntry(LLVOCacheEntry* entry);
|
||||
void addActiveCacheEntry(LLVOCacheEntry* entry);
|
||||
void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep);
|
||||
void killCacheEntry(U32 local_id); //physically delete the cache entry
|
||||
void clearVisibleGroup(LLviewerOctreeGroup* group);
|
||||
|
||||
// Like idleUpdate, but forces everything to complete regardless of
|
||||
// how long it takes.
|
||||
|
|
@ -304,8 +314,9 @@ public:
|
|||
} eCacheUpdateResult;
|
||||
|
||||
// handle a full update message
|
||||
eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp);
|
||||
LLDataPacker *getDP(U32 local_id, U32 crc, U8 &cache_miss_type);
|
||||
eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp);
|
||||
LLVOCacheEntry* getCacheEntryForOctree(U32 local_id);
|
||||
bool probeCache(U32 local_id, U32 crc, U8 &cache_miss_type);
|
||||
void requestCacheMisses();
|
||||
void addCacheMissFull(const U32 local_id);
|
||||
|
||||
|
|
@ -321,7 +332,9 @@ public:
|
|||
virtual std::string getDescription() const;
|
||||
std::string getHttpUrl() const { return mHttpUrl ;}
|
||||
|
||||
U32 getNumOfActiveCachedObjects() const;
|
||||
LLSpatialPartition* getSpatialPartition(U32 type);
|
||||
LLVOCachePartition* getVOCachePartition();
|
||||
|
||||
bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;
|
||||
bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const;
|
||||
|
|
@ -330,6 +343,19 @@ public:
|
|||
void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
|
||||
void getNeighboringRegionsStatus( std::vector<S32>& regions );
|
||||
|
||||
private:
|
||||
void addToVOCacheTree(LLVOCacheEntry* entry);
|
||||
LLViewerObject* addNewObject(LLVOCacheEntry* entry);
|
||||
void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list);
|
||||
LLVOCacheEntry* getCacheEntry(U32 local_id);
|
||||
void removeFromVOCacheTree(LLVOCacheEntry* entry);
|
||||
void replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry);
|
||||
void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry
|
||||
|
||||
F32 killInvisibleObjects(F32 max_time);
|
||||
F32 createVisibleObjects(F32 max_time);
|
||||
F32 updateVisibleEntries(F32 max_time); //update visible entries
|
||||
|
||||
public:
|
||||
struct CompareDistance
|
||||
{
|
||||
|
|
@ -363,6 +389,8 @@ public:
|
|||
LLDynamicArray<U32> mMapAvatars;
|
||||
LLDynamicArray<LLUUID> mMapAvatarIDs;
|
||||
|
||||
static LLViewerRegion* sCurRegionp;
|
||||
static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not.
|
||||
private:
|
||||
LLViewerRegionImpl * mImpl;
|
||||
|
||||
|
|
@ -406,18 +434,17 @@ private:
|
|||
// Maps local ids to cache entries.
|
||||
// Regions can have order 10,000 objects, so assume
|
||||
// a structure of size 2^14 = 16,000
|
||||
BOOL mCacheLoaded;
|
||||
BOOL mCacheDirty;
|
||||
BOOL mCacheLoaded;
|
||||
BOOL mCacheDirty;
|
||||
BOOL mAlive; // can become false if circuit disconnects
|
||||
BOOL mCapabilitiesReceived;
|
||||
BOOL mReleaseNotesRequested;
|
||||
BOOL mDead; //if true, this region is in the process of deleting.
|
||||
|
||||
LLDynamicArray<U32> mCacheMissFull;
|
||||
LLDynamicArray<U32> mCacheMissCRC;
|
||||
|
||||
bool mAlive; // can become false if circuit disconnects
|
||||
bool mCapabilitiesReceived;
|
||||
caps_received_signal_t mCapabilitiesReceivedSignal;
|
||||
|
||||
BOOL mReleaseNotesRequested;
|
||||
|
||||
caps_received_signal_t mCapabilitiesReceivedSignal;
|
||||
LLSD mSimulatorFeatures;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ LLGLSLShader gGlowCombineProgram;
|
|||
LLGLSLShader gSplatTextureRectProgram;
|
||||
LLGLSLShader gGlowCombineFXAAProgram;
|
||||
LLGLSLShader gTwoTextureAddProgram;
|
||||
LLGLSLShader gTwoTextureCompareProgram;
|
||||
LLGLSLShader gOneTextureFilterProgram;
|
||||
LLGLSLShader gOneTextureNoColorProgram;
|
||||
LLGLSLShader gDebugProgram;
|
||||
LLGLSLShader gClipProgram;
|
||||
|
|
@ -672,6 +674,8 @@ void LLViewerShaderMgr::unloadShaders()
|
|||
gSplatTextureRectProgram.unload();
|
||||
gGlowCombineFXAAProgram.unload();
|
||||
gTwoTextureAddProgram.unload();
|
||||
gTwoTextureCompareProgram.unload();
|
||||
gOneTextureFilterProgram.unload();
|
||||
gOneTextureNoColorProgram.unload();
|
||||
gSolidColorProgram.unload();
|
||||
|
||||
|
|
@ -2706,6 +2710,37 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
|
|||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gTwoTextureCompareProgram.mName = "Two Texture Compare Shader";
|
||||
gTwoTextureCompareProgram.mShaderFiles.clear();
|
||||
gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gTwoTextureCompareProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
|
||||
success = gTwoTextureCompareProgram.createShader(NULL, NULL);
|
||||
if (success)
|
||||
{
|
||||
gTwoTextureCompareProgram.bind();
|
||||
gTwoTextureCompareProgram.uniform1i("tex0", 0);
|
||||
gTwoTextureCompareProgram.uniform1i("tex1", 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gOneTextureFilterProgram.mName = "One Texture Filter Shader";
|
||||
gOneTextureFilterProgram.mShaderFiles.clear();
|
||||
gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gOneTextureFilterProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
|
||||
success = gOneTextureFilterProgram.createShader(NULL, NULL);
|
||||
if (success)
|
||||
{
|
||||
gOneTextureFilterProgram.bind();
|
||||
gOneTextureFilterProgram.uniform1i("tex0", 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gOneTextureNoColorProgram.mName = "One Texture No Color Shader";
|
||||
|
|
|
|||
|
|
@ -233,7 +233,11 @@ extern LLGLSLShader gAlphaMaskProgram;
|
|||
|
||||
//output tex0[tc0] + tex1[tc1]
|
||||
extern LLGLSLShader gTwoTextureAddProgram;
|
||||
|
||||
//output tex0[tc0] - tex1[tc1]
|
||||
extern LLGLSLShader gTwoTextureCompareProgram;
|
||||
//discard some fragments based on user-set color tolerance
|
||||
extern LLGLSLShader gOneTextureFilterProgram;
|
||||
|
||||
extern LLGLSLShader gOneTextureNoColorProgram;
|
||||
|
||||
//object shaders
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )
|
|||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl;
|
||||
//llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -966,6 +966,12 @@ void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
|
|||
//nothing here.
|
||||
}
|
||||
|
||||
BOOL LLViewerTexture::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height)
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
return mGLTexturep->setSubImageFromFrameBuffer(fb_x, fb_y, x_pos, y_pos, width, height);
|
||||
}
|
||||
|
||||
void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ public:
|
|||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLViewerTexture::OTHER);
|
||||
virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
|
||||
|
||||
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
|
||||
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
|
||||
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
|
||||
void setAddressMode(LLTexUnit::eTextureAddressMode mode);
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@
|
|||
|
||||
#include "lldebugmessagebox.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llscenemonitor.h"
|
||||
|
||||
extern F32 SPEED_ADJUST_MAX;
|
||||
extern F32 SPEED_ADJUST_MAX_SEC;
|
||||
|
|
@ -771,6 +772,11 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
|
|||
mLastPelvisToFoot = 0.0f;
|
||||
mPelvisFixup = 0.0f;
|
||||
mLastPelvisFixup = 0.0f;
|
||||
|
||||
if(LLSceneMonitor::getInstance()->isEnabled())
|
||||
{
|
||||
LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLVOAvatar::avString() const
|
||||
|
|
|
|||
|
|
@ -808,8 +808,10 @@ U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
updateMeshTextures();
|
||||
|
||||
// unpack the texture UUIDs to the texture slots
|
||||
retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
|
||||
|
||||
if(mesgsys != NULL)
|
||||
{
|
||||
retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
|
||||
}
|
||||
// need to trigger a few operations to get the avatar to use the new bakes
|
||||
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@
|
|||
#include "llerror.h"
|
||||
#include "llregionhandle.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "lldrawable.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "pipeline.h"
|
||||
|
||||
BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
|
||||
{
|
||||
|
|
@ -46,12 +50,16 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp)
|
||||
:
|
||||
: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
|
||||
mLocalID(local_id),
|
||||
mCRC(crc),
|
||||
mHitCount(0),
|
||||
mDupeCount(0),
|
||||
mCRCChangeCount(0)
|
||||
mCRCChangeCount(0),
|
||||
mState(INACTIVE),
|
||||
mRepeatedVisCounter(0),
|
||||
mVisFrameRange(64),
|
||||
mSceneContrib(0.f)
|
||||
{
|
||||
mBuffer = new U8[dp.getBufferSize()];
|
||||
mDP.assignBuffer(mBuffer, dp.getBufferSize());
|
||||
|
|
@ -59,24 +67,35 @@ LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &
|
|||
}
|
||||
|
||||
LLVOCacheEntry::LLVOCacheEntry()
|
||||
:
|
||||
: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
|
||||
mLocalID(0),
|
||||
mCRC(0),
|
||||
mHitCount(0),
|
||||
mDupeCount(0),
|
||||
mCRCChangeCount(0),
|
||||
mBuffer(NULL)
|
||||
mBuffer(NULL),
|
||||
mState(INACTIVE),
|
||||
mRepeatedVisCounter(0),
|
||||
mVisFrameRange(64),
|
||||
mSceneContrib(0.f)
|
||||
{
|
||||
mDP.assignBuffer(mBuffer, 0);
|
||||
}
|
||||
|
||||
LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
|
||||
: mBuffer(NULL)
|
||||
: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
|
||||
mBuffer(NULL),
|
||||
mState(INACTIVE),
|
||||
mRepeatedVisCounter(0),
|
||||
mVisFrameRange(64),
|
||||
mSceneContrib(0.f)
|
||||
{
|
||||
S32 size = -1;
|
||||
BOOL success;
|
||||
|
||||
mDP.assignBuffer(mBuffer, 0);
|
||||
setOctreeEntry(NULL);
|
||||
|
||||
success = check_read(apr_file, &mLocalID, sizeof(U32));
|
||||
if(success)
|
||||
{
|
||||
|
|
@ -95,6 +114,36 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
|
|||
success = check_read(apr_file, &mCRCChangeCount, sizeof(S32));
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
success = check_read(apr_file, &mState, sizeof(U32));
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
F32 ext[8];
|
||||
success = check_read(apr_file, (void*)ext, sizeof(F32) * 8);
|
||||
|
||||
LLVector4a exts[2];
|
||||
exts[0].load4a(ext);
|
||||
exts[1].load4a(&ext[4]);
|
||||
|
||||
setSpatialExtents(exts[0], exts[1]);
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
LLVector4 pos;
|
||||
success = check_read(apr_file, (void*)pos.mV, sizeof(LLVector4));
|
||||
|
||||
LLVector4a pos_;
|
||||
pos_.load4a(pos.mV);
|
||||
setPositionGroup(pos_);
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
F32 rad;
|
||||
success = check_read(apr_file, &rad, sizeof(F32));
|
||||
setBinRadius(rad);
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
success = check_read(apr_file, &size, sizeof(S32));
|
||||
|
||||
|
|
@ -132,32 +181,100 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
|
|||
mDupeCount = 0;
|
||||
mCRCChangeCount = 0;
|
||||
mBuffer = NULL;
|
||||
mEntry = NULL;
|
||||
mState = 0;
|
||||
}
|
||||
}
|
||||
|
||||
LLVOCacheEntry::~LLVOCacheEntry()
|
||||
{
|
||||
mDP.freeBuffer();
|
||||
//llassert(mState == INACTIVE);
|
||||
}
|
||||
|
||||
|
||||
// New CRC means the object has changed.
|
||||
void LLVOCacheEntry::assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp)
|
||||
//virtual
|
||||
void LLVOCacheEntry::setOctreeEntry(LLViewerOctreeEntry* entry)
|
||||
{
|
||||
if ( (mCRC != crc)
|
||||
||(mDP.getBufferSize() == 0))
|
||||
if(!entry && mDP.getBufferSize() > 0)
|
||||
{
|
||||
mCRC = crc;
|
||||
mHitCount = 0;
|
||||
mCRCChangeCount++;
|
||||
LLUUID fullid;
|
||||
mDP.reset();
|
||||
mDP.unpackUUID(fullid, "ID");
|
||||
mDP.reset();
|
||||
|
||||
mDP.freeBuffer();
|
||||
mBuffer = new U8[dp.getBufferSize()];
|
||||
mDP.assignBuffer(mBuffer, dp.getBufferSize());
|
||||
mDP = dp;
|
||||
LLViewerObject* obj = gObjectList.findObject(fullid);
|
||||
if(obj && obj->mDrawable)
|
||||
{
|
||||
entry = obj->mDrawable->getEntry();
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerOctreeEntryData::setOctreeEntry(entry);
|
||||
}
|
||||
|
||||
void LLVOCacheEntry::copyTo(LLVOCacheEntry* new_entry)
|
||||
{
|
||||
//copy LLViewerOctreeEntry
|
||||
if(mEntry.notNull())
|
||||
{
|
||||
new_entry->setOctreeEntry(mEntry);
|
||||
mEntry = NULL;
|
||||
}
|
||||
|
||||
//copy children
|
||||
S32 num_children = getNumOfChildren();
|
||||
for(S32 i = 0; i < num_children; i++)
|
||||
{
|
||||
new_entry->addChild(getChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
void LLVOCacheEntry::setState(U32 state)
|
||||
{
|
||||
mState &= 0xffff0000; //clear the low 16 bits
|
||||
state &= 0x0000ffff; //clear the high 16 bits;
|
||||
mState |= state;
|
||||
|
||||
if(getState() == ACTIVE)
|
||||
{
|
||||
const S32 MIN_REAVTIVE_INTERVAL = 20;
|
||||
U32 last_visible = getVisible();
|
||||
|
||||
setVisible();
|
||||
|
||||
if(getVisible() - last_visible < MIN_REAVTIVE_INTERVAL + mVisFrameRange)
|
||||
{
|
||||
mRepeatedVisCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRepeatedVisCounter = 0;
|
||||
mVisFrameRange = 64;
|
||||
}
|
||||
|
||||
if(mRepeatedVisCounter > 2)
|
||||
{
|
||||
//if repeatedly becomes visible immediately after invisible, enlarge the visible frame range
|
||||
|
||||
mRepeatedVisCounter = 0;
|
||||
mVisFrameRange *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
S32 LLVOCacheEntry::getMinVisFrameRange()const
|
||||
{
|
||||
return mVisFrameRange;
|
||||
}
|
||||
|
||||
void LLVOCacheEntry::addChild(LLVOCacheEntry* entry)
|
||||
{
|
||||
llassert(entry != NULL);
|
||||
|
||||
mChildrenList.push_back(entry);
|
||||
}
|
||||
|
||||
LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc)
|
||||
{
|
||||
if ( (mCRC != crc)
|
||||
|
|
@ -170,6 +287,16 @@ LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc)
|
|||
return &mDP;
|
||||
}
|
||||
|
||||
LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP()
|
||||
{
|
||||
if (mDP.getBufferSize() == 0)
|
||||
{
|
||||
//llinfos << "Not getting cache entry, invalid!" << llendl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &mDP;
|
||||
}
|
||||
|
||||
void LLVOCacheEntry::recordHit()
|
||||
{
|
||||
|
|
@ -189,6 +316,11 @@ void LLVOCacheEntry::dump() const
|
|||
|
||||
BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
|
||||
{
|
||||
if(!mEntry)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL success;
|
||||
success = check_write(apr_file, (void*)&mLocalID, sizeof(U32));
|
||||
if(success)
|
||||
|
|
@ -208,6 +340,33 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
|
|||
success = check_write(apr_file, (void*)&mCRCChangeCount, sizeof(S32));
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
U32 state = mState & 0xffff0000; //only store the high 16 bits.
|
||||
success = check_write(apr_file, (void*)&state, sizeof(U32));
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
const LLVector4a* exts = getSpatialExtents() ;
|
||||
LLVector4 ext(exts[0][0], exts[0][1], exts[0][2], exts[0][3]);
|
||||
success = check_write(apr_file, ext.mV, sizeof(LLVector4));
|
||||
if(success)
|
||||
{
|
||||
ext.set(exts[1][0], exts[1][1], exts[1][2], exts[1][3]);
|
||||
success = check_write(apr_file, ext.mV, sizeof(LLVector4));
|
||||
}
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
const LLVector4a pos_ = getPositionGroup() ;
|
||||
LLVector4 pos(pos_[0], pos_[1], pos_[2], pos_[3]);
|
||||
success = check_write(apr_file, pos.mV, sizeof(LLVector4));
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
F32 rad = getBinRadius();
|
||||
success = check_write(apr_file, (void*)&rad, sizeof(F32));
|
||||
}
|
||||
if(success)
|
||||
{
|
||||
S32 size = mDP.getBufferSize();
|
||||
success = check_write(apr_file, (void*)&size, sizeof(S32));
|
||||
|
|
@ -221,6 +380,121 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
|
|||
return success ;
|
||||
}
|
||||
|
||||
void LLVOCacheEntry::calcSceneContribution(const LLVector3& camera_origin, bool needs_update, U32 last_update)
|
||||
{
|
||||
if(!needs_update && getVisible() >= last_update)
|
||||
{
|
||||
return; //no need to update
|
||||
}
|
||||
|
||||
const LLVector4a& center = getPositionGroup();
|
||||
|
||||
LLVector4a origin;
|
||||
origin.load3(camera_origin.mV);
|
||||
|
||||
LLVector4a lookAt;
|
||||
lookAt.setSub(center, origin);
|
||||
F32 squared_dist = lookAt.dot3(lookAt).getF32();
|
||||
|
||||
F32 rad = getBinRadius();
|
||||
mSceneContrib = rad * rad / squared_dist;
|
||||
|
||||
setVisible();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//LLVOCachePartition
|
||||
//-------------------------------------------------------------------
|
||||
LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp)
|
||||
{
|
||||
mRegionp = regionp;
|
||||
mPartitionType = LLViewerRegion::PARTITION_VO_CACHE;
|
||||
mVisitedTime = 0;
|
||||
|
||||
new LLviewerOctreeGroup(mOctree);
|
||||
}
|
||||
|
||||
void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry)
|
||||
{
|
||||
llassert(entry->hasVOCacheEntry());
|
||||
|
||||
mOctree->insert(entry);
|
||||
}
|
||||
|
||||
void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry)
|
||||
{
|
||||
entry->getVOCacheEntry()->setGroup(NULL);
|
||||
|
||||
llassert(!entry->getGroup());
|
||||
}
|
||||
|
||||
class LLVOCacheOctreeCull : public LLViewerOctreeCull
|
||||
{
|
||||
public:
|
||||
LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, const LLVector3& shift) : LLViewerOctreeCull(camera), mRegionp(regionp)
|
||||
{
|
||||
mLocalShift = shift;
|
||||
}
|
||||
|
||||
virtual S32 frustumCheck(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
//S32 res = AABBInRegionFrustumGroupBounds(group);
|
||||
|
||||
S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group);
|
||||
if (res != 0)
|
||||
{
|
||||
res = llmin(res, AABBRegionSphereIntersectGroupExtents(group, mLocalShift));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group)
|
||||
{
|
||||
//S32 res = AABBInRegionFrustumObjectBounds(group);
|
||||
|
||||
S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group);
|
||||
if (res != 0)
|
||||
{
|
||||
res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
virtual void processGroup(LLviewerOctreeGroup* base_group)
|
||||
{
|
||||
mRegionp->addVisibleGroup(base_group);
|
||||
}
|
||||
|
||||
private:
|
||||
LLViewerRegion* mRegionp;
|
||||
LLVector3 mLocalShift; //shift vector from agent space to local region space.
|
||||
};
|
||||
|
||||
S32 LLVOCachePartition::cull(LLCamera &camera)
|
||||
{
|
||||
if(!LLViewerRegion::sVOCacheCullingEnabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame())
|
||||
{
|
||||
return 0; //already visited.
|
||||
}
|
||||
mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame();
|
||||
|
||||
((LLviewerOctreeGroup*)mOctree->getListener(0))->rebound();
|
||||
|
||||
//localize the camera
|
||||
LLVector3 region_agent = mRegionp->getOriginAgent();
|
||||
camera.calcRegionFrustumPlanes(region_agent);
|
||||
|
||||
LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent);
|
||||
culler.traverse(mOctree);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//LLVOCache
|
||||
//-------------------------------------------------------------------
|
||||
|
|
@ -625,11 +899,10 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
|
|||
{
|
||||
for (S32 i = 0; i < num_entries; i++)
|
||||
{
|
||||
LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file);
|
||||
LLPointer<LLVOCacheEntry> entry = new LLVOCacheEntry(&apr_file);
|
||||
if (!entry->getLocalID())
|
||||
{
|
||||
llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
|
||||
delete entry ;
|
||||
success = false ;
|
||||
break ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,34 +31,95 @@
|
|||
#include "lldatapacker.h"
|
||||
#include "lldlinked.h"
|
||||
#include "lldir.h"
|
||||
|
||||
#include "llvieweroctree.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Cache entries
|
||||
class LLVOCacheEntry;
|
||||
class LLCamera;
|
||||
|
||||
class LLVOCacheEntry
|
||||
class LLVOCacheEntry : public LLViewerOctreeEntryData
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
INACTIVE = 0x00000000, //not visible
|
||||
IN_QUEUE = 0x00000001, //in visible queue, object to be created
|
||||
WAITING = 0x00000002, //object creation request sent
|
||||
ACTIVE = 0x00000004 //object created, and in rendering pipeline.
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ADD_TO_CACHE_TREE = 0x00010000, //has parent
|
||||
};
|
||||
|
||||
struct CompareVOCacheEntry
|
||||
{
|
||||
bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs)
|
||||
{
|
||||
F32 lpa = lhs->getSceneContribution();
|
||||
F32 rpa = rhs->getSceneContribution();
|
||||
|
||||
//larger pixel area first
|
||||
if(lpa > rpa)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if(lpa < rpa)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
}
|
||||
};
|
||||
protected:
|
||||
~LLVOCacheEntry();
|
||||
public:
|
||||
LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp);
|
||||
LLVOCacheEntry(LLAPRFile* apr_file);
|
||||
LLVOCacheEntry();
|
||||
~LLVOCacheEntry();
|
||||
LLVOCacheEntry();
|
||||
|
||||
void setState(U32 state);
|
||||
void clearState(U32 state) {mState &= ~state;}
|
||||
void addState(U32 state) {mState |= state;}
|
||||
bool isState(U32 state) {return (mState & 0xffff) == state;}
|
||||
bool hasState(U32 state) {return mState & state;}
|
||||
U32 getState() const {return (mState & 0xffff);}
|
||||
U32 getFullState() const {return mState;}
|
||||
|
||||
U32 getLocalID() const { return mLocalID; }
|
||||
U32 getCRC() const { return mCRC; }
|
||||
S32 getHitCount() const { return mHitCount; }
|
||||
S32 getCRCChangeCount() const { return mCRCChangeCount; }
|
||||
S32 getMinVisFrameRange()const;
|
||||
|
||||
void calcSceneContribution(const LLVector3& camera_origin, bool needs_update, U32 last_update);
|
||||
void setSceneContribution(F32 scene_contrib) {mSceneContrib = scene_contrib;}
|
||||
F32 getSceneContribution() const { return mSceneContrib;}
|
||||
|
||||
void dump() const;
|
||||
BOOL writeToFile(LLAPRFile* apr_file) const;
|
||||
void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp);
|
||||
LLDataPackerBinaryBuffer *getDP(U32 crc);
|
||||
LLDataPackerBinaryBuffer *getDP();
|
||||
void recordHit();
|
||||
void recordDupe() { mDupeCount++; }
|
||||
|
||||
void copyTo(LLVOCacheEntry* new_entry); //copy variables
|
||||
/*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry);
|
||||
|
||||
void addChild(LLVOCacheEntry* entry);
|
||||
LLVOCacheEntry* getChild(S32 i) {return mChildrenList[i];}
|
||||
S32 getNumOfChildren() {return mChildrenList.size();}
|
||||
void clearChildrenList() {mChildrenList.clear();}
|
||||
|
||||
public:
|
||||
typedef std::map<U32, LLVOCacheEntry*> vocache_entry_map_t;
|
||||
typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t;
|
||||
typedef std::set<LLVOCacheEntry*> vocache_entry_set_t;
|
||||
typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> vocache_entry_priority_list_t;
|
||||
|
||||
protected:
|
||||
U32 mLocalID;
|
||||
|
|
@ -68,6 +129,25 @@ protected:
|
|||
S32 mCRCChangeCount;
|
||||
LLDataPackerBinaryBuffer mDP;
|
||||
U8 *mBuffer;
|
||||
|
||||
F32 mSceneContrib; //projected scene contributuion of this object.
|
||||
S32 mVisFrameRange;
|
||||
S32 mRepeatedVisCounter; //number of repeatedly visible within a short time.
|
||||
U32 mState; //high 16 bits reserved for special use.
|
||||
std::vector<LLVOCacheEntry*> mChildrenList; //children entries in a linked set.
|
||||
};
|
||||
|
||||
class LLVOCachePartition : public LLViewerOctreePartition
|
||||
{
|
||||
public:
|
||||
LLVOCachePartition(LLViewerRegion* regionp);
|
||||
|
||||
void addEntry(LLViewerOctreeEntry* entry);
|
||||
void removeEntry(LLViewerOctreeEntry* entry);
|
||||
/*virtual*/ S32 cull(LLCamera &camera);
|
||||
|
||||
private:
|
||||
U32 mVisitedTime;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -603,8 +603,8 @@ U32 LLVOGrass::getPartitionType() const
|
|||
return LLViewerRegion::PARTITION_GRASS;
|
||||
}
|
||||
|
||||
LLGrassPartition::LLGrassPartition()
|
||||
: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)
|
||||
LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp)
|
||||
: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
|
||||
{
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
|
||||
mPartitionType = LLViewerRegion::PARTITION_GRASS;
|
||||
|
|
@ -624,9 +624,9 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count
|
|||
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
|
||||
{
|
||||
LLDrawable* drawablep = *i;
|
||||
LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
|
||||
|
||||
if (drawablep->isDead())
|
||||
if (!drawablep || drawablep->isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -738,8 +738,10 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
|
|||
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
|
||||
//facep->getTexture(),
|
||||
buffer, fullbright);
|
||||
info->mExtents[0] = group->mObjectExtents[0];
|
||||
info->mExtents[1] = group->mObjectExtents[1];
|
||||
|
||||
const LLVector4a* exts = group->getObjectExtents();
|
||||
info->mExtents[0] = exts[0];
|
||||
info->mExtents[1] = exts[1];
|
||||
info->mVSize = vsize;
|
||||
draw_vec.push_back(info);
|
||||
//for alpha sorting
|
||||
|
|
|
|||
|
|
@ -489,8 +489,8 @@ U32 LLVOPartGroup::getPartitionType() const
|
|||
return LLViewerRegion::PARTITION_PARTICLE;
|
||||
}
|
||||
|
||||
LLParticlePartition::LLParticlePartition()
|
||||
: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)
|
||||
LLParticlePartition::LLParticlePartition(LLViewerRegion* regionp)
|
||||
: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
|
||||
{
|
||||
mRenderPass = LLRenderPass::PASS_ALPHA;
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES;
|
||||
|
|
@ -499,8 +499,8 @@ LLParticlePartition::LLParticlePartition()
|
|||
mLODPeriod = 1;
|
||||
}
|
||||
|
||||
LLHUDParticlePartition::LLHUDParticlePartition() :
|
||||
LLParticlePartition()
|
||||
LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) :
|
||||
LLParticlePartition(regionp)
|
||||
{
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_HUD_PARTICLES;
|
||||
mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;
|
||||
|
|
@ -510,7 +510,7 @@ static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO");
|
|||
|
||||
void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
|
||||
{
|
||||
if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY))
|
||||
if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -558,9 +558,9 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
|
|||
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
|
||||
{
|
||||
LLDrawable* drawablep = *i;
|
||||
LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
|
||||
|
||||
if (drawablep->isDead())
|
||||
if (!drawablep || drawablep->isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -699,8 +699,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
|
|||
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
|
||||
//facep->getTexture(),
|
||||
buffer, fullbright);
|
||||
info->mExtents[0] = group->mObjectExtents[0];
|
||||
info->mExtents[1] = group->mObjectExtents[1];
|
||||
|
||||
const LLVector4a* exts = group->getObjectExtents();
|
||||
info->mExtents[0] = exts[0];
|
||||
info->mExtents[1] = exts[1];
|
||||
info->mVSize = vsize;
|
||||
draw_vec.push_back(info);
|
||||
//for alpha sorting
|
||||
|
|
|
|||
|
|
@ -1058,8 +1058,8 @@ U32 LLVOSurfacePatch::getPartitionType() const
|
|||
return LLViewerRegion::PARTITION_TERRAIN;
|
||||
}
|
||||
|
||||
LLTerrainPartition::LLTerrainPartition()
|
||||
: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB)
|
||||
LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp)
|
||||
: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
|
||||
{
|
||||
mOcclusionEnabled = FALSE;
|
||||
mInfiniteFarClip = TRUE;
|
||||
|
|
|
|||
|
|
@ -1290,8 +1290,8 @@ U32 LLVOTree::getPartitionType() const
|
|||
return LLViewerRegion::PARTITION_TREE;
|
||||
}
|
||||
|
||||
LLTreePartition::LLTreePartition()
|
||||
: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB)
|
||||
LLTreePartition::LLTreePartition(LLViewerRegion* regionp)
|
||||
: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
|
||||
{
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_TREE;
|
||||
mPartitionType = LLViewerRegion::PARTITION_TREE;
|
||||
|
|
|
|||
|
|
@ -3933,8 +3933,8 @@ U32 LLVOVolume::getPartitionType() const
|
|||
return LLViewerRegion::PARTITION_VOLUME;
|
||||
}
|
||||
|
||||
LLVolumePartition::LLVolumePartition()
|
||||
: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB)
|
||||
LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp)
|
||||
: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp)
|
||||
{
|
||||
mLODPeriod = 32;
|
||||
mDepthMask = FALSE;
|
||||
|
|
@ -3944,8 +3944,8 @@ LLVolumePartition::LLVolumePartition()
|
|||
mBufferUsage = GL_DYNAMIC_DRAW_ARB;
|
||||
}
|
||||
|
||||
LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep)
|
||||
: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK)
|
||||
LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
|
||||
: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp)
|
||||
{
|
||||
mDepthMask = FALSE;
|
||||
mLODPeriod = 32;
|
||||
|
|
@ -4167,9 +4167,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
|
||||
group->mLastUpdateViewAngle = group->mViewAngle;
|
||||
|
||||
if (!group->isState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
|
||||
if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
|
||||
{
|
||||
if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
|
||||
if (group->hasState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
|
||||
{
|
||||
rebuildMesh(group);
|
||||
}
|
||||
|
|
@ -4207,7 +4207,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
group->mSurfaceArea = 0;
|
||||
|
||||
//cache object box size since it might be used for determining visibility
|
||||
group->mObjectBoxSize = group->mObjectBounds[1].getLength3().getF32();
|
||||
const LLVector4a* bounds = group->getObjectBounds();
|
||||
group->mObjectBoxSize = bounds[1].getLength3().getF32();
|
||||
|
||||
group->clearDrawMap();
|
||||
|
||||
|
|
@ -4234,9 +4235,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
//get all the faces into a list
|
||||
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
|
||||
{
|
||||
LLDrawable* drawablep = *drawable_iter;
|
||||
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
|
||||
|
||||
if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
|
||||
if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -4640,8 +4641,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
//drawables have been rebuilt, clear rebuild status
|
||||
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
|
||||
{
|
||||
LLDrawable* drawablep = *drawable_iter;
|
||||
drawablep->clearState(LLDrawable::REBUILD_ALL);
|
||||
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
|
||||
if(drawablep)
|
||||
{
|
||||
drawablep->clearState(LLDrawable::REBUILD_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4667,7 +4671,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
{
|
||||
llassert(group);
|
||||
if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
|
||||
if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY))
|
||||
{
|
||||
LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
|
||||
LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers
|
||||
|
|
@ -4680,9 +4684,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
|||
|
||||
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
|
||||
{
|
||||
LLDrawable* drawablep = *drawable_iter;
|
||||
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
|
||||
|
||||
if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
|
||||
if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
|
||||
{
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
vobj->preRebuild();
|
||||
|
|
@ -4748,7 +4752,11 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
|||
llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
|
||||
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
|
||||
{
|
||||
LLDrawable* drawablep = *drawable_iter;
|
||||
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
|
||||
if(!drawablep)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
|
||||
{
|
||||
LLFace* face = drawablep->getFace(i);
|
||||
|
|
@ -5221,9 +5229,9 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
|
|||
|
||||
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
|
||||
{
|
||||
LLDrawable* drawablep = *drawable_iter;
|
||||
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
|
||||
|
||||
if (drawablep->isDead())
|
||||
if (!drawablep || drawablep->isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -5261,7 +5269,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
|
|||
group->mBufferUsage = usage;
|
||||
}
|
||||
|
||||
LLHUDPartition::LLHUDPartition()
|
||||
LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp)
|
||||
{
|
||||
mPartitionType = LLViewerRegion::PARTITION_HUD;
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_HUD;
|
||||
|
|
|
|||
|
|
@ -298,15 +298,15 @@ U32 LLVOVoidWater::getPartitionType() const
|
|||
return LLViewerRegion::PARTITION_VOIDWATER;
|
||||
}
|
||||
|
||||
LLWaterPartition::LLWaterPartition()
|
||||
: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB)
|
||||
LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp)
|
||||
: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
|
||||
{
|
||||
mInfiniteFarClip = TRUE;
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_WATER;
|
||||
mPartitionType = LLViewerRegion::PARTITION_WATER;
|
||||
}
|
||||
|
||||
LLVoidWaterPartition::LLVoidWaterPartition()
|
||||
LLVoidWaterPartition::LLVoidWaterPartition(LLViewerRegion* regionp) : LLWaterPartition(regionp)
|
||||
{
|
||||
mOcclusionEnabled = FALSE;
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
#include "message.h"
|
||||
#include "pipeline.h"
|
||||
#include "llappviewer.h" // for do_disconnect()
|
||||
|
||||
#include "llscenemonitor.h"
|
||||
#include <deque>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
|
|
@ -110,6 +110,7 @@ LLWorld::LLWorld() :
|
|||
gGL.getTexUnit(0)->bind(mDefaultWaterTexturep);
|
||||
mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
LLViewerRegion::sVOCacheCullingEnabled = (BOOL)gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -133,6 +134,11 @@ void LLWorld::destroyClass()
|
|||
{
|
||||
mEdgeWaterObjects[i] = NULL;
|
||||
}
|
||||
|
||||
//make all visible drawbles invisible.
|
||||
LLDrawable::incrementVisible();
|
||||
|
||||
LLSceneMonitor::getInstance()->destroyClass();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -599,7 +605,8 @@ void LLWorld::updateVisibilities()
|
|||
if (part)
|
||||
{
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
|
||||
if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
|
||||
const LLVector4a* bounds = group->getBounds();
|
||||
if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1]))
|
||||
{
|
||||
mCulledRegionList.erase(curiter);
|
||||
mVisibleRegionList.push_back(regionp);
|
||||
|
|
@ -622,7 +629,8 @@ void LLWorld::updateVisibilities()
|
|||
if (part)
|
||||
{
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
|
||||
if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
|
||||
const LLVector4a* bounds = group->getBounds();
|
||||
if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1]))
|
||||
{
|
||||
regionp->calculateCameraDistance();
|
||||
regionp->getLand().updatePatchVisibilities(gAgent);
|
||||
|
|
@ -644,8 +652,8 @@ void LLWorld::updateVisibilities()
|
|||
void LLWorld::updateRegions(F32 max_update_time)
|
||||
{
|
||||
LLTimer update_timer;
|
||||
BOOL did_one = FALSE;
|
||||
|
||||
BOOL did_one = FALSE;
|
||||
|
||||
// Perform idle time updates for the regions (and associated surfaces)
|
||||
for (region_list_t::iterator iter = mRegionList.begin();
|
||||
iter != mRegionList.end(); ++iter)
|
||||
|
|
@ -660,6 +668,13 @@ void LLWorld::updateRegions(F32 max_update_time)
|
|||
did_one = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
mNumOfActiveCachedObjects = 0;
|
||||
for (region_list_t::iterator iter = mRegionList.begin();
|
||||
iter != mRegionList.end(); ++iter)
|
||||
{
|
||||
mNumOfActiveCachedObjects += (*iter)->getNumOfActiveCachedObjects();
|
||||
}
|
||||
}
|
||||
|
||||
void LLWorld::updateParticles()
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ public:
|
|||
U64 getSpaceTimeUSec() const;
|
||||
|
||||
void getInfo(LLSD& info);
|
||||
U32 getNumOfActiveCachedObjects() const {return mNumOfActiveCachedObjects;}
|
||||
|
||||
public:
|
||||
typedef std::list<LLViewerRegion*> region_list_t;
|
||||
|
|
@ -181,7 +182,7 @@ private:
|
|||
S32 mLastPacketsIn;
|
||||
S32 mLastPacketsOut;
|
||||
S32 mLastPacketsLost;
|
||||
|
||||
U32 mNumOfActiveCachedObjects;
|
||||
U64 mSpaceTimeUSec;
|
||||
|
||||
BOOL mClassicCloudsEnabled;
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
#include "llviewerregion.h" // for audio debugging.
|
||||
#include "llviewerwindow.h" // For getSpinAxis
|
||||
#include "llvoavatarself.h"
|
||||
#include "llvocache.h"
|
||||
#include "llvoground.h"
|
||||
#include "llvosky.h"
|
||||
#include "llvotree.h"
|
||||
|
|
@ -111,6 +112,7 @@
|
|||
#include "llfloaterpathfindingconsole.h"
|
||||
#include "llfloaterpathfindingcharacters.h"
|
||||
#include "llpathfindingpathtool.h"
|
||||
#include "llscenemonitor.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Debug indices is disabled for now for debug performance - djs 4/24/02
|
||||
|
|
@ -1410,18 +1412,18 @@ S32 LLPipeline::setLightingDetail(S32 level)
|
|||
return mLightingDetail;
|
||||
}
|
||||
|
||||
class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable>
|
||||
class LLOctreeDirtyTexture : public OctreeTraveler
|
||||
{
|
||||
public:
|
||||
const std::set<LLViewerFetchedTexture*>& mTextures;
|
||||
|
||||
LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { }
|
||||
|
||||
virtual void visit(const LLOctreeNode<LLDrawable>* node)
|
||||
virtual void visit(const OctreeNode* node)
|
||||
{
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
|
||||
|
||||
if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
|
||||
if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
|
||||
{
|
||||
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
|
||||
{
|
||||
|
|
@ -1610,11 +1612,9 @@ void LLPipeline::addPool(LLDrawPool *new_poolp)
|
|||
|
||||
void LLPipeline::allocDrawable(LLViewerObject *vobj)
|
||||
{
|
||||
LLDrawable *drawable = new LLDrawable();
|
||||
LLDrawable *drawable = new LLDrawable(vobj);
|
||||
vobj->mDrawable = drawable;
|
||||
|
||||
drawable->mVObjp = vobj;
|
||||
|
||||
//encompass completely sheared objects by taking
|
||||
//the most extreme point possible (<1,1,0.5>)
|
||||
drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length());
|
||||
|
|
@ -2038,7 +2038,7 @@ void check_references(LLSpatialGroup* group, LLDrawable* drawable)
|
|||
{
|
||||
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
|
||||
{
|
||||
if (drawable == *i)
|
||||
if (drawable == (LLDrawable*)(*i)->getDrawable())
|
||||
{
|
||||
llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl;
|
||||
}
|
||||
|
|
@ -2060,8 +2060,11 @@ void check_references(LLSpatialGroup* group, LLFace* face)
|
|||
{
|
||||
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
|
||||
{
|
||||
LLDrawable* drawable = *i;
|
||||
check_references(drawable, face);
|
||||
LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
|
||||
if(drawable)
|
||||
{
|
||||
check_references(drawable, face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2385,6 +2388,13 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//scan the VO Cache tree
|
||||
LLVOCachePartition* vo_part = region->getVOCachePartition();
|
||||
if(vo_part)
|
||||
{
|
||||
vo_part->cull(camera);
|
||||
}
|
||||
}
|
||||
|
||||
if (bound_shader)
|
||||
|
|
@ -2452,14 +2462,15 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
|
|||
return;
|
||||
}
|
||||
|
||||
const LLVector4a* bounds = group->getBounds();
|
||||
if (sMinRenderSize > 0.f &&
|
||||
llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize)
|
||||
llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
assertInitialized();
|
||||
|
||||
|
||||
if (!group->mSpatialPartition->mRenderByGroup)
|
||||
{ //render by drawable
|
||||
sCull->pushDrawableGroup(group);
|
||||
|
|
@ -3041,14 +3052,14 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
|
|||
|
||||
if (priority)
|
||||
{
|
||||
if (!group->isState(LLSpatialGroup::IN_BUILD_Q1))
|
||||
if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1))
|
||||
{
|
||||
llassert_always(!mGroupQ1Locked);
|
||||
|
||||
mGroupQ1.push_back(group);
|
||||
group->setState(LLSpatialGroup::IN_BUILD_Q1);
|
||||
|
||||
if (group->isState(LLSpatialGroup::IN_BUILD_Q2))
|
||||
if (group->hasState(LLSpatialGroup::IN_BUILD_Q2))
|
||||
{
|
||||
LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group);
|
||||
if (iter != mGroupQ2.end())
|
||||
|
|
@ -3059,7 +3070,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1))
|
||||
else if (!group->hasState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1))
|
||||
{
|
||||
llassert_always(!mGroupQ2Locked);
|
||||
mGroupQ2.push_back(group);
|
||||
|
|
@ -3134,7 +3145,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
|
|||
group->setVisible();
|
||||
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
|
||||
{
|
||||
markVisible(*i, camera);
|
||||
markVisible((LLDrawable*)(*i)->getDrawable(), camera);
|
||||
}
|
||||
|
||||
if (!sDelayVBUpdate)
|
||||
|
|
@ -3212,7 +3223,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
|
|||
}
|
||||
}
|
||||
|
||||
postSort(camera);
|
||||
postSort(camera);
|
||||
|
||||
LLSceneMonitor::getInstance()->fetchQueryResult();
|
||||
}
|
||||
|
||||
void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
|
||||
|
|
@ -3221,8 +3234,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
|
|||
{
|
||||
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
|
||||
{
|
||||
LLDrawable* drawablep = *i;
|
||||
stateSort(drawablep, camera);
|
||||
stateSort((LLDrawable*)(*i)->getDrawable(), camera);
|
||||
}
|
||||
|
||||
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
|
||||
|
|
@ -3341,7 +3353,10 @@ void forAllDrawables(LLCullResult::sg_iterator begin,
|
|||
{
|
||||
for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j)
|
||||
{
|
||||
func(*j);
|
||||
if((*j)->hasDrawable())
|
||||
{
|
||||
func((LLDrawable*)(*j)->getDrawable());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3569,7 +3584,7 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY))
|
||||
if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY))
|
||||
{ //no way this group is going to be drawable without a rebuild
|
||||
group->rebuildGeom();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1989,6 +1989,16 @@
|
|||
function="Advanced.ToggleConsole"
|
||||
parameter="scene view" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Scene Loading Monitor"
|
||||
name="Scene Loading Monitor">
|
||||
<menu_item_check.on_check
|
||||
function="Advanced.CheckConsole"
|
||||
parameter="scene monitor" />
|
||||
<menu_item_check.on_click
|
||||
function="Advanced.ToggleConsole"
|
||||
parameter="scene monitor" />
|
||||
</menu_item_check>
|
||||
<menu_item_call
|
||||
enabled="false"
|
||||
visible="false"
|
||||
|
|
|
|||
Loading…
Reference in New Issue