A majority of vectorization done. Note that it's INCOMPLETE. LLVolumeFace and LLVertexBuffer haven't been updated, so it's very dirty(and buggy) at those transitions. Compiles on windoze.
This commit is contained in:
@@ -38,6 +38,8 @@
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include "llpreprocessor.h"
|
||||
|
||||
#include "stdtypes.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,13 +17,16 @@ set(llmath_SOURCE_FILES
|
||||
llcamera.cpp
|
||||
llcoordframe.cpp
|
||||
llline.cpp
|
||||
llmatrix3a.cpp
|
||||
llmodularmath.cpp
|
||||
llperlin.cpp
|
||||
llquaternion.cpp
|
||||
llrect.cpp
|
||||
llsphere.cpp
|
||||
llvector4a.cpp
|
||||
llvolume.cpp
|
||||
llvolumemgr.cpp
|
||||
llvolumeoctree.cpp
|
||||
llsdutil_math.cpp
|
||||
m3math.cpp
|
||||
m4math.cpp
|
||||
@@ -53,21 +56,32 @@ set(llmath_HEADER_FILES
|
||||
llinterp.h
|
||||
llline.h
|
||||
llmath.h
|
||||
llmatrix3a.h
|
||||
llmatrix3a.inl
|
||||
llmodularmath.h
|
||||
lloctree.h
|
||||
llperlin.h
|
||||
llplane.h
|
||||
llquantize.h
|
||||
llquaternion.h
|
||||
llquaternion2.h
|
||||
llquaternion2.inl
|
||||
llrect.h
|
||||
llsimdmath.h
|
||||
llsimdtypes.h
|
||||
llsimdtypes.inl
|
||||
llsphere.h
|
||||
lltreenode.h
|
||||
llvector4a.h
|
||||
llvector4a.inl
|
||||
llvector4logical.h
|
||||
llv4math.h
|
||||
llv4matrix3.h
|
||||
llv4matrix4.h
|
||||
llv4vector3.h
|
||||
llvolume.h
|
||||
llvolumemgr.h
|
||||
llvolumeoctree.h
|
||||
llsdutil_math.h
|
||||
m3math.h
|
||||
m4math.h
|
||||
|
||||
@@ -92,7 +92,7 @@ F32 LLCamera::getMaxView() const
|
||||
|
||||
// ---------------- LLCamera::setFoo() member functions ----------------
|
||||
|
||||
void LLCamera::setUserClipPlane(LLPlane const& plane)
|
||||
void LLCamera::setUserClipPlane(LLPlane& plane)
|
||||
{
|
||||
mPlaneCount = 7;
|
||||
mAgentPlanes[6] = plane;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "llmath.h"
|
||||
#include "llcoordframe.h"
|
||||
#include "llplane.h"
|
||||
#include "llvector4a.h"
|
||||
|
||||
const F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD;
|
||||
const F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f;
|
||||
@@ -143,7 +144,7 @@ public:
|
||||
virtual ~LLCamera();
|
||||
|
||||
|
||||
void setUserClipPlane(LLPlane const& plane);
|
||||
void setUserClipPlane(LLPlane& plane);
|
||||
void disableUserClipPlane();
|
||||
virtual void setView(F32 vertical_fov_rads);
|
||||
void setViewHeightInPixels(S32 height);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
// So, let's define _USE_MATH_DEFINES before including math.h
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include "math.h"
|
||||
|
||||
// Class from which different types of interpolators can be derived
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
#include "lldefs.h"
|
||||
#include "llstl.h" // *TODO: Remove when LLString is gone
|
||||
#include "llstring.h" // *TODO: Remove when LLString is gone
|
||||
@@ -541,4 +541,7 @@ inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k)
|
||||
data.erase(data.begin(), data.begin()+i);
|
||||
}
|
||||
}
|
||||
|
||||
// Include simd math header
|
||||
#include "llsimdmath.h"
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "lltreenode.h"
|
||||
#include "v3math.h"
|
||||
#include "llvector4a.h"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
@@ -85,6 +86,7 @@ template <class T>
|
||||
class LLOctreeNode : public LLTreeNode<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef LLOctreeTraveler<T> oct_traveler;
|
||||
typedef LLTreeTraveler<T> tree_traveler;
|
||||
typedef typename std::set<LLPointer<T> > element_list;
|
||||
@@ -174,7 +176,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,4 +31,5 @@
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
// implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes.
|
||||
#include "llrect.h"
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "xform.h"
|
||||
#include "llmemory.h"
|
||||
#include <vector>
|
||||
|
||||
template <class T> class LLTreeNode;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llmemory.h"
|
||||
#include "llmath.h"
|
||||
|
||||
#include <set>
|
||||
@@ -43,9 +44,15 @@
|
||||
#include "v4math.h"
|
||||
#include "m4math.h"
|
||||
#include "m3math.h"
|
||||
#include "llmatrix3a.h"
|
||||
#include "lloctree.h"
|
||||
#include "lldarray.h"
|
||||
#include "llvolume.h"
|
||||
#include "llstl.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
#define DEBUG_SILHOUETTE_BINORMALS 0
|
||||
#define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette
|
||||
@@ -135,102 +142,231 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent
|
||||
// and returns the intersection point along dir in intersection_t.
|
||||
|
||||
// Moller-Trumbore algorithm
|
||||
BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
|
||||
F32* intersection_a, F32* intersection_b, F32* intersection_t, BOOL two_sided)
|
||||
BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
|
||||
F32& intersection_a, F32& intersection_b, F32& intersection_t)
|
||||
{
|
||||
|
||||
/* find vectors for two edges sharing vert0 */
|
||||
LLVector4a edge1;
|
||||
edge1.setSub(vert1, vert0);
|
||||
|
||||
LLVector4a edge2;
|
||||
edge2.setSub(vert2, vert0);
|
||||
|
||||
/* begin calculating determinant - also used to calculate U parameter */
|
||||
LLVector4a pvec;
|
||||
pvec.setCross3(dir, edge2);
|
||||
|
||||
/* if determinant is near zero, ray lies in plane of triangle */
|
||||
LLVector4a det;
|
||||
det.setAllDot3(edge1, pvec);
|
||||
|
||||
if (det.greaterEqual(LLVector4a::getEpsilon()).getGatheredBits() & 0x7)
|
||||
{
|
||||
/* calculate distance from vert0 to ray origin */
|
||||
LLVector4a tvec;
|
||||
tvec.setSub(orig, vert0);
|
||||
|
||||
/* calculate U parameter and test bounds */
|
||||
LLVector4a u;
|
||||
u.setAllDot3(tvec,pvec);
|
||||
|
||||
if ((u.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7) &&
|
||||
(u.lessEqual(det).getGatheredBits() & 0x7))
|
||||
{
|
||||
/* prepare to test V parameter */
|
||||
LLVector4a qvec;
|
||||
qvec.setCross3(tvec, edge1);
|
||||
|
||||
/* calculate V parameter and test bounds */
|
||||
LLVector4a v;
|
||||
v.setAllDot3(dir, qvec);
|
||||
|
||||
|
||||
//if (!(v < 0.f || u + v > det))
|
||||
|
||||
LLVector4a sum_uv;
|
||||
sum_uv.setAdd(u, v);
|
||||
|
||||
S32 v_gequal = v.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7;
|
||||
S32 sum_lequal = sum_uv.lessEqual(det).getGatheredBits() & 0x7;
|
||||
|
||||
if (v_gequal && sum_lequal)
|
||||
{
|
||||
/* calculate t, scale parameters, ray intersects triangle */
|
||||
LLVector4a t;
|
||||
t.setAllDot3(edge2,qvec);
|
||||
|
||||
t.div(det);
|
||||
u.div(det);
|
||||
v.div(det);
|
||||
|
||||
intersection_a = u[0];
|
||||
intersection_b = v[0];
|
||||
intersection_t = t[0];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
|
||||
F32& intersection_a, F32& intersection_b, F32& intersection_t)
|
||||
{
|
||||
F32 u, v, t;
|
||||
|
||||
/* find vectors for two edges sharing vert0 */
|
||||
LLVector3 edge1 = vert1 - vert0;
|
||||
LLVector4a edge1;
|
||||
edge1.setSub(vert1, vert0);
|
||||
|
||||
LLVector3 edge2 = vert2 - vert0;;
|
||||
|
||||
LLVector4a edge2;
|
||||
edge2.setSub(vert2, vert0);
|
||||
|
||||
/* begin calculating determinant - also used to calculate U parameter */
|
||||
LLVector3 pvec = dir % edge2;
|
||||
|
||||
LLVector4a pvec;
|
||||
pvec.setCross3(dir, edge2);
|
||||
|
||||
/* if determinant is near zero, ray lies in plane of triangle */
|
||||
F32 det = edge1 * pvec;
|
||||
F32 det = edge1.dot3(pvec).getF32();
|
||||
|
||||
if (!two_sided)
|
||||
|
||||
if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO)
|
||||
{
|
||||
if (det < F_APPROXIMATELY_ZERO)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* calculate distance from vert0 to ray origin */
|
||||
LLVector3 tvec = orig - vert0;
|
||||
|
||||
/* calculate U parameter and test bounds */
|
||||
u = tvec * pvec;
|
||||
|
||||
if (u < 0.f || u > det)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* prepare to test V parameter */
|
||||
LLVector3 qvec = tvec % edge1;
|
||||
|
||||
/* calculate V parameter and test bounds */
|
||||
v = dir * qvec;
|
||||
if (v < 0.f || u + v > det)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* calculate t, scale parameters, ray intersects triangle */
|
||||
t = edge2 * qvec;
|
||||
F32 inv_det = 1.0 / det;
|
||||
t *= inv_det;
|
||||
u *= inv_det;
|
||||
v *= inv_det;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
F32 inv_det = 1.f / det;
|
||||
|
||||
/* calculate distance from vert0 to ray origin */
|
||||
LLVector4a tvec;
|
||||
tvec.setSub(orig, vert0);
|
||||
|
||||
else // two sided
|
||||
{
|
||||
if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
F32 inv_det = 1.0 / det;
|
||||
|
||||
/* calculate distance from vert0 to ray origin */
|
||||
LLVector3 tvec = orig - vert0;
|
||||
|
||||
/* calculate U parameter and test bounds */
|
||||
u = (tvec * pvec) * inv_det;
|
||||
if (u < 0.f || u > 1.f)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* prepare to test V parameter */
|
||||
LLVector3 qvec = tvec - edge1;
|
||||
|
||||
/* calculate V parameter and test bounds */
|
||||
v = (dir * qvec) * inv_det;
|
||||
|
||||
if (v < 0.f || u + v > 1.f)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* calculate t, ray intersects triangle */
|
||||
t = (edge2 * qvec) * inv_det;
|
||||
/* calculate U parameter and test bounds */
|
||||
u = (tvec.dot3(pvec).getF32()) * inv_det;
|
||||
if (u < 0.f || u > 1.f)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* prepare to test V parameter */
|
||||
tvec.sub(edge1);
|
||||
|
||||
/* calculate V parameter and test bounds */
|
||||
v = (dir.dot3(tvec).getF32()) * inv_det;
|
||||
|
||||
if (intersection_a != NULL)
|
||||
*intersection_a = u;
|
||||
if (intersection_b != NULL)
|
||||
*intersection_b = v;
|
||||
if (intersection_t != NULL)
|
||||
*intersection_t = t;
|
||||
if (v < 0.f || u + v > 1.f)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* calculate t, ray intersects triangle */
|
||||
t = (edge2.dot3(tvec).getF32()) * inv_det;
|
||||
|
||||
intersection_a = u;
|
||||
intersection_b = v;
|
||||
intersection_t = t;
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//helper for non-aligned vectors
|
||||
BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
|
||||
F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided)
|
||||
{
|
||||
LLVector4a vert0a, vert1a, vert2a, origa, dira;
|
||||
vert0a.load3(vert0.mV);
|
||||
vert1a.load3(vert1.mV);
|
||||
vert2a.load3(vert2.mV);
|
||||
origa.load3(orig.mV);
|
||||
dira.load3(dir.mV);
|
||||
|
||||
if (two_sided)
|
||||
{
|
||||
return LLTriangleRayIntersectTwoSided(vert0a, vert1a, vert2a, origa, dira,
|
||||
intersection_a, intersection_b, intersection_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira,
|
||||
intersection_a, intersection_b, intersection_t);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle>
|
||||
{
|
||||
public:
|
||||
const LLVolumeFace* mFace;
|
||||
|
||||
LLVolumeOctreeRebound(const LLVolumeFace* face)
|
||||
{
|
||||
mFace = face;
|
||||
}
|
||||
|
||||
virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
|
||||
{ //this is a depth first traversal, so it's safe to assum all children have complete
|
||||
//bounding data
|
||||
|
||||
LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0);
|
||||
|
||||
LLVector4a& min = node->mExtents[0];
|
||||
LLVector4a& max = node->mExtents[1];
|
||||
|
||||
if (!branch->getData().empty())
|
||||
{ //node has data, find AABB that binds data set
|
||||
const LLVolumeTriangle* tri = *(branch->getData().begin());
|
||||
|
||||
//initialize min/max to first available vertex
|
||||
min = *(tri->mV[0]);
|
||||
max = *(tri->mV[0]);
|
||||
|
||||
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
|
||||
branch->getData().begin(); iter != branch->getData().end(); ++iter)
|
||||
{ //for each triangle in node
|
||||
|
||||
//stretch by triangles in node
|
||||
tri = *iter;
|
||||
|
||||
min.setMin(min, *tri->mV[0]);
|
||||
min.setMin(min, *tri->mV[1]);
|
||||
min.setMin(min, *tri->mV[2]);
|
||||
|
||||
max.setMax(max, *tri->mV[0]);
|
||||
max.setMax(max, *tri->mV[1]);
|
||||
max.setMax(max, *tri->mV[2]);
|
||||
}
|
||||
}
|
||||
else if (!branch->getChildren().empty())
|
||||
{ //no data, but child nodes exist
|
||||
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0);
|
||||
|
||||
//initialize min/max to extents of first child
|
||||
min = child->mExtents[0];
|
||||
max = child->mExtents[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Empty leaf" << llendl;
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < branch->getChildCount(); ++i)
|
||||
{ //stretch by child extents
|
||||
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0);
|
||||
min.setMin(min, child->mExtents[0]);
|
||||
max.setMax(max, child->mExtents[1]);
|
||||
}
|
||||
|
||||
node->mBounds[0].setAdd(min, max);
|
||||
node->mBounds[0].mul(0.5f);
|
||||
|
||||
node->mBounds[1].setSub(max,min);
|
||||
node->mBounds[1].mul(0.5f);
|
||||
}
|
||||
};*/
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// statics
|
||||
@@ -2199,7 +2335,7 @@ void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32
|
||||
ratio = (F32) width / (F32) height;
|
||||
|
||||
|
||||
s = (S32)fsqrtf(((F32)vertices / ratio));
|
||||
s = (S32)(F32) sqrt(((F32)vertices / ratio));
|
||||
|
||||
s = llmax(s, 4); // no degenerate sizes, please
|
||||
t = vertices / s;
|
||||
@@ -3396,13 +3532,22 @@ S32 LLVolume::getNumTriangleIndices() const
|
||||
void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
||||
std::vector<LLVector3> &normals,
|
||||
std::vector<S32> &segments,
|
||||
const LLVector3& obj_cam_vec,
|
||||
const LLMatrix4& mat,
|
||||
const LLMatrix3& norm_mat,
|
||||
const LLVector3& obj_cam_vec_in,
|
||||
const LLMatrix4& mat_in,
|
||||
const LLMatrix3& norm_mat_in,
|
||||
S32 face_mask)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_VOLUME);
|
||||
|
||||
|
||||
LLMatrix4a mat;
|
||||
mat.loadu(mat_in);
|
||||
|
||||
LLMatrix4a norm_mat;
|
||||
norm_mat.loadu(norm_mat_in);
|
||||
|
||||
LLVector4a obj_cam_vec;
|
||||
obj_cam_vec.load3(obj_cam_vec_in.mV);
|
||||
|
||||
vertices.clear();
|
||||
normals.clear();
|
||||
segments.clear();
|
||||
@@ -3414,10 +3559,12 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
||||
{
|
||||
const LLVolumeFace& face = *iter;
|
||||
|
||||
if (!(face_mask & (0x1 << cur_index++)))
|
||||
if (!(face_mask & (0x1 << cur_index++)) ||
|
||||
face.mIndices.empty() || face.mEdge.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) {
|
||||
|
||||
}
|
||||
@@ -3517,18 +3664,30 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
||||
S32 v2 = face.mIndices[j*3+1];
|
||||
S32 v3 = face.mIndices[j*3+2];
|
||||
|
||||
LLVector3 norm = (face.mVertices[v1].mPosition - face.mVertices[v2].mPosition) %
|
||||
(face.mVertices[v2].mPosition - face.mVertices[v3].mPosition);
|
||||
|
||||
if (norm.magVecSquared() < 0.00000001f)
|
||||
//ew. Face verts arent aligned yet.
|
||||
LLVector4a va1,va3;
|
||||
va1.load3(face.mVertices[v1].mPosition.mV);
|
||||
va3.load3(face.mVertices[v3].mPosition.mV);
|
||||
|
||||
LLVector4a c1,c2;
|
||||
c2.load3(face.mVertices[v2].mPosition.mV);
|
||||
c1.setSub(va1,c2);
|
||||
c2.sub(va3);
|
||||
|
||||
LLVector4a norm;
|
||||
|
||||
norm.setCross3(c1, c2);
|
||||
|
||||
if (norm.dot3(norm) < 0.00000001f)
|
||||
{
|
||||
fFacing[j] = AWAY | TOWARDS;
|
||||
}
|
||||
else
|
||||
{
|
||||
//get view vector
|
||||
LLVector3 view = (obj_cam_vec-face.mVertices[v1].mPosition);
|
||||
bool away = view * norm > 0.0f;
|
||||
LLVector4a view;
|
||||
view.setSub(obj_cam_vec, va1);
|
||||
bool away = view.dot3(norm) > 0.0f;
|
||||
if (away)
|
||||
{
|
||||
fFacing[j] = AWAY;
|
||||
@@ -3574,13 +3733,13 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
||||
S32 v1 = face.mIndices[j*3+k];
|
||||
S32 v2 = face.mIndices[j*3+((k+1)%3)];
|
||||
|
||||
vertices.push_back(face.mVertices[v1].mPosition*mat);
|
||||
LLVector3 norm1 = face.mVertices[v1].mNormal * norm_mat;
|
||||
vertices.push_back(face.mVertices[v1].mPosition*mat_in);
|
||||
LLVector3 norm1 = face.mVertices[v1].mNormal * norm_mat_in;
|
||||
norm1.normVec();
|
||||
normals.push_back(norm1);
|
||||
|
||||
vertices.push_back(face.mVertices[v2].mPosition*mat);
|
||||
LLVector3 norm2 = face.mVertices[v2].mNormal * norm_mat;
|
||||
vertices.push_back(face.mVertices[v2].mPosition*mat_in);
|
||||
LLVector3 norm2 = face.mVertices[v2].mNormal * norm_mat_in;
|
||||
norm2.normVec();
|
||||
normals.push_back(norm2);
|
||||
|
||||
@@ -3596,6 +3755,19 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
||||
S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
S32 face,
|
||||
LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
|
||||
{
|
||||
LLVector4a starta, enda;
|
||||
starta.load3(start.mV);
|
||||
enda.load3(end.mV);
|
||||
|
||||
return lineSegmentIntersect(starta, enda, face, intersection, tex_coord, normal, bi_normal);
|
||||
|
||||
}
|
||||
|
||||
|
||||
S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face,
|
||||
LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
|
||||
{
|
||||
S32 hit_face = -1;
|
||||
|
||||
@@ -3613,7 +3785,8 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
end_face = face;
|
||||
}
|
||||
|
||||
LLVector3 dir = end - start;
|
||||
LLVector4a dir;
|
||||
dir.setSub(end, start);
|
||||
|
||||
F32 closest_t = 2.f; // must be larger than 1
|
||||
|
||||
@@ -3621,8 +3794,12 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
{
|
||||
const LLVolumeFace &face = getVolumeFace((U32)i);
|
||||
|
||||
LLVector3 box_center = (face.mExtents[0] + face.mExtents[1]) / 2.f;
|
||||
LLVector3 box_size = face.mExtents[1] - face.mExtents[0];
|
||||
LLVector4a box_center;
|
||||
box_center.setAdd(face.mExtents[0], face.mExtents[1]);
|
||||
box_center.mul(0.5f);
|
||||
|
||||
LLVector4a box_size;
|
||||
box_size.setSub(face.mExtents[1], face.mExtents[0]);
|
||||
|
||||
if (LLLineSegmentBoxIntersect(start, end, box_center, box_size))
|
||||
{
|
||||
@@ -3638,11 +3815,15 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
S32 index3 = face.mIndices[tri*3+2];
|
||||
|
||||
F32 a, b, t;
|
||||
|
||||
if (LLTriangleRayIntersect(face.mVertices[index1].mPosition,
|
||||
face.mVertices[index2].mPosition,
|
||||
face.mVertices[index3].mPosition,
|
||||
start, dir, &a, &b, &t, FALSE))
|
||||
|
||||
LLVector4a pos[3];
|
||||
pos[0].load3(face.mVertices[index1].mPosition.mV);
|
||||
pos[1].load3(face.mVertices[index2].mPosition.mV);
|
||||
pos[2].load3(face.mVertices[index2].mPosition.mV);
|
||||
if (LLTriangleRayIntersect(pos[0],
|
||||
pos[1],
|
||||
pos[2],
|
||||
start, dir, a, b, t))
|
||||
{
|
||||
if ((t >= 0.f) && // if hit is after start
|
||||
(t <= 1.f) && // and before end
|
||||
@@ -3653,7 +3834,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
|
||||
if (intersection != NULL)
|
||||
{
|
||||
*intersection = start + dir * closest_t;
|
||||
LLVector4a v;
|
||||
v.setMul(dir,closest_t);
|
||||
v.add(start);
|
||||
intersection->set(v.getF32ptr());
|
||||
}
|
||||
|
||||
if (tex_coord != NULL)
|
||||
@@ -4421,7 +4605,69 @@ std::ostream& operator<<(std::ostream &s, const LLVolume *volumep)
|
||||
return s;
|
||||
}
|
||||
|
||||
LLVolumeFace::LLVolumeFace() :
|
||||
mID(0),
|
||||
mTypeMask(0),
|
||||
mHasBinormals(FALSE),
|
||||
mBeginS(0),
|
||||
mBeginT(0),
|
||||
mNumS(0),
|
||||
mNumT(0)
|
||||
{
|
||||
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
|
||||
mExtents[0].splat(-0.5f);
|
||||
mExtents[1].splat(0.5f);
|
||||
mCenter = mExtents+2;
|
||||
}
|
||||
|
||||
LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
|
||||
: mID(0),
|
||||
mTypeMask(0),
|
||||
mHasBinormals(FALSE),
|
||||
mBeginS(0),
|
||||
mBeginT(0),
|
||||
mNumS(0),
|
||||
mNumT(0)
|
||||
{
|
||||
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
|
||||
mCenter = mExtents+2;
|
||||
*this = src;
|
||||
}
|
||||
|
||||
LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
|
||||
{
|
||||
if (&src == this)
|
||||
{ //self assignment, do nothing
|
||||
return *this;
|
||||
}
|
||||
|
||||
mID = src.mID;
|
||||
mTypeMask = src.mTypeMask;
|
||||
mHasBinormals = src.mHasBinormals,
|
||||
mBeginS = src.mBeginS;
|
||||
mBeginT = src.mBeginT;
|
||||
mNumS = src.mNumS;
|
||||
mNumT = src.mNumT;
|
||||
|
||||
mExtents[0] = src.mExtents[0];
|
||||
mExtents[1] = src.mExtents[1];
|
||||
*mCenter = *src.mCenter;
|
||||
|
||||
|
||||
|
||||
LLVector4a::memcpyNonAliased16((F32*) mExtents, (F32*) src.mExtents, 3*sizeof(LLVector4a));
|
||||
|
||||
mVertices = src.mVertices;
|
||||
mIndices = src.mIndices;
|
||||
mEdge = src.mEdge;
|
||||
return *this;
|
||||
}
|
||||
LLVolumeFace::~LLVolumeFace()
|
||||
{
|
||||
ll_aligned_free_16(mExtents);
|
||||
mExtents = NULL;
|
||||
|
||||
}
|
||||
BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
|
||||
{
|
||||
BOOL ret = FALSE ;
|
||||
@@ -4504,78 +4750,99 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
|
||||
num_vertices = (grid_size+1)*(grid_size+1);
|
||||
num_indices = quad_count * 4;
|
||||
|
||||
LLVector3& min = mExtents[0];
|
||||
LLVector3& max = mExtents[1];
|
||||
LLVector4a& min = mExtents[0];
|
||||
LLVector4a& max = mExtents[1];
|
||||
|
||||
S32 offset = 0;
|
||||
if (mTypeMask & TOP_MASK)
|
||||
offset = (max_t-1) * max_s;
|
||||
else
|
||||
offset = mBeginS;
|
||||
|
||||
VertexData corners[4];
|
||||
VertexData baseVert;
|
||||
for(int t = 0; t < 4; t++){
|
||||
corners[t].mPosition = mesh[offset + (grid_size*t)].mPos;
|
||||
corners[t].mTexCoord.mV[0] = profile[grid_size*t].mV[0]+0.5f;
|
||||
corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t].mV[1];
|
||||
}
|
||||
baseVert.mNormal =
|
||||
((corners[1].mPosition-corners[0].mPosition) %
|
||||
(corners[2].mPosition-corners[1].mPosition));
|
||||
baseVert.mNormal.normVec();
|
||||
if(!(mTypeMask & TOP_MASK)){
|
||||
baseVert.mNormal *= -1.0f;
|
||||
}else{
|
||||
//Swap the UVs on the U(X) axis for top face
|
||||
LLVector2 swap;
|
||||
swap = corners[0].mTexCoord;
|
||||
corners[0].mTexCoord=corners[3].mTexCoord;
|
||||
corners[3].mTexCoord=swap;
|
||||
swap = corners[1].mTexCoord;
|
||||
corners[1].mTexCoord=corners[2].mTexCoord;
|
||||
corners[2].mTexCoord=swap;
|
||||
}
|
||||
baseVert.mBinormal = calc_binormal_from_triangle(
|
||||
corners[0].mPosition, corners[0].mTexCoord,
|
||||
corners[1].mPosition, corners[1].mTexCoord,
|
||||
corners[2].mPosition, corners[2].mTexCoord);
|
||||
for(int t = 0; t < 4; t++){
|
||||
corners[t].mBinormal = baseVert.mBinormal;
|
||||
corners[t].mNormal = baseVert.mNormal;
|
||||
}
|
||||
mHasBinormals = TRUE;
|
||||
|
||||
if (partial_build)
|
||||
{
|
||||
mVertices.clear();
|
||||
offset = (max_t-1) * max_s;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = mBeginS;
|
||||
}
|
||||
|
||||
S32 vtop = mVertices.size();
|
||||
for(int gx = 0;gx<grid_size+1;gx++){
|
||||
for(int gy = 0;gy<grid_size+1;gy++){
|
||||
VertexData newVert;
|
||||
LerpPlanarVertex(
|
||||
corners[0],
|
||||
corners[1],
|
||||
corners[3],
|
||||
newVert,
|
||||
(F32)gx/(F32)grid_size,
|
||||
(F32)gy/(F32)grid_size);
|
||||
mVertices.push_back(newVert);
|
||||
S32 vtop;
|
||||
{
|
||||
VertexData corners[4];
|
||||
VertexData baseVert;
|
||||
for(S32 t = 0; t < 4; t++){
|
||||
corners[t].mPosition = mesh[offset + (grid_size*t)].mPos;
|
||||
corners[t].mTexCoord.mV[0] = profile[grid_size*t].mV[0]+0.5f;
|
||||
corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t].mV[1];
|
||||
}
|
||||
|
||||
if (gx == 0 && gy == 0)
|
||||
{
|
||||
baseVert.mNormal =
|
||||
((corners[1].mPosition-corners[0].mPosition) %
|
||||
(corners[2].mPosition-corners[1].mPosition));
|
||||
baseVert.mNormal.normalize();
|
||||
}
|
||||
|
||||
if(!(mTypeMask & TOP_MASK))
|
||||
{
|
||||
baseVert.mNormal *= -.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Swap the UVs on the U(X) axis for top face
|
||||
LLVector2 swap;
|
||||
swap = corners[0].mTexCoord;
|
||||
corners[0].mTexCoord=corners[3].mTexCoord;
|
||||
corners[3].mTexCoord=swap;
|
||||
swap = corners[1].mTexCoord;
|
||||
corners[1].mTexCoord=corners[2].mTexCoord;
|
||||
corners[2].mTexCoord=swap;
|
||||
}
|
||||
baseVert.mBinormal = calc_binormal_from_triangle(
|
||||
corners[0].mPosition, corners[0].mTexCoord,
|
||||
corners[1].mPosition, corners[1].mTexCoord,
|
||||
corners[2].mPosition, corners[2].mTexCoord);
|
||||
for(int t = 0; t < 4; t++){
|
||||
corners[t].mBinormal = baseVert.mBinormal;
|
||||
corners[t].mNormal = baseVert.mNormal;
|
||||
}
|
||||
mHasBinormals = TRUE;
|
||||
|
||||
if (partial_build)
|
||||
{
|
||||
mVertices.clear();
|
||||
}
|
||||
|
||||
vtop = mVertices.size();
|
||||
|
||||
for(int gx = 0;gx<grid_size+1;gx++)
|
||||
{
|
||||
for(int gy = 0;gy<grid_size+1;gy++)
|
||||
{
|
||||
min = max = newVert.mPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
update_min_max(min,max,newVert.mPosition);
|
||||
VertexData newVert;
|
||||
LerpPlanarVertex(
|
||||
corners[0],
|
||||
corners[1],
|
||||
corners[3],
|
||||
newVert,
|
||||
(F32)gx/(F32)grid_size,
|
||||
(F32)gy/(F32)grid_size);
|
||||
mVertices.push_back(newVert);
|
||||
|
||||
if (gx == 0 && gy == 0)
|
||||
{
|
||||
max.load3(newVert.mPosition.mV);
|
||||
min = max;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVector4a pos;
|
||||
pos.load3(newVert.mPosition.mV);
|
||||
update_min_max(min,max,pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mCenter = (min + max) * 0.5f;
|
||||
mCenter->setAdd(min, max);
|
||||
mCenter->mul(0.5f);
|
||||
}
|
||||
|
||||
if (!partial_build)
|
||||
{
|
||||
@@ -4640,7 +4907,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
|
||||
S32 max_s = volume->getProfile().getTotal();
|
||||
S32 max_t = volume->getPath().mPath.size();
|
||||
|
||||
mCenter.clearVec();
|
||||
mCenter->clear();
|
||||
|
||||
S32 offset = 0;
|
||||
if (mTypeMask & TOP_MASK)
|
||||
@@ -4658,8 +4925,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
|
||||
LLVector2 cuv;
|
||||
LLVector2 min_uv, max_uv;
|
||||
|
||||
LLVector3& min = mExtents[0];
|
||||
LLVector3& max = mExtents[1];
|
||||
LLVector4a& min = mExtents[0];
|
||||
LLVector4a& max = mExtents[1];
|
||||
|
||||
// Copy the vertices into the array
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
@@ -4680,38 +4947,54 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
min = max = mVertices[i].mPosition;
|
||||
max.load3(mVertices[i].mPosition.mV);
|
||||
min = max;
|
||||
min_uv = max_uv = mVertices[i].mTexCoord;
|
||||
}
|
||||
else
|
||||
{
|
||||
update_min_max(min,max, mVertices[i].mPosition);
|
||||
LLVector4a pos;
|
||||
pos.load3(mVertices[i].mPosition.mV);
|
||||
update_min_max(min,max, pos);
|
||||
update_min_max(min_uv, max_uv, mVertices[i].mTexCoord);
|
||||
}
|
||||
}
|
||||
|
||||
mCenter = (min+max)*0.5f;
|
||||
mCenter->setAdd(min, max);
|
||||
mCenter->mul(0.5f);
|
||||
|
||||
cuv = (min_uv + max_uv)*0.5f;
|
||||
|
||||
LLVector3 binormal = calc_binormal_from_triangle(
|
||||
mCenter, cuv,
|
||||
LLVector3 binormal = calc_binormal_from_triangle(
|
||||
LLVector3(mCenter->getF32ptr()), cuv,
|
||||
mVertices[0].mPosition, mVertices[0].mTexCoord,
|
||||
mVertices[1].mPosition, mVertices[1].mTexCoord);
|
||||
binormal.normVec();
|
||||
|
||||
LLVector3 d0;
|
||||
LLVector3 d1;
|
||||
LLVector3 normal;
|
||||
LLVector4a pos[2];
|
||||
pos[0].load3(mVertices[0].mPosition.mV);
|
||||
pos[1].load3(mVertices[0].mPosition.mV);
|
||||
LLVector4a normal;
|
||||
LLVector4a d0, d1;
|
||||
|
||||
|
||||
d0 = mCenter-mVertices[0].mPosition;
|
||||
d1 = mCenter-mVertices[1].mPosition;
|
||||
d0.setSub(*mCenter, pos[0]);
|
||||
d1.setSub(*mCenter, pos[1]);
|
||||
|
||||
normal = (mTypeMask & TOP_MASK) ? (d0%d1) : (d1%d0);
|
||||
normal.normVec();
|
||||
if (mTypeMask & TOP_MASK)
|
||||
{
|
||||
normal.setCross3(d0, d1);
|
||||
}
|
||||
else
|
||||
{
|
||||
normal.setCross3(d1, d0);
|
||||
}
|
||||
|
||||
normal.normalize3fast();
|
||||
|
||||
VertexData vd;
|
||||
vd.mPosition = mCenter;
|
||||
vd.mNormal = normal;
|
||||
vd.mPosition.set(mCenter->getF32ptr());
|
||||
vd.mNormal.set(normal.getF32ptr());
|
||||
vd.mBinormal = binormal;
|
||||
vd.mTexCoord = cuv;
|
||||
|
||||
@@ -4729,7 +5012,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
mVertices[i].mBinormal = binormal;
|
||||
mVertices[i].mNormal = normal;
|
||||
mVertices[i].mNormal.set(normal.getF32ptr());
|
||||
}
|
||||
|
||||
mHasBinormals = TRUE;
|
||||
@@ -5146,17 +5429,21 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
|
||||
|
||||
|
||||
//get bounding box for this side
|
||||
LLVector3& face_min = mExtents[0];
|
||||
LLVector3& face_max = mExtents[1];
|
||||
mCenter.clearVec();
|
||||
LLVector4a& face_min = mExtents[0];
|
||||
LLVector4a& face_max = mExtents[1];
|
||||
mCenter->clear();
|
||||
|
||||
face_min = face_max = mVertices[0].mPosition;
|
||||
face_max.load3(mVertices[0].mPosition.mV);
|
||||
face_min = face_max;
|
||||
for (U32 i = 1; i < mVertices.size(); ++i)
|
||||
{
|
||||
update_min_max(face_min, face_max, mVertices[i].mPosition);
|
||||
LLVector4a pos;
|
||||
pos.load3(mVertices[i].mPosition.mV);
|
||||
update_min_max(face_min, face_max, pos);
|
||||
}
|
||||
|
||||
mCenter = (face_min + face_max) * 0.5f;
|
||||
mCenter->setAdd(face_min, face_max);
|
||||
mCenter->mul(0.5f);
|
||||
|
||||
S32 cur_index = 0;
|
||||
S32 cur_edge = 0;
|
||||
|
||||
@@ -49,6 +49,8 @@ class LLVolume;
|
||||
//#include "vmath.h"
|
||||
#include "v2math.h"
|
||||
#include "v3math.h"
|
||||
#include "v3dmath.h"
|
||||
#include "v4math.h"
|
||||
#include "llquaternion.h"
|
||||
#include "llstrider.h"
|
||||
#include "v4coloru.h"
|
||||
@@ -786,20 +788,6 @@ public:
|
||||
class LLVolumeFace
|
||||
{
|
||||
public:
|
||||
LLVolumeFace() :
|
||||
mID(0),
|
||||
mTypeMask(0),
|
||||
mHasBinormals(FALSE),
|
||||
mBeginS(0),
|
||||
mBeginT(0),
|
||||
mNumS(0),
|
||||
mNumT(0)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
void createBinormals();
|
||||
|
||||
class VertexData
|
||||
{
|
||||
public:
|
||||
@@ -808,6 +796,14 @@ public:
|
||||
LLVector3 mBinormal;
|
||||
LLVector2 mTexCoord;
|
||||
};
|
||||
LLVolumeFace();
|
||||
LLVolumeFace(const LLVolumeFace& src);
|
||||
LLVolumeFace& operator=(const LLVolumeFace& rhs);
|
||||
|
||||
~LLVolumeFace();
|
||||
BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
void createBinormals();
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -827,7 +823,6 @@ public:
|
||||
public:
|
||||
S32 mID;
|
||||
U32 mTypeMask;
|
||||
LLVector3 mCenter;
|
||||
BOOL mHasBinormals;
|
||||
|
||||
// Only used for INNER/OUTER faces
|
||||
@@ -836,8 +831,9 @@ public:
|
||||
S32 mNumS;
|
||||
S32 mNumT;
|
||||
|
||||
LLVector3 mExtents[2]; //minimum and maximum point of face
|
||||
LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
|
||||
LLVector4a* mExtents; //minimum and maximum point of face
|
||||
LLVector4a* mCenter;
|
||||
LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
|
||||
|
||||
std::vector<VertexData> mVertices;
|
||||
std::vector<U16> mIndices;
|
||||
@@ -898,6 +894,7 @@ public:
|
||||
BOOL isUnique() const { return mUnique; }
|
||||
|
||||
S32 getSculptLevel() const { return mSculptLevel; }
|
||||
void setSculptLevel(S32 level) { mSculptLevel = level; }
|
||||
|
||||
S32 *getTriangleIndices(U32 &num_indices) const;
|
||||
|
||||
@@ -922,6 +919,13 @@ public:
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
);
|
||||
|
||||
S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = 1,
|
||||
LLVector3* intersection = NULL,
|
||||
LLVector2* tex_coord = NULL,
|
||||
LLVector3* normal = NULL,
|
||||
LLVector3* bi_normal = NULL);
|
||||
|
||||
// The following cleans up vertices and triangles,
|
||||
// getting rid of degenerate triangles and duplicate vertices,
|
||||
@@ -986,8 +990,15 @@ LLVector3 calc_binormal_from_triangle(
|
||||
|
||||
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);
|
||||
BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);
|
||||
BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size);
|
||||
|
||||
BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
|
||||
F32* intersection_a, F32* intersection_b, F32* intersection_t, BOOL two_sided);
|
||||
F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
|
||||
|
||||
BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
|
||||
F32& intersection_a, F32& intersection_b, F32& intersection_t);
|
||||
BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
|
||||
F32& intersection_a, F32& intersection_b, F32& intersection_t);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -320,7 +320,7 @@ BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep)
|
||||
{
|
||||
llassert_always(mLODRefs[i] > 0);
|
||||
mLODRefs[i]--;
|
||||
#if 1 // SJB: Possible opt: keep other lods around
|
||||
#if 0 // SJB: Possible opt: keep other lods around
|
||||
if (!mLODRefs[i])
|
||||
{
|
||||
mVolumeLODs[i] = NULL;
|
||||
@@ -375,6 +375,19 @@ F32 LLVolumeLODGroup::getVolumeScaleFromDetail(const S32 detail)
|
||||
return mDetailScales[detail];
|
||||
}
|
||||
|
||||
S32 LLVolumeLODGroup::getVolumeDetailFromScale(const F32 detail)
|
||||
{
|
||||
for (S32 i = 1; i < 4; i++)
|
||||
{
|
||||
if (mDetailScales[i] > detail)
|
||||
{
|
||||
return i-1;
|
||||
}
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
F32 LLVolumeLODGroup::dump()
|
||||
{
|
||||
F32 usage = 0.f;
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
static S32 getDetailFromTan(const F32 tan_angle);
|
||||
static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher);
|
||||
static F32 getVolumeScaleFromDetail(const S32 detail);
|
||||
static S32 getVolumeDetailFromScale(F32 scale);
|
||||
|
||||
LLVolume* refLOD(const S32 detail);
|
||||
BOOL derefLOD(LLVolume *volumep);
|
||||
@@ -92,8 +93,8 @@ public:
|
||||
// whatever calls getVolume() never owns the LLVolume* and
|
||||
// cannot keep references for long since it may be deleted
|
||||
// later. For best results hold it in an LLPointer<LLVolume>.
|
||||
LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail);
|
||||
void unrefVolume(LLVolume *volumep);
|
||||
virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail);
|
||||
virtual void unrefVolume(LLVolume *volumep);
|
||||
|
||||
void dump();
|
||||
|
||||
|
||||
@@ -411,8 +411,9 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
|
||||
LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation
|
||||
LLVector3 object_extents = object->getScale();
|
||||
//this stuff just seems to make camera snapping worse...
|
||||
//const LLVector3* oe3 = object->mDrawable->getSpatialExtents();
|
||||
//object_extents.set( oe3[1][0], oe3[1][1], oe3[1][2] );
|
||||
//const LLVector4a* oe4 = object->mDrawable->getSpatialExtents();
|
||||
//object_extents.set( oe4[1][0], oe4[1][1], oe4[1][2] );
|
||||
|
||||
|
||||
// make sure they object extents are non-zero
|
||||
object_extents.clamp(0.001f, F32_MAX);
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
#include "statemachine/aifilepicker.h"
|
||||
#include "llfirstuse.h"
|
||||
#include "llrender.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llfont.h"
|
||||
#include "llvocache.h"
|
||||
#include "llfloaterteleporthistory.h"
|
||||
@@ -562,6 +563,8 @@ bool LLAppViewer::init()
|
||||
// we run the "program crashed last time" error handler below.
|
||||
//
|
||||
|
||||
// initialize SSE options
|
||||
LLVector4a::initClass();
|
||||
// Need to do this initialization before we do anything else, since anything
|
||||
// that touches files should really go through the lldir API
|
||||
gDirUtilp->initAppDirs("SecondLife");
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "llcriticaldamp.h"
|
||||
#include "llface.h"
|
||||
#include "lllightconstants.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "llsky.h"
|
||||
#include "llsurfacepatch.h"
|
||||
#include "llviewercamera.h"
|
||||
@@ -95,7 +96,7 @@ void LLDrawable::init()
|
||||
mRenderType = 0;
|
||||
mCurrentScale = LLVector3(1,1,1);
|
||||
mDistanceWRTCamera = 0.0f;
|
||||
mPositionGroup.clearVec();
|
||||
mPositionGroup.clear();
|
||||
mExtents[0].clear();
|
||||
mExtents[1].clear();
|
||||
mQuietCount = 0;
|
||||
@@ -705,7 +706,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
|
||||
{
|
||||
if (getSpatialGroup())
|
||||
{
|
||||
pos.set(getPositionGroup());
|
||||
pos.set(getPositionGroup().getF32ptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -714,26 +715,28 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
|
||||
|
||||
if (isState(LLDrawable::HAS_ALPHA))
|
||||
{
|
||||
for (S32 i = 0; i < getNumFaces(); i++)
|
||||
{
|
||||
LLFace* facep = getFace(i);
|
||||
if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)
|
||||
for (S32 i = 0; i < getNumFaces(); i++)
|
||||
{
|
||||
LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f;
|
||||
LLVector3 v = (facep->mCenterLocal-camera.getOrigin());
|
||||
LLFace* facep = getFace(i);
|
||||
if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)
|
||||
{
|
||||
LLVector4a box;
|
||||
box.setSub(facep->mExtents[1], facep->mExtents[0]);
|
||||
box.mul(0.25f);
|
||||
LLVector3 v = (facep->mCenterLocal-camera.getOrigin());
|
||||
const LLVector3& at = camera.getAtAxis();
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
v.mV[j] -= box.mV[j] * at.mV[j];
|
||||
{
|
||||
v.mV[j] -= box[j] * at.mV[j];
|
||||
}
|
||||
facep->mDistance = v * camera.getAtAxis();
|
||||
}
|
||||
facep->mDistance = v * camera.getAtAxis();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = LLVector3(getPositionGroup());
|
||||
pos = LLVector3(getPositionGroup().getF32ptr());
|
||||
}
|
||||
|
||||
pos -= camera.getOrigin();
|
||||
@@ -782,7 +785,7 @@ BOOL LLDrawable::updateGeometry(BOOL priority)
|
||||
return res;
|
||||
}
|
||||
|
||||
void LLDrawable::shiftPos(const LLVector3 &shift_vector)
|
||||
void LLDrawable::shiftPos(const LLVector4a &shift_vector)
|
||||
{
|
||||
if (isDead())
|
||||
{
|
||||
@@ -814,9 +817,9 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector)
|
||||
for (S32 i = 0; i < getNumFaces(); i++)
|
||||
{
|
||||
LLFace *facep = getFace(i);
|
||||
facep->mCenterAgent += shift_vector;
|
||||
facep->mExtents[0] += shift_vector;
|
||||
facep->mExtents[1] += shift_vector;
|
||||
facep->mCenterAgent += LLVector3(shift_vector.getF32ptr());
|
||||
facep->mExtents[0].add(shift_vector);
|
||||
facep->mExtents[1].add(shift_vector);
|
||||
|
||||
if (!volume && facep->hasGeometry())
|
||||
{
|
||||
@@ -824,9 +827,9 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector)
|
||||
}
|
||||
}
|
||||
|
||||
mExtents[0] += shift_vector;
|
||||
mExtents[1] += shift_vector;
|
||||
mPositionGroup += LLVector3d(shift_vector);
|
||||
mExtents[0].add(shift_vector);
|
||||
mExtents[1].add(shift_vector);
|
||||
mPositionGroup.add(shift_vector);
|
||||
}
|
||||
else if (mSpatialBridge)
|
||||
{
|
||||
@@ -834,9 +837,9 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector)
|
||||
}
|
||||
else if (isAvatar())
|
||||
{
|
||||
mExtents[0] += shift_vector;
|
||||
mExtents[1] += shift_vector;
|
||||
mPositionGroup += LLVector3d(shift_vector);
|
||||
mExtents[0].add(shift_vector);
|
||||
mExtents[1].add(shift_vector);
|
||||
mPositionGroup.add(shift_vector);
|
||||
}
|
||||
|
||||
mVObjp->onShift(shift_vector);
|
||||
@@ -848,21 +851,26 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const
|
||||
return mXform.getPositionW();
|
||||
}
|
||||
|
||||
const LLVector3* LLDrawable::getSpatialExtents() const
|
||||
const LLVector4a* LLDrawable::getSpatialExtents() const
|
||||
{
|
||||
return mExtents;
|
||||
}
|
||||
|
||||
void LLDrawable::setSpatialExtents(LLVector3 min, LLVector3 max)
|
||||
void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max)
|
||||
{
|
||||
LLVector3 size = max - min;
|
||||
mExtents[0] = min;
|
||||
mExtents[1] = max;
|
||||
mExtents[0].load3(min.mV);
|
||||
mExtents[1].load3(max.mV);
|
||||
}
|
||||
|
||||
void LLDrawable::setPositionGroup(const LLVector3d& pos)
|
||||
void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max)
|
||||
{
|
||||
mExtents[0] = min;
|
||||
mExtents[1] = max;
|
||||
}
|
||||
|
||||
void LLDrawable::setPositionGroup(const LLVector4a& pos)
|
||||
{
|
||||
mPositionGroup.setVec(pos);
|
||||
mPositionGroup = pos;
|
||||
}
|
||||
|
||||
void LLDrawable::updateSpatialExtents()
|
||||
@@ -876,7 +884,7 @@ void LLDrawable::updateSpatialExtents()
|
||||
|
||||
if (mSpatialBridge.notNull())
|
||||
{
|
||||
mPositionGroup.setVec(0,0,0);
|
||||
mPositionGroup.splat(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1099,59 +1107,72 @@ void LLSpatialBridge::updateSpatialExtents()
|
||||
root->rebound();
|
||||
}
|
||||
|
||||
LLXformMatrix* mat = mDrawable->getXform();
|
||||
|
||||
LLVector3 offset = root->mBounds[0];
|
||||
LLVector3 size = root->mBounds[1];
|
||||
LLVector4a offset;
|
||||
LLVector4a size = root->mBounds[1];
|
||||
|
||||
LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix();
|
||||
LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix());
|
||||
|
||||
offset *= rotation;
|
||||
center += offset;
|
||||
|
||||
LLVector3 v[4];
|
||||
//get 4 corners of bounding box
|
||||
v[0] = (size * rotation);
|
||||
v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation);
|
||||
v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation);
|
||||
v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation);
|
||||
//VECTORIZE THIS
|
||||
LLMatrix4a mat;
|
||||
mat.loadu(mDrawable->getXform()->getWorldMatrix());
|
||||
|
||||
LLVector3& newMin = mExtents[0];
|
||||
LLVector3& newMax = mExtents[1];
|
||||
LLVector4a t;
|
||||
t.splat(0.f);
|
||||
|
||||
LLVector4a center;
|
||||
mat.affineTransform(t, center);
|
||||
|
||||
mat.rotate(root->mBounds[0], offset);
|
||||
center.add(offset);
|
||||
|
||||
LLVector4a v[4];
|
||||
|
||||
//get 4 corners of bounding box
|
||||
mat.rotate(size,v[0]);
|
||||
|
||||
LLVector4a scale;
|
||||
|
||||
scale.set(-1.f, -1.f, 1.f);
|
||||
scale.mul(size);
|
||||
mat.rotate(scale, v[1]);
|
||||
|
||||
scale.set(1.f, -1.f, -1.f);
|
||||
scale.mul(size);
|
||||
mat.rotate(scale, v[2]);
|
||||
|
||||
scale.set(-1.f, 1.f, -1.f);
|
||||
scale.mul(size);
|
||||
mat.rotate(scale, v[3]);
|
||||
|
||||
|
||||
LLVector4a& newMin = mExtents[0];
|
||||
LLVector4a& newMax = mExtents[1];
|
||||
|
||||
newMin = newMax = center;
|
||||
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
F32 delta = fabsf(v[i].mV[j]);
|
||||
F32 min = center.mV[j] - delta;
|
||||
F32 max = center.mV[j] + delta;
|
||||
|
||||
if (min < newMin.mV[j])
|
||||
{
|
||||
newMin.mV[j] = min;
|
||||
}
|
||||
|
||||
if (max > newMax.mV[j])
|
||||
{
|
||||
newMax.mV[j] = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
LLVector4a delta;
|
||||
delta.setAbs(v[i]);
|
||||
LLVector4a min;
|
||||
min.setSub(center, delta);
|
||||
LLVector4a max;
|
||||
max.setAdd(center, delta);
|
||||
|
||||
LLVector3 diagonal = newMax - newMin;
|
||||
mRadius = diagonal.magVec() * 0.5f;
|
||||
newMin.setMin(newMin, min);
|
||||
newMax.setMax(newMax, max);
|
||||
}
|
||||
|
||||
mPositionGroup.setVec((newMin + newMax) * 0.5f);
|
||||
LLVector4a diagonal;
|
||||
diagonal.setSub(newMax, newMin);
|
||||
mRadius = diagonal.getLength3().getF32() * 0.5f;
|
||||
|
||||
mPositionGroup.setAdd(newMin,newMax);
|
||||
mPositionGroup.mul(0.5f);
|
||||
updateBinRadius();
|
||||
}
|
||||
|
||||
void LLSpatialBridge::updateBinRadius()
|
||||
{
|
||||
mBinRadius = llmin((F32) mOctree->getSize().mdV[0]*0.5f, 256.f);
|
||||
mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f);
|
||||
}
|
||||
|
||||
LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
|
||||
@@ -1292,8 +1313,12 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
|
||||
group->rebound();
|
||||
|
||||
LLVector3 center = (mExtents[0] + mExtents[1]) * 0.5f;
|
||||
LLVector3 size = (mExtents[1]-mExtents[0]) * 0.5f;
|
||||
LLVector4a center;
|
||||
center.setAdd(mExtents[0], mExtents[1]);
|
||||
center.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(mExtents[1], mExtents[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) ||
|
||||
LLPipeline::sImpostorRender ||
|
||||
@@ -1397,6 +1422,7 @@ BOOL LLSpatialBridge::updateMove()
|
||||
llassert_always(mDrawable->getRegion());
|
||||
LLSpatialPartition* part = mDrawable->getRegion()->getSpatialPartition(mPartitionType);
|
||||
llassert_always(part);
|
||||
|
||||
mOctree->balance();
|
||||
if (part)
|
||||
{
|
||||
@@ -1405,11 +1431,11 @@ BOOL LLSpatialBridge::updateMove()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLSpatialBridge::shiftPos(const LLVector3& vec)
|
||||
void LLSpatialBridge::shiftPos(const LLVector4a& vec)
|
||||
{
|
||||
mExtents[0] += vec;
|
||||
mExtents[1] += vec;
|
||||
mPositionGroup += LLVector3d(vec);
|
||||
mExtents[0].add(vec);
|
||||
mExtents[1].add(vec);
|
||||
mPositionGroup.add(vec);
|
||||
}
|
||||
|
||||
void LLSpatialBridge::cleanupReferences()
|
||||
@@ -1527,7 +1553,7 @@ F32 LLHUDBridge::calcPixelArea(LLSpatialGroup* group, LLCamera& camera)
|
||||
}
|
||||
|
||||
|
||||
void LLHUDBridge::shiftPos(const LLVector3& vec)
|
||||
void LLHUDBridge::shiftPos(const LLVector4a& vec)
|
||||
{
|
||||
//don't shift hud bridges on region crossing
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "v4math.h"
|
||||
#include "m4math.h"
|
||||
#include "v4coloru.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llquaternion.h"
|
||||
#include "xform.h"
|
||||
#include "llmemtype.h"
|
||||
@@ -63,7 +64,6 @@ class LLViewerTexture;
|
||||
// Can have multiple silhouettes for each object
|
||||
const U32 SILHOUETTE_HIGHLIGHT = 0;
|
||||
|
||||
|
||||
// All data for new renderer goes into this class.
|
||||
class LLDrawable : public LLRefCount
|
||||
{
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
const LLVector3& getPosition() const { return mXform.getPosition(); }
|
||||
const LLVector3& getWorldPosition() const { return mXform.getPositionW(); }
|
||||
const LLVector3 getPositionAgent() const;
|
||||
const LLVector3d& getPositionGroup() const { return mPositionGroup; }
|
||||
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(); }
|
||||
@@ -168,7 +168,7 @@ public:
|
||||
|
||||
void updateSpecialHoverCursor(BOOL enabled);
|
||||
|
||||
virtual void shiftPos(const LLVector3 &shift_vector);
|
||||
virtual void shiftPos(const LLVector4a &shift_vector);
|
||||
|
||||
S32 getGeneration() const { return mGeneration; }
|
||||
|
||||
@@ -186,11 +186,12 @@ public:
|
||||
const LLVector3& getBounds(LLVector3& min, LLVector3& max) const;
|
||||
virtual void updateSpatialExtents();
|
||||
virtual void updateBinRadius();
|
||||
const LLVector3* getSpatialExtents() const;
|
||||
void setSpatialExtents(LLVector3 min, LLVector3 max);
|
||||
void setPositionGroup(const LLVector3d& pos);
|
||||
void setPositionGroup(const LLVector3& pos) { setPositionGroup(LLVector3d(pos)); }
|
||||
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; }
|
||||
S32 getRenderType() { return mRenderType; }
|
||||
@@ -282,6 +283,11 @@ public:
|
||||
PARTITION_MOVE = 0x10000000,
|
||||
} EDrawableFlags;
|
||||
|
||||
private: //aligned members
|
||||
LLVector4a mExtents[2];
|
||||
LLVector4a mPositionGroup;
|
||||
|
||||
public:
|
||||
LLXformMatrix mXform;
|
||||
|
||||
// vis data
|
||||
@@ -293,7 +299,7 @@ public:
|
||||
|
||||
static S32 getCurrentFrame() { return sCurVisible; }
|
||||
static S32 getMinVisFrameRange();
|
||||
|
||||
|
||||
void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
|
||||
LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
|
||||
|
||||
@@ -311,8 +317,6 @@ private:
|
||||
|
||||
mutable U32 mVisible;
|
||||
F32 mRadius;
|
||||
LLVector3 mExtents[2];
|
||||
LLVector3d mPositionGroup;
|
||||
F32 mBinRadius;
|
||||
S32 mGeneration;
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "llviewercontrol.h"
|
||||
#include "llvolume.h"
|
||||
#include "m3math.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "v3color.h"
|
||||
|
||||
#include "lldrawpoolbump.h"
|
||||
@@ -73,35 +74,43 @@ The resulting texture coordinate <u,v> is:
|
||||
u = 2(B dot P)
|
||||
v = 2(T dot P)
|
||||
*/
|
||||
void planarProjection(LLVector2 &tc, const LLVector3& normal,
|
||||
const LLVector3 &mCenter, const LLVector3& vec)
|
||||
{ //DONE!
|
||||
LLVector3 binormal;
|
||||
float d = normal * LLVector3(1,0,0);
|
||||
void planarProjection(LLVector2 &tc, const LLVector4a& normal,
|
||||
const LLVector4a ¢er, const LLVector4a& vec)
|
||||
{
|
||||
LLVector4a binormal;
|
||||
F32 d = normal[0];
|
||||
|
||||
if (d >= 0.5f || d <= -0.5f)
|
||||
{
|
||||
binormal = LLVector3(0,1,0);
|
||||
if (normal.mV[0] < 0)
|
||||
if (d < 0)
|
||||
{
|
||||
binormal = -binormal;
|
||||
binormal.set(0,-1,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
binormal.set(0, 1, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
binormal = LLVector3(1,0,0);
|
||||
if (normal.mV[1] > 0)
|
||||
if (normal[1] > 0)
|
||||
{
|
||||
binormal = -binormal;
|
||||
binormal.set(-1,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
binormal.set(1,0,0);
|
||||
}
|
||||
}
|
||||
LLVector3 tangent = binormal % normal;
|
||||
LLVector4a tangent;
|
||||
tangent.setCross3(binormal,normal);
|
||||
|
||||
tc.mV[1] = -((tangent*vec)*2 - 0.5f);
|
||||
tc.mV[0] = 1.0f+((binormal*vec)*2 - 0.5f);
|
||||
tc.mV[1] = -((tangent.dot3(vec).getF32())*2 - 0.5f);
|
||||
tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f);
|
||||
}
|
||||
|
||||
void sphericalProjection(LLVector2 &tc, const LLVector3& normal,
|
||||
const LLVector3 &mCenter, const LLVector3& vec)
|
||||
void sphericalProjection(LLVector2 &tc, const LLVector4a& normal,
|
||||
const LLVector4a &mCenter, const LLVector4a& vec)
|
||||
{ //BROKEN
|
||||
/*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f;
|
||||
|
||||
@@ -112,7 +121,7 @@ void sphericalProjection(LLVector2 &tc, const LLVector3& normal,
|
||||
}*/
|
||||
}
|
||||
|
||||
void cylindricalProjection(LLVector2 &tc, const LLVector3& normal, const LLVector3 &mCenter, const LLVector3& vec)
|
||||
void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec)
|
||||
{ //BROKEN
|
||||
/*LLVector3 binormal;
|
||||
float d = vd.mNormal * LLVector3(1,0,0);
|
||||
@@ -687,96 +696,148 @@ static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 of
|
||||
}
|
||||
|
||||
|
||||
bool less_than_max_mag(const LLVector4a& vec)
|
||||
{
|
||||
LLVector4a MAX_MAG;
|
||||
MAX_MAG.splat(1024.f*1024.f);
|
||||
|
||||
LLVector4a val;
|
||||
val.setAbs(vec);
|
||||
|
||||
S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7;
|
||||
|
||||
return lt == 0x7;
|
||||
}
|
||||
|
||||
BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
|
||||
const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, BOOL global_volume)
|
||||
const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume)
|
||||
{
|
||||
LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
|
||||
|
||||
//get bounding box
|
||||
if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
|
||||
{
|
||||
//VECTORIZE THIS
|
||||
LLMatrix4a mat_vert;
|
||||
mat_vert.loadu(mat_vert_in);
|
||||
|
||||
LLMatrix4a mat_normal;
|
||||
mat_normal.loadu(mat_normal_in);
|
||||
|
||||
//if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
|
||||
//{ //vertex buffer no longer valid
|
||||
// mVertexBuffer = NULL;
|
||||
// mLastVertexBuffer = NULL;
|
||||
//}
|
||||
|
||||
LLVector3 min,max;
|
||||
//VECTORIZE THIS
|
||||
LLVector4a min,max;
|
||||
|
||||
if (f >= volume.getNumVolumeFaces())
|
||||
{
|
||||
min = LLVector3(-1,-1,-1);
|
||||
max = LLVector3(1,1,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const LLVolumeFace &face = volume.getVolumeFace(f);
|
||||
min = face.mExtents[0];
|
||||
max = face.mExtents[1];
|
||||
llwarns << "Generating bounding box for invalid face index!" << llendl;
|
||||
f = 0;
|
||||
}
|
||||
|
||||
const LLVolumeFace &face = volume.getVolumeFace(f);
|
||||
min = face.mExtents[0];
|
||||
max = face.mExtents[1];
|
||||
|
||||
llassert(less_than_max_mag(min));
|
||||
llassert(less_than_max_mag(max));
|
||||
|
||||
//min, max are in volume space, convert to drawable render space
|
||||
LLVector3 center = ((min + max) * 0.5f)*mat_vert;
|
||||
LLVector3 size = ((max-min) * 0.5f);
|
||||
LLVector4a center;
|
||||
LLVector4a t;
|
||||
t.setAdd(min, max);
|
||||
t.mul(0.5f);
|
||||
mat_vert.affineTransform(t, center);
|
||||
LLVector4a size;
|
||||
size.setSub(max, min);
|
||||
size.mul(0.5f);
|
||||
|
||||
llassert(less_than_max_mag(min));
|
||||
llassert(less_than_max_mag(max));
|
||||
|
||||
if (!global_volume)
|
||||
{
|
||||
size.scaleVec(mDrawablep->getVObj()->getScale());
|
||||
//VECTORIZE THIS
|
||||
LLVector4a scale;
|
||||
scale.load3(mDrawablep->getVObj()->getScale().mV);
|
||||
size.mul(scale);
|
||||
}
|
||||
|
||||
LLMatrix3 mat = mat_normal;
|
||||
LLVector3 x = mat.getFwdRow();
|
||||
LLVector3 y = mat.getLeftRow();
|
||||
LLVector3 z = mat.getUpRow();
|
||||
x.normVec();
|
||||
y.normVec();
|
||||
z.normVec();
|
||||
|
||||
mat.setRows(x,y,z);
|
||||
|
||||
LLQuaternion rotation = LLQuaternion(mat);
|
||||
mat_normal.mMatrix[0].normalize3fast();
|
||||
mat_normal.mMatrix[1].normalize3fast();
|
||||
mat_normal.mMatrix[2].normalize3fast();
|
||||
|
||||
LLVector3 v[4];
|
||||
//get 4 corners of bounding box
|
||||
v[0] = (size * rotation);
|
||||
v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation);
|
||||
v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation);
|
||||
v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation);
|
||||
LLVector4a v[4];
|
||||
|
||||
LLVector3& newMin = mExtents[0];
|
||||
LLVector3& newMax = mExtents[1];
|
||||
//get 4 corners of bounding box
|
||||
mat_normal.rotate(size,v[0]);
|
||||
|
||||
//VECTORIZE THIS
|
||||
LLVector4a scale;
|
||||
|
||||
scale.set(-1.f, -1.f, 1.f);
|
||||
scale.mul(size);
|
||||
mat_normal.rotate(scale, v[1]);
|
||||
|
||||
scale.set(1.f, -1.f, -1.f);
|
||||
scale.mul(size);
|
||||
mat_normal.rotate(scale, v[2]);
|
||||
|
||||
scale.set(-1.f, 1.f, -1.f);
|
||||
scale.mul(size);
|
||||
mat_normal.rotate(scale, v[3]);
|
||||
|
||||
LLVector4a& newMin = mExtents[0];
|
||||
LLVector4a& newMax = mExtents[1];
|
||||
|
||||
newMin = newMax = center;
|
||||
|
||||
llassert(less_than_max_mag(center));
|
||||
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
F32 delta = fabsf(v[i].mV[j]);
|
||||
F32 min = center.mV[j] - delta;
|
||||
F32 max = center.mV[j] + delta;
|
||||
|
||||
if (min < newMin.mV[j])
|
||||
{
|
||||
newMin.mV[j] = min;
|
||||
}
|
||||
|
||||
if (max > newMax.mV[j])
|
||||
{
|
||||
newMax.mV[j] = max;
|
||||
}
|
||||
}
|
||||
LLVector4a delta;
|
||||
delta.setAbs(v[i]);
|
||||
LLVector4a min;
|
||||
min.setSub(center, delta);
|
||||
LLVector4a max;
|
||||
max.setAdd(center, delta);
|
||||
|
||||
newMin.setMin(newMin,min);
|
||||
newMax.setMax(newMax,max);
|
||||
|
||||
llassert(less_than_max_mag(newMin));
|
||||
llassert(less_than_max_mag(newMax));
|
||||
}
|
||||
|
||||
if (!mDrawablep->isActive())
|
||||
{
|
||||
LLVector3 offset = mDrawablep->getRegion()->getOriginAgent();
|
||||
newMin += offset;
|
||||
newMax += offset;
|
||||
LLVector4a offset;
|
||||
offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);
|
||||
newMin.add(offset);
|
||||
newMax.add(offset);
|
||||
|
||||
llassert(less_than_max_mag(newMin));
|
||||
llassert(less_than_max_mag(newMax));
|
||||
}
|
||||
|
||||
mCenterLocal = (newMin+newMax)*0.5f;
|
||||
LLVector3 tmp = (newMin - newMax) ;
|
||||
mBoundingSphereRadius = tmp.length() * 0.5f ;
|
||||
t.setAdd(newMin, newMax);
|
||||
t.mul(0.5f);
|
||||
|
||||
llassert(less_than_max_mag(t));
|
||||
|
||||
//VECTORIZE THIS
|
||||
mCenterLocal.set(t.getF32ptr());
|
||||
|
||||
llassert(less_than_max_mag(newMin));
|
||||
llassert(less_than_max_mag(newMax));
|
||||
|
||||
t.setSub(newMax,newMin);
|
||||
mBoundingSphereRadius = t.getLength3().getF32()*0.5f;
|
||||
|
||||
updateCenterAgent();
|
||||
}
|
||||
@@ -803,18 +864,26 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,
|
||||
return surface_coord;
|
||||
}
|
||||
|
||||
//VECTORIZE THIS
|
||||
// see if we have a non-default mapping
|
||||
U8 texgen = getTextureEntry()->getTexGen();
|
||||
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
|
||||
{
|
||||
LLVector3 center = mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter;
|
||||
LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);
|
||||
|
||||
LLVector3 scale = (mDrawablep->getVOVolume()->isVolumeGlobal()) ? LLVector3(1,1,1) : mVObjp->getScale();
|
||||
LLVector3 volume_position = mDrawablep->getVOVolume()->agentPositionToVolume(position);
|
||||
volume_position.scaleVec(scale);
|
||||
LLVector4a volume_position;
|
||||
volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV);
|
||||
|
||||
LLVector3 volume_normal = mDrawablep->getVOVolume()->agentDirectionToVolume(normal);
|
||||
volume_normal.normalize();
|
||||
if (!mDrawablep->getVOVolume()->isVolumeGlobal())
|
||||
{
|
||||
LLVector4a scale;
|
||||
scale.load3(mVObjp->getScale().mV);
|
||||
volume_position.mul(scale);
|
||||
}
|
||||
|
||||
LLVector4a volume_normal;
|
||||
volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV);
|
||||
volume_normal.normalize3fast();
|
||||
|
||||
switch (texgen)
|
||||
{
|
||||
@@ -855,17 +924,23 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po
|
||||
{
|
||||
const LLMatrix4& vol_mat = getWorldMatrix();
|
||||
const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
|
||||
LLVector3 normal = vf.mVertices[0].mNormal;
|
||||
LLVector3 binormal = vf.mVertices[0].mBinormal;
|
||||
LLVector4a normal4a;
|
||||
normal4a.load3(vf.mVertices[0].mNormal.mV);
|
||||
LLVector4a binormal4a;
|
||||
binormal4a.load3(vf.mVertices[0].mNormal.mV);
|
||||
LLVector2 projected_binormal;
|
||||
planarProjection(projected_binormal, normal, vf.mCenter, binormal);
|
||||
planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);
|
||||
projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform()
|
||||
*scale = projected_binormal.length();
|
||||
// rotate binormal to match what planarProjection() thinks it is,
|
||||
// then find face's rotation from normal and rotated binormal:
|
||||
// then find rotation from that:
|
||||
projected_binormal.normalize();
|
||||
F32 ang = acos(projected_binormal.mV[VY]);
|
||||
ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang;
|
||||
|
||||
//VECTORIZE THIS
|
||||
LLVector3 binormal(binormal4a.getF32ptr());
|
||||
LLVector3 normal(normal4a.getF32ptr());
|
||||
binormal.rotVec(ang, normal);
|
||||
LLQuaternion local_rot( binormal % normal, binormal, normal );
|
||||
*face_rot = local_rot * vol_mat.quaternion();
|
||||
@@ -967,7 +1042,8 @@ bool LLFace::canRenderAsMask()
|
||||
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
const S32 &f,
|
||||
const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,
|
||||
const U16 &index_offset)
|
||||
const U16 &index_offset,
|
||||
bool force_rebuild)
|
||||
{
|
||||
llassert(verify());
|
||||
const LLVolumeFace &vf = volume.getVolumeFace(f);
|
||||
@@ -1220,6 +1296,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
mVObjp->getVolume()->genBinormals(f);
|
||||
}
|
||||
|
||||
LLVector4a scalea;
|
||||
scalea.load3(scale.mV);
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
if (rebuild_tcoord)
|
||||
@@ -1228,20 +1307,22 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
|
||||
{
|
||||
LLVector3 vec = vf.mVertices[i].mPosition;
|
||||
|
||||
vec.scaleVec(scale);
|
||||
LLVector4a vec;
|
||||
vec.load3(vf.mVertices[i].mPosition.mV);
|
||||
vec.mul(scalea);
|
||||
LLVector4a norm;
|
||||
norm.load3(vf.mVertices[i].mNormal.mV);
|
||||
|
||||
switch (texgen)
|
||||
{
|
||||
case LLTextureEntry::TEX_GEN_PLANAR:
|
||||
planarProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec);
|
||||
planarProjection(tc, norm, *(vf.mCenter), vec);
|
||||
break;
|
||||
case LLTextureEntry::TEX_GEN_SPHERICAL:
|
||||
sphericalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec);
|
||||
sphericalProjection(tc, norm, *(vf.mCenter), vec);
|
||||
break;
|
||||
case LLTextureEntry::TEX_GEN_CYLINDRICAL:
|
||||
cylindricalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec);
|
||||
cylindricalProjection(tc, norm, *(vf.mCenter), vec);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1386,20 +1467,32 @@ F32 LLFace::getTextureVirtualSize()
|
||||
|
||||
BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
|
||||
{
|
||||
//VECTORIZE THIS
|
||||
//get area of circle around face
|
||||
LLVector3 center = getPositionAgent();
|
||||
LLVector3 size = (mExtents[1] - mExtents[0]) * 0.5f;
|
||||
LLVector4a center;
|
||||
center.load3(getPositionAgent().mV);
|
||||
LLVector4a size;
|
||||
size.setSub(mExtents[1], mExtents[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||
|
||||
F32 size_squared = size.lengthSquared() ;
|
||||
LLVector3 lookAt = center - camera->getOrigin();
|
||||
F32 dist = lookAt.normVec() ;
|
||||
|
||||
F32 size_squared = size.dot3(size).getF32();
|
||||
LLVector4a lookAt;
|
||||
LLVector4a t;
|
||||
t.load3(camera->getOrigin().mV);
|
||||
lookAt.setSub(center, t);
|
||||
F32 dist = lookAt.getLength3().getF32();
|
||||
dist = llmax(dist-size.getLength3().getF32(), 0.f);
|
||||
lookAt.normalize3fast() ;
|
||||
|
||||
//get area of circle around node
|
||||
F32 app_angle = atanf(fsqrtf(size_squared) / dist);
|
||||
F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
|
||||
radius = app_angle*LLDrawable::sCurPixelAngle;
|
||||
mPixelArea = radius*radius * 3.14159f;
|
||||
cos_angle_to_view_dir = lookAt * camera->getXAxis();
|
||||
LLVector4a x_axis;
|
||||
x_axis.load3(camera->getXAxis().mV);
|
||||
cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32();
|
||||
|
||||
if(dist < mBoundingSphereRadius) //camera is very close
|
||||
{
|
||||
|
||||
@@ -159,7 +159,8 @@ public:
|
||||
BOOL getGeometryVolume(const LLVolume& volume,
|
||||
const S32 &f,
|
||||
const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,
|
||||
const U16 &index_offset);
|
||||
const U16 &index_offset,
|
||||
bool force_rebuild = false);
|
||||
|
||||
// For avatar
|
||||
U16 getGeometryAvatar(
|
||||
@@ -211,6 +212,8 @@ public:
|
||||
void setVertexBuffer(LLVertexBuffer* buffer);
|
||||
void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL
|
||||
LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; }
|
||||
public: //aligned members
|
||||
LLVector4a mExtents[2];
|
||||
|
||||
private:
|
||||
F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );
|
||||
@@ -223,7 +226,6 @@ public:
|
||||
|
||||
LLVector3 mCenterLocal;
|
||||
LLVector3 mCenterAgent;
|
||||
LLVector3 mExtents[2];
|
||||
LLVector2 mTexExtents[2];
|
||||
F32 mDistance;
|
||||
F32 mLastUpdateTime;
|
||||
|
||||
@@ -94,11 +94,13 @@ void LLVolumeImplFlexible::onParameterChanged(U16 param_type, LLNetworkData *dat
|
||||
}
|
||||
}
|
||||
|
||||
void LLVolumeImplFlexible::onShift(const LLVector3 &shift_vector)
|
||||
void LLVolumeImplFlexible::onShift(const LLVector4a &shift_vector)
|
||||
{
|
||||
//VECTORIZE THIS
|
||||
LLVector3 shift(shift_vector.getF32ptr());
|
||||
for (int section = 0; section < (1<<FLEXIBLE_OBJECT_MAX_SECTIONS)+1; ++section)
|
||||
{
|
||||
mSection[section].mPosition += shift_vector;
|
||||
mSection[section].mPosition += shift;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +196,6 @@ void LLVolumeImplFlexible::remapSections(LLFlexibleObjectSection *source, S32 so
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLVolumeImplFlexible::setAttributesOfAllSections(LLVector3* inScale)
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface
|
||||
void onSetVolume(const LLVolumeParams &volume_params, const S32 detail);
|
||||
void onSetScale(const LLVector3 &scale, BOOL damped);
|
||||
void onParameterChanged(U16 param_type, LLNetworkData *data, BOOL in_use, bool local_origin);
|
||||
void onShift(const LLVector3 &shift_vector);
|
||||
void onShift(const LLVector4a &shift_vector);
|
||||
bool isVolumeUnique() const { return true; }
|
||||
bool isVolumeGlobal() const { return true; }
|
||||
bool isActive() const { return true; }
|
||||
|
||||
@@ -275,8 +275,10 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
|
||||
F32 t = 0.f;
|
||||
LLVector3 dir = end-start;
|
||||
|
||||
if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, NULL, NULL, &t, FALSE) ||
|
||||
LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, NULL, NULL, &t, FALSE))
|
||||
F32 a,b;
|
||||
|
||||
if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, a, b, t, FALSE) ||
|
||||
LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, a, b, t, FALSE))
|
||||
{
|
||||
if (intersection)
|
||||
{
|
||||
|
||||
@@ -215,8 +215,9 @@ BOOL LLHUDText::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
|
||||
LLVector3 dir = end-start;
|
||||
F32 t = 0.f;
|
||||
|
||||
if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, NULL, NULL, &t, FALSE) ||
|
||||
LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, NULL, NULL, &t, FALSE) )
|
||||
F32 a, b;
|
||||
if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
|
||||
LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
|
||||
{
|
||||
if (t <= 1.f)
|
||||
{
|
||||
|
||||
@@ -301,7 +301,7 @@ void LLPanelMediaHUD::updateShape()
|
||||
{
|
||||
const LLVolumeFace& vf = volume->getVolumeFace(nodep->getLastSelectedTE());
|
||||
|
||||
const LLVector3* ext = vf.mExtents;
|
||||
const LLVector3* ext = (LLVector3*)vf.mExtents->getF32ptr();
|
||||
|
||||
LLVector3 center = (ext[0]+ext[1])*0.5f;
|
||||
LLVector3 size = (ext[1]-ext[0])*0.5f;
|
||||
|
||||
@@ -1215,8 +1215,8 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
|
||||
mGridRotation = first_grid_object->getRenderRotation();
|
||||
LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition();
|
||||
|
||||
LLVector3 min_extents(F32_MAX, F32_MAX, F32_MAX);
|
||||
LLVector3 max_extents(-F32_MAX, -F32_MAX, -F32_MAX);
|
||||
LLVector4a min_extents(F32_MAX);
|
||||
LLVector4a max_extents(-F32_MAX);
|
||||
BOOL grid_changed = FALSE;
|
||||
for (LLObjectSelection::iterator iter = mGridObjects.begin();
|
||||
iter != mGridObjects.end(); ++iter)
|
||||
@@ -1225,7 +1225,7 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
|
||||
LLDrawable* drawable = object->mDrawable;
|
||||
if (drawable)
|
||||
{
|
||||
const LLVector3* ext = drawable->getSpatialExtents();
|
||||
const LLVector4a* ext = drawable->getSpatialExtents();
|
||||
update_min_max(min_extents, max_extents, ext[0]);
|
||||
update_min_max(min_extents, max_extents, ext[1]);
|
||||
grid_changed = TRUE;
|
||||
@@ -1233,13 +1233,19 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
|
||||
}
|
||||
if (grid_changed)
|
||||
{
|
||||
mGridOrigin = lerp(min_extents, max_extents, 0.5f);
|
||||
LLVector4a center, size;
|
||||
center.setAdd(min_extents, max_extents);
|
||||
center.mul(0.5f);
|
||||
size.setSub(max_extents, min_extents);
|
||||
size.mul(0.5f);
|
||||
|
||||
mGridOrigin.set(center.getF32ptr());
|
||||
LLDrawable* drawable = first_grid_object->mDrawable;
|
||||
if (drawable && drawable->isActive())
|
||||
{
|
||||
mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix();
|
||||
}
|
||||
mGridScale = (max_extents - min_extents) * 0.5f;
|
||||
mGridScale.set(size.getF32ptr());
|
||||
}
|
||||
}
|
||||
else // GRID_MODE_WORLD or just plain default
|
||||
|
||||
@@ -166,6 +166,55 @@ S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVe
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
b000 = 0x00,
|
||||
@@ -183,42 +232,41 @@ typedef enum
|
||||
//gives you a triangle fan index array
|
||||
static U8 sOcclusionIndices[] =
|
||||
{
|
||||
// 000
|
||||
//000
|
||||
b111, b110, b010, b011, b001, b101, b100, b110,
|
||||
//001
|
||||
b110, b000, b010, b011, b111, b101, b100, b000,
|
||||
//001
|
||||
b011, b010, b000, b001, b101, b111, b110, b010,
|
||||
//010
|
||||
b101, b100, b110, b111, b011, b001, b000, b100,
|
||||
//011
|
||||
b100, b010, b110, b111, b101, b001, b000, b010,
|
||||
//100
|
||||
b011, b010, b000, b001, b101, b111, b110, b010,
|
||||
b001, b000, b100, b101, b111, b011, b010, b000,
|
||||
//100
|
||||
b110, b000, b010, b011, b111, b101, b100, b000,
|
||||
//101
|
||||
b010, b100, b000, b001, b011, b111, b110, b100,
|
||||
//110
|
||||
b001, b000, b100, b101, b111, b011, b010, b000,
|
||||
b100, b010, b110, b111, b101, b001, b000, b010,
|
||||
//111
|
||||
b000, b110, b100, b101, b001, b011, b010, b110,
|
||||
};
|
||||
|
||||
U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector3& center)
|
||||
U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
|
||||
{
|
||||
LLVector3 d = center - camera->getOrigin();
|
||||
LLVector4a origin;
|
||||
origin.load3(camera->getOrigin().mV);
|
||||
|
||||
U8 cypher = 0;
|
||||
if (d.mV[0] > 0)
|
||||
{
|
||||
cypher |= b100;
|
||||
}
|
||||
if (d.mV[1] > 0)
|
||||
{
|
||||
cypher |= b010;
|
||||
}
|
||||
if (d.mV[2] > 0)
|
||||
{
|
||||
cypher |= b001;
|
||||
}
|
||||
S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
|
||||
|
||||
return cypher*8;
|
||||
}
|
||||
|
||||
U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
|
||||
{
|
||||
LLVector4a origin;
|
||||
origin.load3(camera->getOrigin().mV);
|
||||
|
||||
S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
|
||||
|
||||
return sOcclusionIndices+cypher*8;
|
||||
}
|
||||
|
||||
@@ -229,15 +277,18 @@ void LLSpatialGroup::buildOcclusion()
|
||||
mOcclusionVerts = new F32[8*3];
|
||||
}
|
||||
|
||||
LLVector3 r = mBounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE);
|
||||
LLVector3 bounds[2];
|
||||
bounds[0].set(mBounds[0].getF32ptr());
|
||||
bounds[1].set(mBounds[1].getF32ptr());
|
||||
LLVector3 r = bounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE);
|
||||
|
||||
for (U32 k = 0; k < 3; k++)
|
||||
{
|
||||
r.mV[k] = llmin(mBounds[1].mV[k]+0.25f, r.mV[k]);
|
||||
r.mV[k] = llmin(bounds[1].mV[k]+0.25f, r.mV[k]);
|
||||
}
|
||||
|
||||
F32* v = mOcclusionVerts;
|
||||
F32* c = mBounds[0].mV;
|
||||
F32* c = bounds[0].mV;
|
||||
F32* s = r.mV;
|
||||
|
||||
//vertex positions are encoded so the 3 bits of their vertex index
|
||||
@@ -352,8 +403,10 @@ void LLSpatialGroup::validate()
|
||||
sg_assert(!isState(DIRTY));
|
||||
sg_assert(!isDead());
|
||||
|
||||
LLVector3 myMin = mBounds[0] - mBounds[1];
|
||||
LLVector3 myMax = mBounds[0] + mBounds[1];
|
||||
LLVector4a myMin;
|
||||
myMin.setSub(mBounds[0], mBounds[1]);
|
||||
LLVector4a myMax;
|
||||
myMax.setAdd(mBounds[0], mBounds[1]);
|
||||
|
||||
validateDrawMap();
|
||||
|
||||
@@ -385,16 +438,18 @@ void LLSpatialGroup::validate()
|
||||
group->validate();
|
||||
|
||||
//ensure all children are enclosed in this node
|
||||
LLVector3 center = group->mBounds[0];
|
||||
LLVector3 size = group->mBounds[1];
|
||||
LLVector4a center = group->mBounds[0];
|
||||
LLVector4a size = group->mBounds[1];
|
||||
|
||||
LLVector3 min = center - size;
|
||||
LLVector3 max = center + size;
|
||||
LLVector4a min;
|
||||
min.setSub(center, size);
|
||||
LLVector4a max;
|
||||
max.setAdd(center, size);
|
||||
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
sg_assert(min.mV[j] >= myMin.mV[j]-0.02f);
|
||||
sg_assert(max.mV[j] <= myMax.mV[j]+0.02f);
|
||||
sg_assert(min[j] >= myMin[j]-0.02f);
|
||||
sg_assert(max[j] <= myMax[j]+0.02f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +537,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
|
||||
|
||||
if (mOctreeNode->isInside(drawablep->getPositionGroup()) &&
|
||||
(mOctreeNode->contains(drawablep) ||
|
||||
(drawablep->getBinRadius() > mOctreeNode->getSize().mdV[0] &&
|
||||
(drawablep->getBinRadius() > mOctreeNode->getSize()[0] &&
|
||||
parent && parent->getElementCount() >= gOctreeMaxCapacity)))
|
||||
{
|
||||
unbound();
|
||||
@@ -604,7 +659,7 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group)
|
||||
|
||||
}
|
||||
|
||||
BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut)
|
||||
BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut)
|
||||
{
|
||||
const OctreeNode* node = mOctreeNode;
|
||||
|
||||
@@ -617,8 +672,8 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLVector3& newMin = mObjectExtents[0];
|
||||
LLVector3& newMax = mObjectExtents[1];
|
||||
LLVector4a& newMin = mObjectExtents[0];
|
||||
LLVector4a& newMax = mObjectExtents[1];
|
||||
|
||||
if (isState(OBJECT_DIRTY))
|
||||
{ //calculate new bounding box
|
||||
@@ -627,10 +682,10 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO
|
||||
//initialize bounding box to first element
|
||||
OctreeNode::const_element_iter i = node->getData().begin();
|
||||
LLDrawable* drawablep = *i;
|
||||
const LLVector3* minMax = drawablep->getSpatialExtents();
|
||||
const LLVector4a* minMax = drawablep->getSpatialExtents();
|
||||
|
||||
newMin.setVec(minMax[0]);
|
||||
newMax.setVec(minMax[1]);
|
||||
newMin = minMax[0];
|
||||
newMax = minMax[1];
|
||||
|
||||
for (++i; i != node->getData().end(); ++i)
|
||||
{
|
||||
@@ -654,8 +709,10 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO
|
||||
}*/
|
||||
}
|
||||
|
||||
mObjectBounds[0] = (newMin + newMax) * 0.5f;
|
||||
mObjectBounds[1] = (newMax - newMin) * 0.5f;
|
||||
mObjectBounds[0].setAdd(newMin, newMax);
|
||||
mObjectBounds[0].mul(0.5f);
|
||||
mObjectBounds[1].setSub(newMax, newMin);
|
||||
mObjectBounds[1].mul(0.5f);
|
||||
}
|
||||
|
||||
if (empty)
|
||||
@@ -665,17 +722,8 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO
|
||||
}
|
||||
else
|
||||
{
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (newMin.mV[i] < minOut.mV[i])
|
||||
{
|
||||
minOut.mV[i] = newMin.mV[i];
|
||||
}
|
||||
if (newMax.mV[i] > maxOut.mV[i])
|
||||
{
|
||||
maxOut.mV[i] = newMax.mV[i];
|
||||
}
|
||||
}
|
||||
minOut.setMin(minOut, newMin);
|
||||
maxOut.setMax(maxOut, newMax);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -766,18 +814,19 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLSpatialGroup::shift(const LLVector3 &offset)
|
||||
void LLSpatialGroup::shift(const LLVector4a &offset)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
|
||||
LLVector3d offsetd(offset);
|
||||
mOctreeNode->setCenter(mOctreeNode->getCenter()+offsetd);
|
||||
LLVector4a t = mOctreeNode->getCenter();
|
||||
t.add(offset);
|
||||
mOctreeNode->setCenter(t);
|
||||
mOctreeNode->updateMinMax();
|
||||
mBounds[0] += offset;
|
||||
mExtents[0] += offset;
|
||||
mExtents[1] += offset;
|
||||
mObjectBounds[0] += offset;
|
||||
mObjectExtents[0] += offset;
|
||||
mObjectExtents[1] += offset;
|
||||
mBounds[0].add(offset);
|
||||
mExtents[0].add(offset);
|
||||
mExtents[1].add(offset);
|
||||
mObjectBounds[0].add(offset);
|
||||
mObjectExtents[0].add(offset);
|
||||
mObjectExtents[1].add(offset);
|
||||
|
||||
//if (!mSpatialPartition->mRenderByGroup)
|
||||
{
|
||||
@@ -788,13 +837,6 @@ void LLSpatialGroup::shift(const LLVector3 &offset)
|
||||
if (mOcclusionVerts)
|
||||
{
|
||||
setState(OCCLUSION_DIRTY);
|
||||
/*for (U32 i = 0; i < 8; i++)
|
||||
{
|
||||
F32* v = mOcclusionVerts+i*3;
|
||||
v[0] += offset.mV[0];
|
||||
v[1] += offset.mV[1];
|
||||
v[2] += offset.mV[2];
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1085,6 +1127,8 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
|
||||
sNodeCount++;
|
||||
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
|
||||
|
||||
mViewAngle.splat(0.f);
|
||||
mLastUpdateViewAngle.splat(-1.f);
|
||||
mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[1] =
|
||||
mObjectExtents[0] = mObjectExtents[1] = mViewAngle;
|
||||
|
||||
@@ -1093,12 +1137,12 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
|
||||
setState(SG_INITIAL_STATE_MASK);
|
||||
gPipeline.markRebuild(this, TRUE);
|
||||
|
||||
mBounds[0] = LLVector3(node->getCenter());
|
||||
mBounds[1] = LLVector3(node->getSize());
|
||||
mBounds[0] = node->getCenter();
|
||||
mBounds[1] = node->getSize();
|
||||
|
||||
part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod;
|
||||
mLODHash = part->mLODSeed;
|
||||
|
||||
|
||||
OctreeNode* oct_parent = node->getOctParent();
|
||||
|
||||
LLSpatialGroup* parent = oct_parent ? (LLSpatialGroup*) oct_parent->getListener(0) : NULL;
|
||||
@@ -1109,6 +1153,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
|
||||
mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0;
|
||||
mVisible[i] = 0;
|
||||
}
|
||||
|
||||
mOcclusionVerts = NULL;
|
||||
|
||||
mRadius = 1;
|
||||
@@ -1119,7 +1164,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
|
||||
{
|
||||
if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
llwarns << "Attempted to update distance for camera other than world camera!" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
@@ -1130,8 +1176,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
|
||||
#endif
|
||||
if (!getData().empty() /*&& !LLSpatialPartition::sFreezeState*/)
|
||||
{
|
||||
mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() :
|
||||
(F32) mOctreeNode->getSize().magVec();
|
||||
mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() :
|
||||
(F32) mOctreeNode->getSize().getLength3().getF32();
|
||||
mDistance = mSpatialPartition->calcDistance(this, camera);
|
||||
mPixelArea = mSpatialPartition->calcPixelArea(this, camera);
|
||||
}
|
||||
@@ -1139,24 +1185,31 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
|
||||
|
||||
F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)
|
||||
{
|
||||
LLVector3 eye = group->mObjectBounds[0] - camera.getOrigin();
|
||||
LLVector4a eye;
|
||||
LLVector4a origin;
|
||||
origin.load3(camera.getOrigin().mV);
|
||||
|
||||
eye.setSub(group->mObjectBounds[0], origin);
|
||||
|
||||
F32 dist = 0.f;
|
||||
|
||||
if (group->mDrawMap.find(LLRenderPass::PASS_ALPHA) != group->mDrawMap.end())
|
||||
{
|
||||
LLVector3 v = eye;
|
||||
dist = eye.normVec();
|
||||
LLVector4a v = eye;
|
||||
|
||||
dist = eye.getLength3().getF32();
|
||||
eye.normalize3fast();
|
||||
|
||||
if (!group->isState(LLSpatialGroup::ALPHA_DIRTY))
|
||||
{
|
||||
if (!group->mSpatialPartition->isBridge())
|
||||
{
|
||||
LLVector3 view_angle = eye;/*LLVector3(eye * LLVector3(1,0,0), //WTF is this?
|
||||
eye * LLVector3(0,1,0),
|
||||
eye * LLVector3(0,0,1));*/
|
||||
LLVector4a view_angle = eye;
|
||||
|
||||
if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f)
|
||||
LLVector4a diff;
|
||||
diff.setSub(view_angle, group->mLastUpdateViewAngle);
|
||||
|
||||
if (diff.getLength3().getF32() > 0.64f)
|
||||
{
|
||||
group->mViewAngle = view_angle;
|
||||
group->mLastUpdateViewAngle = view_angle;
|
||||
@@ -1173,17 +1226,20 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)
|
||||
|
||||
LLVector3 at = camera.getAtAxis();
|
||||
|
||||
//front of bounding box
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
{
|
||||
v.mV[i] -= group->mObjectBounds[1].mV[i]*0.25f * at.mV[i];
|
||||
}
|
||||
LLVector4a ata;
|
||||
ata.load3(at.mV);
|
||||
|
||||
group->mDepth = v * at;
|
||||
LLVector4a t = ata;
|
||||
//front of bounding box
|
||||
t.mul(0.25f);
|
||||
t.mul(group->mObjectBounds[1]);
|
||||
v.sub(t);
|
||||
|
||||
group->mDepth = v.dot3(ata).getF32();
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = eye.magVec();
|
||||
dist = eye.getLength3().getF32();
|
||||
}
|
||||
|
||||
if (dist < 16.f)
|
||||
@@ -1211,7 +1267,7 @@ F32 LLSpatialGroup::getUpdateUrgency() const
|
||||
{
|
||||
//return (gFrameTimeSeconds - mLastUpdateTime+4.f)/mDistance;
|
||||
F32 time = gFrameTimeSeconds-mLastUpdateTime+4.f;
|
||||
return (time + (mObjectBounds[1]*mObjectBounds[1]) + 1.f)/mDistance;
|
||||
return time + (mObjectBounds[1].dot3(mObjectBounds[1]).getF32()+1.f)/mDistance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1223,7 +1279,7 @@ BOOL LLSpatialGroup::needsUpdate()
|
||||
BOOL LLSpatialGroup::changeLOD()
|
||||
{
|
||||
if (isState(ALPHA_DIRTY | OBJECT_DIRTY))
|
||||
{ ///an alpha sort is going to happen, update distance and LOD
|
||||
{ ///a rebuild is going to happen, update distance and LoD
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1236,7 +1292,6 @@ BOOL LLSpatialGroup::changeLOD()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//if (mDistance > mRadius)
|
||||
if (mDistance > mRadius*2.f)
|
||||
{
|
||||
return FALSE;
|
||||
@@ -1323,6 +1378,7 @@ void LLSpatialGroup::destroyGL()
|
||||
{
|
||||
setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
|
||||
gPipeline.markRebuild(this, TRUE);
|
||||
|
||||
mLastUpdateTime = gFrameTimeSeconds;
|
||||
mVertexBuffer = NULL;
|
||||
mBufferMap.clear();
|
||||
@@ -1380,8 +1436,8 @@ BOOL LLSpatialGroup::rebound()
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVector3& newMin = mExtents[0];
|
||||
LLVector3& newMax = mExtents[1];
|
||||
LLVector4a& newMin = mExtents[0];
|
||||
LLVector4a& newMax = mExtents[1];
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
|
||||
group->clearState(SKIP_FRUSTUM_CHECK);
|
||||
group->rebound();
|
||||
@@ -1395,26 +1451,19 @@ BOOL LLSpatialGroup::rebound()
|
||||
group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0);
|
||||
group->clearState(SKIP_FRUSTUM_CHECK);
|
||||
group->rebound();
|
||||
const LLVector3& max = group->mExtents[1];
|
||||
const LLVector3& min = group->mExtents[0];
|
||||
const LLVector4a& max = group->mExtents[1];
|
||||
const LLVector4a& min = group->mExtents[0];
|
||||
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
if (max.mV[j] > newMax.mV[j])
|
||||
{
|
||||
newMax.mV[j] = max.mV[j];
|
||||
}
|
||||
if (min.mV[j] < newMin.mV[j])
|
||||
{
|
||||
newMin.mV[j] = min.mV[j];
|
||||
}
|
||||
}
|
||||
newMax.setMax(newMax, max);
|
||||
newMin.setMin(newMin, min);
|
||||
}
|
||||
|
||||
boundObjects(FALSE, newMin, newMax);
|
||||
|
||||
mBounds[0] = (newMin + newMax)*0.5f;
|
||||
mBounds[1] = (newMax - newMin)*0.5f;
|
||||
mBounds[0].setAdd(newMin, newMax);
|
||||
mBounds[0].mul(0.5f);
|
||||
mBounds[1].setSub(newMax, newMin);
|
||||
mBounds[1].mul(0.5f);
|
||||
}
|
||||
|
||||
setState(OCCLUSION_DIRTY);
|
||||
@@ -1448,10 +1497,10 @@ void LLSpatialGroup::checkOcclusion()
|
||||
|
||||
if (available)
|
||||
{ //result is available, read it back, otherwise wait until next frame
|
||||
GLuint res = 1;
|
||||
if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
|
||||
{
|
||||
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);
|
||||
GLuint res = 1;
|
||||
if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
|
||||
{
|
||||
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);
|
||||
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
|
||||
sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
#endif
|
||||
@@ -1462,25 +1511,25 @@ void LLSpatialGroup::checkOcclusion()
|
||||
mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
|
||||
}
|
||||
|
||||
if (isOcclusionState(DISCARD_QUERY))
|
||||
{
|
||||
res = 2;
|
||||
}
|
||||
if (isOcclusionState(DISCARD_QUERY))
|
||||
{
|
||||
res = 2;
|
||||
}
|
||||
|
||||
if (res > 0)
|
||||
{
|
||||
assert_states_valid(this);
|
||||
clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
|
||||
assert_states_valid(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_states_valid(this);
|
||||
setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
|
||||
assert_states_valid(this);
|
||||
}
|
||||
if (res > 0)
|
||||
{
|
||||
assert_states_valid(this);
|
||||
clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
|
||||
assert_states_valid(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_states_valid(this);
|
||||
setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
|
||||
assert_states_valid(this);
|
||||
}
|
||||
|
||||
clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
|
||||
clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
|
||||
}
|
||||
}
|
||||
else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED))
|
||||
@@ -1611,9 +1660,11 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32
|
||||
mSlopRatio = 0.25f;
|
||||
mInfiniteFarClip = FALSE;
|
||||
|
||||
LLVector4a center, size;
|
||||
center.splat(0.f);
|
||||
size.splat(1.f);
|
||||
|
||||
mOctree = new LLSpatialGroup::OctreeRoot(LLVector3d(0,0,0),
|
||||
LLVector3d(1,1,1),
|
||||
mOctree = new LLSpatialGroup::OctreeRoot(center,size,
|
||||
NULL);
|
||||
new LLSpatialGroup(mOctree, this);
|
||||
}
|
||||
@@ -1717,15 +1768,16 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL
|
||||
class LLSpatialShift : public LLSpatialGroup::OctreeTraveler
|
||||
{
|
||||
public:
|
||||
const LLVector3& mOffset;
|
||||
LLSpatialShift(const LLVector3 &offset) : mOffset(offset) { }
|
||||
const LLVector4a& mOffset;
|
||||
|
||||
LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { }
|
||||
virtual void visit(const LLSpatialGroup::OctreeNode* branch)
|
||||
{
|
||||
((LLSpatialGroup*) branch->getListener(0))->shift(mOffset);
|
||||
}
|
||||
};
|
||||
|
||||
void LLSpatialPartition::shift(const LLVector3 &offset)
|
||||
void LLSpatialPartition::shift(const LLVector4a &offset)
|
||||
{ //shift octree node bounding boxes by offset
|
||||
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
|
||||
LLSpatialShift shifter(offset);
|
||||
@@ -1887,7 +1939,7 @@ public:
|
||||
class LLOctreeCullVisExtents: public LLOctreeCullShadow
|
||||
{
|
||||
public:
|
||||
LLOctreeCullVisExtents(LLCamera* camera, LLVector3& min, LLVector3& max)
|
||||
LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max)
|
||||
: LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { }
|
||||
|
||||
virtual bool earlyFail(LLSpatialGroup* group)
|
||||
@@ -1954,8 +2006,8 @@ public:
|
||||
}
|
||||
|
||||
BOOL mEmpty;
|
||||
LLVector3& mMin;
|
||||
LLVector3& mMax;
|
||||
LLVector4a& mMin;
|
||||
LLVector4a& mMax;
|
||||
};
|
||||
|
||||
class LLOctreeCullDetectVisible: public LLOctreeCullShadow
|
||||
@@ -2061,6 +2113,11 @@ void drawBox(const LLVector3& c, const LLVector3& r)
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
void drawBox(const LLVector4a& c, const LLVector4a& r)
|
||||
{
|
||||
drawBox(reinterpret_cast<const LLVector3&>(c), reinterpret_cast<const LLVector3&>(r));
|
||||
}
|
||||
|
||||
void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
|
||||
{
|
||||
LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
|
||||
@@ -2107,6 +2164,11 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size)
|
||||
{
|
||||
drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size));
|
||||
}
|
||||
|
||||
class LLOctreeDirty : public LLOctreeTraveler<LLDrawable>
|
||||
{
|
||||
public:
|
||||
@@ -2150,13 +2212,20 @@ BOOL LLSpatialPartition::isOcclusionEnabled()
|
||||
|
||||
BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax)
|
||||
{
|
||||
LLVector4a visMina, visMaxa;
|
||||
visMina.load3(visMin.mV);
|
||||
visMaxa.load3(visMax.mV);
|
||||
{
|
||||
LLFastTimer ftm( LLFastTimer::FTM_CULL_REBOUND);
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
|
||||
group->rebound();
|
||||
}
|
||||
LLOctreeCullVisExtents vis(&camera, visMin, visMax);
|
||||
|
||||
LLOctreeCullVisExtents vis(&camera, visMina, visMaxa);
|
||||
vis.traverse(mOctree);
|
||||
|
||||
visMin.set(visMina.getF32ptr());
|
||||
visMax.set(visMaxa.getF32ptr());
|
||||
return vis.mEmpty;
|
||||
}
|
||||
|
||||
@@ -2222,25 +2291,36 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group)
|
||||
}
|
||||
|
||||
const F32 vel = SG_OCCLUSION_FUDGE*2.f;
|
||||
LLVector3 c = group->mBounds[0];
|
||||
LLVector3 r = group->mBounds[1] + LLVector3(vel,vel,vel);
|
||||
|
||||
LLVector4a fudge;
|
||||
fudge.splat(vel);
|
||||
|
||||
const LLVector4a& c = group->mBounds[0];
|
||||
LLVector4a r;
|
||||
r.setAdd(group->mBounds[1], fudge);
|
||||
|
||||
/*if (r.magVecSquared() > 1024.0*1024.0)
|
||||
{
|
||||
return TRUE;
|
||||
}*/
|
||||
|
||||
LLVector3 e = camera->getOrigin();
|
||||
LLVector4a e;
|
||||
e.load3(camera->getOrigin().mV);
|
||||
|
||||
LLVector3 min = c - r;
|
||||
LLVector3 max = c + r;
|
||||
LLVector4a min;
|
||||
min.setSub(c,r);
|
||||
LLVector4a max;
|
||||
max.setAdd(c,r);
|
||||
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
S32 lt = e.lessThan(min).getGatheredBits() & 0x7;
|
||||
if (lt)
|
||||
{
|
||||
if (e.mV[j] < min.mV[j] || e.mV[j] > max.mV[j])
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
S32 gt = e.greaterThan(max).getGatheredBits() & 0x7;
|
||||
if (gt)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -2282,7 +2362,26 @@ void pushVerts(LLFace* face, U32 mask)
|
||||
U16 offset = face->getIndicesStart();
|
||||
buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
|
||||
}
|
||||
}
|
||||
|
||||
void pushVerts(LLDrawable* drawable, U32 mask)
|
||||
{
|
||||
for (S32 i = 0; i < drawable->getNumFaces(); ++i)
|
||||
{
|
||||
pushVerts(drawable->getFace(i), mask);
|
||||
}
|
||||
}
|
||||
|
||||
void pushVerts(LLVolume* volume)
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
|
||||
{
|
||||
const LLVolumeFace& face = volume->getVolumeFace(i);
|
||||
glVertexPointer(3, GL_FLOAT, 16, face.mVertices[i].mPosition.mV);
|
||||
//This probably doesn't work.
|
||||
glDrawElements(GL_TRIANGLES, face.mIndices.size(), GL_UNSIGNED_SHORT, (GLvoid*)face.mIndices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
|
||||
@@ -2446,10 +2545,15 @@ void renderOctree(LLSpatialGroup* group)
|
||||
}
|
||||
|
||||
gGL.color4fv(col.mV);
|
||||
LLVector4a fudge;
|
||||
fudge.splat(0.001f);
|
||||
LLVector4a size = group->mObjectBounds[1];
|
||||
size.mul(1.01f);
|
||||
size.add(fudge);
|
||||
|
||||
{
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f));
|
||||
drawBox(group->mObjectBounds[0], fudge);
|
||||
}
|
||||
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
@@ -2481,8 +2585,12 @@ void renderOctree(LLSpatialGroup* group)
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
|
||||
{
|
||||
LLDrawInfo* draw_info = *j;
|
||||
LLVector3 center = (draw_info->mExtents[1] + draw_info->mExtents[0])*0.5f;
|
||||
LLVector3 size = (draw_info->mExtents[1] - draw_info->mExtents[0])*0.5f;
|
||||
LLVector4a center;
|
||||
center.setAdd(draw_info->mExtents[1], draw_info->mExtents[0]);
|
||||
center.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(draw_info->mExtents[1], draw_info->mExtents[0]);
|
||||
size.mul(0.5f);
|
||||
drawBoxOutline(center, size);
|
||||
}
|
||||
}
|
||||
@@ -2655,8 +2763,8 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
|
||||
}
|
||||
}
|
||||
|
||||
const LLVector3* ext;
|
||||
LLVector3 pos, size;
|
||||
const LLVector4a* ext;
|
||||
LLVector4a pos, size;
|
||||
|
||||
//render face bounding boxes
|
||||
for (S32 i = 0; i < drawable->getNumFaces(); i++)
|
||||
@@ -2665,20 +2773,21 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
|
||||
|
||||
ext = facep->mExtents;
|
||||
|
||||
if (ext[0].isExactlyZero() && ext[1].isExactlyZero())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
pos = (ext[0] + ext[1]) * 0.5f;
|
||||
size = (ext[1] - ext[0]) * 0.5f;
|
||||
pos.setAdd(ext[0], ext[1]);
|
||||
pos.mul(0.5f);
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
drawBoxOutline(pos,size);
|
||||
}
|
||||
|
||||
//render drawable bounding box
|
||||
ext = drawable->getSpatialExtents();
|
||||
|
||||
pos = (ext[0] + ext[1]) * 0.5f;
|
||||
size = (ext[1] - ext[0]) * 0.5f;
|
||||
pos.setAdd(ext[0], ext[1]);
|
||||
pos.mul(0.5f);
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
LLViewerObject* vobj = drawable->getVObj();
|
||||
if (vobj && vobj->onActiveList())
|
||||
@@ -2734,8 +2843,13 @@ void renderTexturePriority(LLDrawable* drawable)
|
||||
// gGL.color4f(1,0,1,1);
|
||||
//}
|
||||
|
||||
LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f;
|
||||
LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f);
|
||||
LLVector4a center;
|
||||
center.setAdd(facep->mExtents[1],facep->mExtents[0]);
|
||||
center.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(facep->mExtents[1],facep->mExtents[0]);
|
||||
size.mul(0.5f);
|
||||
size.add(LLVector4a(0.01f));
|
||||
drawBox(center, size);
|
||||
|
||||
/*S32 boost = imagep->getBoostLevel();
|
||||
@@ -2781,6 +2895,8 @@ void renderTextureAnim(LLDrawInfo* params)
|
||||
|
||||
void renderBatchSize(LLDrawInfo* params)
|
||||
{
|
||||
LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.f, 1.f);
|
||||
glColor3ubv((GLubyte*) &(params->mDebugColor));
|
||||
pushVerts(params, LLVertexBuffer::MAP_VERTEX);
|
||||
}
|
||||
@@ -2802,10 +2918,14 @@ void renderLights(LLDrawable* drawablep)
|
||||
pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX);
|
||||
}
|
||||
|
||||
const LLVector3* ext = drawablep->getSpatialExtents();
|
||||
const LLVector4a* ext = drawablep->getSpatialExtents();
|
||||
|
||||
LLVector3 pos = (ext[0] + ext[1]) * 0.5f;
|
||||
LLVector3 size = (ext[1] - ext[0]) * 0.5f;
|
||||
LLVector4a pos;
|
||||
pos.setAdd(ext[0], ext[1]);
|
||||
pos.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
{
|
||||
LLGLDepthTest depth(GL_FALSE, GL_TRUE);
|
||||
@@ -2815,7 +2935,7 @@ void renderLights(LLDrawable* drawablep)
|
||||
|
||||
gGL.color4f(1,1,0,1);
|
||||
F32 rad = drawablep->getVOVolume()->getLightRadius();
|
||||
drawBoxOutline(pos, LLVector3(rad,rad,rad));
|
||||
drawBoxOutline(pos, LLVector4a(rad));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2864,11 +2984,15 @@ void renderRaycast(LLDrawable* drawablep)
|
||||
drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f));
|
||||
glPopMatrix();
|
||||
|
||||
// draw bounding box of prim
|
||||
const LLVector3* ext = drawablep->getSpatialExtents();
|
||||
// draw bounding box of prim
|
||||
const LLVector4a* ext = drawablep->getSpatialExtents();
|
||||
|
||||
LLVector3 pos = (ext[0] + ext[1]) * 0.5f;
|
||||
LLVector3 size = (ext[1] - ext[0]) * 0.5f;
|
||||
LLVector4a pos;
|
||||
pos.setAdd(ext[0], ext[1]);
|
||||
pos.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
LLGLDepthTest depth(GL_FALSE, GL_TRUE);
|
||||
gGL.color4f(0,0.5f,0.5f,1);
|
||||
@@ -2955,8 +3079,8 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
LLVector3 nodeCenter = group->mBounds[0];
|
||||
LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter());
|
||||
LLVector4a nodeCenter = group->mBounds[0];
|
||||
LLVector4a octCenter = group->mOctreeNode->getCenter();
|
||||
|
||||
group->rebuildGeom();
|
||||
group->rebuildMesh();
|
||||
@@ -2985,8 +3109,14 @@ public:
|
||||
if (drawable->isState(LLDrawable::IN_REBUILD_Q2))
|
||||
{
|
||||
gGL.color4f(0.6f, 0.6f, 0.1f, 1.f);
|
||||
const LLVector3* ext = drawable->getSpatialExtents();
|
||||
drawBoxOutline((ext[0]+ext[1])*0.5f, (ext[1]-ext[0])*0.5f);
|
||||
const LLVector4a* ext = drawable->getSpatialExtents();
|
||||
LLVector4a center;
|
||||
center.setAdd(ext[0], ext[1]);
|
||||
center.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
drawBoxOutline(center, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3217,7 +3347,11 @@ void LLSpatialPartition::renderDebug()
|
||||
void LLSpatialGroup::drawObjectBox(LLColor4 col)
|
||||
{
|
||||
gGL.color4fv(col.mV);
|
||||
drawBox(mObjectBounds[0], mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f));
|
||||
LLVector4a size;
|
||||
size = mObjectBounds[1];
|
||||
size.mul(1.01f);
|
||||
size.add(LLVector4a(0.001f));
|
||||
drawBox(mObjectBounds[0], size);
|
||||
}
|
||||
|
||||
|
||||
@@ -3277,8 +3411,8 @@ public:
|
||||
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0);
|
||||
|
||||
LLVector3 size;
|
||||
LLVector3 center;
|
||||
LLVector4a size;
|
||||
LLVector4a center;
|
||||
|
||||
size = group->mBounds[1];
|
||||
center = group->mBounds[0];
|
||||
@@ -3295,7 +3429,11 @@ public:
|
||||
local_end = mEnd * local_matrix;
|
||||
}
|
||||
|
||||
if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))
|
||||
LLVector4a start, end;
|
||||
start.load3(local_start.mV);
|
||||
end.load3(local_end.mV);
|
||||
|
||||
if (LLLineSegmentBoxIntersect(start, end, center, size))
|
||||
{
|
||||
check(child);
|
||||
}
|
||||
|
||||
@@ -54,11 +54,16 @@ class LLSpatialPartition;
|
||||
class LLSpatialBridge;
|
||||
class LLSpatialGroup;
|
||||
|
||||
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
|
||||
U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector3& center);
|
||||
U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
|
||||
U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center);
|
||||
|
||||
class LLDrawInfo : public LLRefCount
|
||||
{
|
||||
@@ -71,6 +76,9 @@ public:
|
||||
BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
|
||||
|
||||
|
||||
|
||||
LLVector4a mExtents[2];
|
||||
|
||||
LLPointer<LLVertexBuffer> mVertexBuffer;
|
||||
LLPointer<LLViewerTexture> mTexture;
|
||||
LLColor4U mGlowColor;
|
||||
@@ -89,7 +97,6 @@ public:
|
||||
LLSpatialGroup* mGroup;
|
||||
LLFace* mFace; //associated face
|
||||
F32 mDistance;
|
||||
LLVector3 mExtents[2];
|
||||
|
||||
struct CompareTexture
|
||||
{
|
||||
@@ -151,6 +158,7 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
LL_ALIGN_PREFIX(64)
|
||||
class LLSpatialGroup : public LLOctreeListener<LLDrawable>
|
||||
{
|
||||
friend class LLSpatialPartition;
|
||||
@@ -265,8 +273,8 @@ public:
|
||||
BOOL isVisible() const;
|
||||
BOOL isRecentlyVisible() const;
|
||||
void setVisible();
|
||||
void shift(const LLVector3 &offset);
|
||||
BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax);
|
||||
void shift(const LLVector4a &offset);
|
||||
BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax);
|
||||
void unbound();
|
||||
BOOL rebound();
|
||||
void buildOcclusion(); //rebuild mOcclusionVerts
|
||||
@@ -296,13 +304,24 @@ public:
|
||||
virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
|
||||
virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);
|
||||
|
||||
LLVector3 mBounds[2];
|
||||
LLVector3 mExtents[2];
|
||||
|
||||
LLVector3 mObjectExtents[2];
|
||||
LLVector3 mObjectBounds[2];
|
||||
LLVector3 mViewAngle;
|
||||
LLVector3 mLastUpdateViewAngle;
|
||||
typedef enum
|
||||
{
|
||||
BOUNDS = 0,
|
||||
EXTENTS = 2,
|
||||
OBJECT_BOUNDS = 4,
|
||||
OBJECT_EXTENTS = 6,
|
||||
VIEW_ANGLE = 8,
|
||||
LAST_VIEW_ANGLE = 9,
|
||||
V4_COUNT = 10
|
||||
} eV4Index;
|
||||
|
||||
LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects)
|
||||
LLVector4a mExtents[2]; // extents (min, max) of this node and all its children
|
||||
LLVector4a mObjectExtents[2]; // extents (min, max) of objects in this node
|
||||
LLVector4a mObjectBounds[2]; // bounding box (center, size) of objects in this node
|
||||
LLVector4a mViewAngle;
|
||||
LLVector4a mLastUpdateViewAngle;
|
||||
|
||||
protected:
|
||||
virtual ~LLSpatialGroup();
|
||||
|
||||
@@ -334,7 +353,7 @@ public:
|
||||
|
||||
F32 mPixelArea;
|
||||
F32 mRadius;
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(64);
|
||||
|
||||
inline LLSpatialGroup::eOcclusionState operator|(const LLSpatialGroup::eOcclusionState &a, const LLSpatialGroup::eOcclusionState &b)
|
||||
{
|
||||
@@ -380,7 +399,7 @@ public:
|
||||
|
||||
// If the drawable moves, move it here.
|
||||
virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE);
|
||||
virtual void shift(const LLVector3 &offset);
|
||||
virtual void shift(const LLVector4a &offset);
|
||||
|
||||
virtual F32 calcDistance(LLSpatialGroup* group, LLCamera& camera);
|
||||
virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
|
||||
@@ -438,7 +457,7 @@ public:
|
||||
virtual void makeActive();
|
||||
virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE);
|
||||
virtual BOOL updateMove();
|
||||
virtual void shiftPos(const LLVector3& vec);
|
||||
virtual void shiftPos(const LLVector4a& vec);
|
||||
virtual void cleanupReferences();
|
||||
virtual LLSpatialPartition* asPartition() { return this; }
|
||||
virtual LLSpatialBridge* asBridge() { return this; }
|
||||
@@ -631,7 +650,7 @@ class LLHUDBridge : public LLVolumeBridge
|
||||
{
|
||||
public:
|
||||
LLHUDBridge(LLDrawable* drawablep);
|
||||
virtual void shiftPos(const LLVector3& vec);
|
||||
virtual void shiftPos(const LLVector4a& vec);
|
||||
virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
|
||||
};
|
||||
|
||||
@@ -648,7 +667,7 @@ class LLHUDPartition : public LLBridgePartition
|
||||
{
|
||||
public:
|
||||
LLHUDPartition();
|
||||
virtual void shift(const LLVector3 &offset);
|
||||
virtual void shift(const LLVector4a &offset);
|
||||
};
|
||||
|
||||
void validate_draw_info(LLDrawInfo& params);
|
||||
|
||||
@@ -860,8 +860,10 @@ void LLSurfacePatch::updateVisibility()
|
||||
F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid();
|
||||
U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
|
||||
|
||||
LLVector3 center = mCenterRegion + mSurfacep->getOriginAgent();
|
||||
LLVector3 radius = LLVector3(mRadius, mRadius, mRadius);
|
||||
LLVector4a center;
|
||||
center.load3( (mCenterRegion + mSurfacep->getOriginAgent()).mV);
|
||||
LLVector4a radius;
|
||||
radius.splat(mRadius);
|
||||
|
||||
// sphere in frustum on global coordinates
|
||||
if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius))
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#define LLVIEWERCAMERA_CPP
|
||||
#include "llviewercamera.h"
|
||||
|
||||
#include <iomanip> // for setprecision
|
||||
@@ -39,6 +41,7 @@
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "lldrawable.h"
|
||||
#include "llface.h"
|
||||
@@ -760,6 +763,11 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
|
||||
|
||||
LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition()));
|
||||
|
||||
LLMatrix4a render_mata;
|
||||
render_mata.loadu(render_mat);
|
||||
LLMatrix4a mata;
|
||||
mata.loadu(mat);
|
||||
|
||||
num_faces = volume->getNumVolumeFaces();
|
||||
for (i = 0; i < num_faces; i++)
|
||||
{
|
||||
@@ -767,14 +775,18 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
|
||||
|
||||
for (U32 v = 0; v < face.mVertices.size(); v++)
|
||||
{
|
||||
LLVector4 vec = LLVector4(face.mVertices[v].mPosition) * mat;
|
||||
LLVector4a src_vec;
|
||||
src_vec.load3(face.mVertices[v].mPosition.mV);
|
||||
LLVector4a vec;
|
||||
mata.affineTransform(src_vec, vec);
|
||||
|
||||
if (drawablep->isActive())
|
||||
{
|
||||
vec = vec * render_mat;
|
||||
LLVector4a t = vec;
|
||||
render_mata.affineTransform(t, vec);
|
||||
}
|
||||
|
||||
BOOL in_frustum = pointInFrustum(LLVector3(vec)) > 0;
|
||||
BOOL in_frustum = pointInFrustum(LLVector3(vec.getF32ptr())) > 0;
|
||||
|
||||
if (( !in_frustum && all_verts) ||
|
||||
(in_frustum && !all_verts))
|
||||
|
||||
@@ -51,6 +51,11 @@ const F32 OGL_TO_CFR_ROTATION[16] = { 0.f, 0.f, -1.f, 0.f, // -Z becomes X
|
||||
const BOOL FOR_SELECTION = TRUE;
|
||||
const BOOL NOT_FOR_SELECTION = FALSE;
|
||||
|
||||
// Build time optimization, generate this once in .cpp file
|
||||
#ifndef LLVIEWERCAMERA_CPP
|
||||
extern template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInstance();
|
||||
#endif
|
||||
|
||||
class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -150,9 +150,9 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
|
||||
case LL_VO_SKY:
|
||||
res = new LLVOSky(id, pcode, regionp); break;
|
||||
case LL_VO_VOID_WATER:
|
||||
res = new LLVOVoidWater(id, pcode, regionp); break;
|
||||
res = new LLVOVoidWater(id, pcode, regionp); break;
|
||||
case LL_VO_WATER:
|
||||
res = new LLVOWater(id, pcode, regionp); break;
|
||||
res = new LLVOWater(id, pcode, regionp); break;
|
||||
case LL_VO_GROUND:
|
||||
res = new LLVOGround(id, pcode, regionp); break;
|
||||
case LL_VO_PART_GROUP:
|
||||
@@ -649,14 +649,13 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
|
||||
}
|
||||
|
||||
BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
|
||||
if (!ret)
|
||||
if(!ret)
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
LLDrawable* old_parent = mDrawable->mParent;
|
||||
|
||||
mDrawable->mParent = parentp;
|
||||
|
||||
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
|
||||
if( (old_parent != parentp && old_parent)
|
||||
|| (parentp && parentp->isActive()))
|
||||
@@ -836,6 +835,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
|
||||
((LLVOAvatar*)this)->setFootPlane(collision_plane);
|
||||
count += sizeof(LLVector4);
|
||||
// fall through
|
||||
case 60:
|
||||
this_update_precision = 32;
|
||||
// this is a terse update
|
||||
@@ -875,6 +875,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
|
||||
((LLVOAvatar*)this)->setFootPlane(collision_plane);
|
||||
count += sizeof(LLVector4);
|
||||
// fall through
|
||||
case 32:
|
||||
this_update_precision = 16;
|
||||
test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
|
||||
@@ -1180,6 +1181,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
|
||||
((LLVOAvatar*)this)->setFootPlane(collision_plane);
|
||||
count += sizeof(LLVector4);
|
||||
// fall through
|
||||
case 60:
|
||||
// this is a terse 32 update
|
||||
// pos
|
||||
@@ -1219,6 +1221,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
|
||||
((LLVOAvatar*)this)->setFootPlane(collision_plane);
|
||||
count += sizeof(LLVector4);
|
||||
// fall through
|
||||
case 32:
|
||||
// this is a terse 16 update
|
||||
this_update_precision = 16;
|
||||
@@ -2909,22 +2912,26 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped)
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
|
||||
void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
|
||||
{
|
||||
LLVector3 center = getRenderPosition();
|
||||
LLVector3 size = getScale();
|
||||
newMin.setVec(center-size);
|
||||
newMax.setVec(center+size);
|
||||
if(mDrawable.notNull())
|
||||
mDrawable->setPositionGroup((newMin + newMax) * 0.5f);
|
||||
LLVector4a center;
|
||||
center.load3(getRenderPosition().mV);
|
||||
LLVector4a size;
|
||||
size.load3(getScale().mV);
|
||||
newMin.setSub(center, size);
|
||||
newMax.setAdd(center, size);
|
||||
|
||||
mDrawable->setPositionGroup(center);
|
||||
}
|
||||
|
||||
F32 LLViewerObject::getBinRadius()
|
||||
{
|
||||
if (mDrawable.notNull())
|
||||
{
|
||||
const LLVector3* ext = mDrawable->getSpatialExtents();
|
||||
return (ext[1]-ext[0]).magVec();
|
||||
const LLVector4a* ext = mDrawable->getSpatialExtents();
|
||||
LLVector4a diff;
|
||||
diff.setSub(ext[1], ext[0]);
|
||||
return diff.getLength3().getF32();
|
||||
}
|
||||
|
||||
return getScale().magVec();
|
||||
@@ -3516,12 +3523,21 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const LLVector3* ext = mDrawable->getSpatialExtents();
|
||||
const LLVector4a* ext = mDrawable->getSpatialExtents();
|
||||
|
||||
LLVector3 center = (ext[1]+ext[0])*0.5f;
|
||||
LLVector3 size = (ext[1]-ext[0])*0.5f;
|
||||
//VECTORIZE THIS
|
||||
LLVector4a center;
|
||||
center.setAdd(ext[1], ext[0]);
|
||||
center.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
return LLLineSegmentBoxIntersect(start, end, center, size);
|
||||
LLVector4a starta, enda;
|
||||
starta.load3(start.mV);
|
||||
enda.load3(end.mV);
|
||||
|
||||
return LLLineSegmentBoxIntersect(starta, enda, center, size);
|
||||
}
|
||||
|
||||
U8 LLViewerObject::getMediaType() const
|
||||
@@ -3742,7 +3758,7 @@ void LLViewerObject::sendTEUpdate() const
|
||||
msg->addString("MediaURL", NULL);
|
||||
}
|
||||
|
||||
// JAMESDEBUG TODO send media type
|
||||
// TODO send media type
|
||||
|
||||
packTEMessage(msg);
|
||||
|
||||
@@ -3753,7 +3769,7 @@ void LLViewerObject::sendTEUpdate() const
|
||||
void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
|
||||
{
|
||||
LLPrimitive::setTE(te, texture_entry);
|
||||
// JAMESDEBUG This doesn't work, don't get any textures.
|
||||
// This doesn't work, don't get any textures.
|
||||
// if (mDrawable.notNull() && mDrawable->isVisible())
|
||||
// {
|
||||
const LLUUID& image_id = getTE(te)->getID();
|
||||
@@ -3927,7 +3943,7 @@ S32 LLViewerObject::setTEFullbright(const U8 te, const U8 fullbright)
|
||||
|
||||
S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags)
|
||||
{
|
||||
// JAMESDEBUG this might need work for media type
|
||||
// this might need work for media type
|
||||
S32 retval = 0;
|
||||
const LLTextureEntry *tep = getTE(te);
|
||||
if (!tep)
|
||||
|
||||
@@ -367,7 +367,7 @@ public:
|
||||
|
||||
void markForUpdate(BOOL priority);
|
||||
void updateVolume(const LLVolumeParams& volume_params);
|
||||
virtual void updateSpatialExtents(LLVector3& min, LLVector3& max);
|
||||
virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
|
||||
virtual F32 getBinRadius();
|
||||
|
||||
LLBBox getBoundingBoxAgent() const;
|
||||
@@ -380,7 +380,7 @@ public:
|
||||
void clearDrawableState(U32 state, BOOL recursive = TRUE);
|
||||
|
||||
// Called when the drawable shifts
|
||||
virtual void onShift(const LLVector3 &shift_vector) { }
|
||||
virtual void onShift(const LLVector4a &shift_vector) { }
|
||||
|
||||
//////////////////////////////////////
|
||||
//
|
||||
|
||||
@@ -161,8 +161,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo
|
||||
|
||||
if (group != NULL)
|
||||
{
|
||||
LLVector3 center(group->mOctreeNode->getCenter());
|
||||
LLVector3 size(group->mOctreeNode->getSize());
|
||||
LLVector3 center(group->mOctreeNode->getCenter().getF32ptr());
|
||||
LLVector3 size(group->mOctreeNode->getSize().getF32ptr());
|
||||
size += LLVector3(0.01f, 0.01f, 0.01f);
|
||||
mMinObjPos = center - size;
|
||||
mMaxObjPos = center + size;
|
||||
|
||||
@@ -1536,41 +1536,46 @@ void LLVOAvatar::updateDrawable(BOOL force_damped)
|
||||
clearChanged(SHIFTED);
|
||||
}
|
||||
|
||||
void LLVOAvatar::onShift(const LLVector3& shift_vector)
|
||||
void LLVOAvatar::onShift(const LLVector4a& shift_vector)
|
||||
{
|
||||
mLastAnimExtents[0] += shift_vector;
|
||||
mLastAnimExtents[1] += shift_vector;
|
||||
const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector);
|
||||
mLastAnimExtents[0] += shift;
|
||||
mLastAnimExtents[1] += shift;
|
||||
mNeedsImpostorUpdate = TRUE;
|
||||
mNeedsAnimUpdate = TRUE;
|
||||
}
|
||||
|
||||
void LLVOAvatar::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
|
||||
void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
|
||||
{
|
||||
if (isImpostor() && !needsImpostorUpdate())
|
||||
{
|
||||
LLVector3 delta = getRenderPosition() -
|
||||
((LLVector3(mDrawable->getPositionGroup())-mImpostorOffset));
|
||||
((LLVector3(mDrawable->getPositionGroup().getF32ptr())-mImpostorOffset));
|
||||
|
||||
newMin = mLastAnimExtents[0] + delta;
|
||||
newMax = mLastAnimExtents[1] + delta;
|
||||
newMin.load3( (mLastAnimExtents[0] + delta).mV);
|
||||
newMax.load3( (mLastAnimExtents[1] + delta).mV);
|
||||
}
|
||||
else
|
||||
{
|
||||
getSpatialExtents(newMin,newMax);
|
||||
mLastAnimExtents[0] = newMin;
|
||||
mLastAnimExtents[1] = newMax;
|
||||
LLVector3 pos_group = (newMin+newMax)*0.5f;
|
||||
mImpostorOffset = pos_group-getRenderPosition();
|
||||
mLastAnimExtents[0].set(newMin.getF32ptr());
|
||||
mLastAnimExtents[1].set(newMax.getF32ptr());
|
||||
LLVector4a pos_group;
|
||||
pos_group.setAdd(newMin,newMax);
|
||||
pos_group.mul(0.5f);
|
||||
mImpostorOffset = LLVector3(pos_group.getF32ptr())-getRenderPosition();
|
||||
mDrawable->setPositionGroup(pos_group);
|
||||
}
|
||||
}
|
||||
|
||||
void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
|
||||
void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
|
||||
{
|
||||
LLVector3 buffer(0.25f, 0.25f, 0.25f);
|
||||
LLVector3 pos = getRenderPosition();
|
||||
newMin = pos - buffer;
|
||||
newMax = pos + buffer;
|
||||
LLVector4a buffer(0.25f);
|
||||
LLVector4a pos;
|
||||
pos.load3(getRenderPosition().mV);
|
||||
newMin.setSub(pos, buffer);
|
||||
newMax.setAdd(pos, buffer);
|
||||
|
||||
float max_attachment_span = DEFAULT_MAX_PRIM_SCALE * 5.0f;
|
||||
|
||||
//stretch bounding box by joint positions
|
||||
@@ -1579,12 +1584,20 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
|
||||
LLPolyMesh* mesh = i->second;
|
||||
for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++)
|
||||
{
|
||||
update_min_max(newMin, newMax,
|
||||
mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation());
|
||||
LLVector4a trans;
|
||||
trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV);
|
||||
update_min_max(newMin, newMax, trans);
|
||||
}
|
||||
}
|
||||
|
||||
mPixelArea = LLPipeline::calcPixelArea((newMin+newMax)*0.5f, (newMax-newMin)*0.5f, *LLViewerCamera::getInstance());
|
||||
LLVector4a center, size;
|
||||
center.setAdd(newMin, newMax);
|
||||
center.mul(0.5f);
|
||||
|
||||
size.setSub(newMax,newMin);
|
||||
size.mul(0.5f);
|
||||
|
||||
mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
|
||||
|
||||
//stretch bounding box by attachments
|
||||
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
|
||||
@@ -1610,15 +1623,17 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
|
||||
LLSpatialBridge* bridge = drawable->getSpatialBridge();
|
||||
if (bridge)
|
||||
{
|
||||
const LLVector3* ext = bridge->getSpatialExtents();
|
||||
LLVector3 distance = (ext[1] - ext[0]);
|
||||
const LLVector4a* ext = bridge->getSpatialExtents();
|
||||
LLVector4a distance;
|
||||
distance.setSub(ext[1], ext[0]);
|
||||
LLVector4a max_span(max_attachment_span);
|
||||
|
||||
S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7;
|
||||
|
||||
// Only add the prim to spatial extents calculations if it isn't a megaprim.
|
||||
// max_attachment_span calculated at the start of the function
|
||||
// (currently 5 times our max prim size)
|
||||
if (distance.mV[0] < max_attachment_span
|
||||
&& distance.mV[1] < max_attachment_span
|
||||
&& distance.mV[2] < max_attachment_span)
|
||||
if (lt == 0x7)
|
||||
{
|
||||
update_min_max(newMin,newMax,ext[0]);
|
||||
update_min_max(newMin,newMax,ext[1]);
|
||||
@@ -1630,8 +1645,9 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
|
||||
}
|
||||
|
||||
//pad bounding box
|
||||
newMin -= buffer;
|
||||
newMax += buffer;
|
||||
|
||||
newMin.sub(buffer);
|
||||
newMax.add(buffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2926,7 +2942,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
|
||||
|
||||
if (isImpostor() && !mNeedsImpostorUpdate)
|
||||
{
|
||||
LLVector3 ext[2];
|
||||
LLVector4a ext[2];
|
||||
F32 distance;
|
||||
LLVector3 angle;
|
||||
|
||||
@@ -2938,7 +2954,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
|
||||
F32 old_angle = mImpostorAngle.mV[i];
|
||||
F32 angle_diff = fabsf(cur_angle-old_angle);
|
||||
|
||||
if (angle_diff > 3.14159f/512.f*distance*mUpdatePeriod)
|
||||
if (angle_diff > F_PI/512.f*distance*mUpdatePeriod)
|
||||
{
|
||||
mNeedsImpostorUpdate = TRUE;
|
||||
}
|
||||
@@ -2955,16 +2971,25 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
|
||||
}
|
||||
else
|
||||
{
|
||||
//VECTORIZE THIS
|
||||
getSpatialExtents(ext[0], ext[1]);
|
||||
if ((ext[1]-mImpostorExtents[1]).length() > 0.05f ||
|
||||
(ext[0]-mImpostorExtents[0]).length() > 0.05f)
|
||||
LLVector4a diff;
|
||||
diff.setSub(ext[1], mImpostorExtents[1]);
|
||||
if (diff.getLength3().getF32() > 0.05f)
|
||||
{
|
||||
mNeedsImpostorUpdate = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
diff.setSub(ext[0], mImpostorExtents[0]);
|
||||
if (diff.getLength3().getF32() > 0.05f)
|
||||
{
|
||||
mNeedsImpostorUpdate = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mDrawable)
|
||||
{
|
||||
mDrawable->movePartition();
|
||||
@@ -6600,14 +6625,18 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_AVATAR);
|
||||
|
||||
if (!mDrawable || mDrawable.isNull())
|
||||
if (mDrawable.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const LLVector3* ext = mDrawable->getSpatialExtents();
|
||||
LLVector3 center = (ext[1] + ext[0]) * 0.5f;
|
||||
LLVector3 size = (ext[1]-ext[0])*0.5f;
|
||||
const LLVector4a* ext = mDrawable->getSpatialExtents();
|
||||
LLVector4a center;
|
||||
center.setAdd(ext[1], ext[0]);
|
||||
center.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
|
||||
|
||||
@@ -6619,7 +6648,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 radius = size.length();
|
||||
F32 radius = size.getLength3().getF32();
|
||||
mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG;
|
||||
}
|
||||
|
||||
@@ -10528,9 +10557,9 @@ void LLVOAvatar::cacheImpostorValues()
|
||||
getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance);
|
||||
}
|
||||
|
||||
void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const
|
||||
void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& distance) const
|
||||
{
|
||||
const LLVector3* ext = mDrawable->getSpatialExtents();
|
||||
const LLVector4a* ext = mDrawable->getSpatialExtents();
|
||||
extents[0] = ext[0];
|
||||
extents[1] = ext[1];
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
|
||||
/*virtual*/ void updateTextures();
|
||||
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
|
||||
/*virtual*/ void onShift(const LLVector3& shift_vector);
|
||||
/*virtual*/ void onShift(const LLVector4a& shift_vector);
|
||||
virtual U32 getPartitionType() const;
|
||||
virtual const LLVector3 getRenderPosition() const;
|
||||
virtual void updateDrawable(BOOL force_damped);
|
||||
@@ -135,8 +135,8 @@ public:
|
||||
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
|
||||
/*virtual*/ void setPixelAreaAndAngle(LLAgent &agent);
|
||||
virtual void updateRegion(LLViewerRegion *regionp);
|
||||
void updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax);
|
||||
void getSpatialExtents(LLVector3& newMin, LLVector3& newMax);
|
||||
void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
|
||||
void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
BOOL pick_transparent = FALSE,
|
||||
@@ -196,6 +196,10 @@ public:
|
||||
public:
|
||||
bool isSelf() const { return mIsSelf; } // True if this avatar is for this viewer's agent
|
||||
bool isBuilt() const { return mIsBuilt; }
|
||||
|
||||
private: //aligned members
|
||||
LLVector4a mImpostorExtents[2];
|
||||
|
||||
private:
|
||||
BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients
|
||||
|
||||
@@ -393,7 +397,7 @@ public:
|
||||
BOOL needsImpostorUpdate() const;
|
||||
const LLVector3& getImpostorOffset() const;
|
||||
const LLVector2& getImpostorDim() const;
|
||||
void getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const;
|
||||
void getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& distance) const;
|
||||
void cacheImpostorValues();
|
||||
void setImpostorDim(const LLVector2& dim);
|
||||
static void resetImpostors();
|
||||
@@ -404,7 +408,6 @@ private:
|
||||
LLVector3 mImpostorOffset;
|
||||
LLVector2 mImpostorDim;
|
||||
BOOL mNeedsAnimUpdate;
|
||||
LLVector3 mImpostorExtents[2];
|
||||
LLVector3 mImpostorAngle;
|
||||
F32 mImpostorDistance;
|
||||
F32 mImpostorPixelArea;
|
||||
|
||||
@@ -706,23 +706,23 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
|
||||
|
||||
U32 idx0 = 0,idx1 = 0,idx2 = 0;
|
||||
|
||||
if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, &a, &b, &t, FALSE))
|
||||
if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE))
|
||||
{
|
||||
hit = TRUE;
|
||||
idx0 = 0; idx1 = 1; idx2 = 2;
|
||||
}
|
||||
else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, &a, &b, &t, FALSE))
|
||||
else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a, b, t, FALSE))
|
||||
{
|
||||
hit = TRUE;
|
||||
idx0 = 1; idx1 = 3; idx2 = 2;
|
||||
}
|
||||
else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, &a, &b, &t, FALSE))
|
||||
else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, a, b, t, FALSE))
|
||||
{
|
||||
normal1 = -normal1;
|
||||
hit = TRUE;
|
||||
idx0 = 2; idx1 = 1; idx2 = 0;
|
||||
}
|
||||
else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, &a, &b, &t, FALSE))
|
||||
else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, a, b, t, FALSE))
|
||||
{
|
||||
normal1 = -normal1;
|
||||
hit = TRUE;
|
||||
|
||||
@@ -79,12 +79,14 @@ F32 LLVOPartGroup::getBinRadius()
|
||||
return mScale.mV[0]*2.f;
|
||||
}
|
||||
|
||||
void LLVOPartGroup::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax)
|
||||
void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
|
||||
{
|
||||
const LLVector3& pos_agent = getPositionAgent();
|
||||
newMin = pos_agent - mScale;
|
||||
newMax = pos_agent + mScale;
|
||||
mDrawable->setPositionGroup(pos_agent);
|
||||
newMin.load3( (pos_agent - mScale).mV);
|
||||
newMax.load3( (pos_agent + mScale).mV);
|
||||
LLVector4a pos;
|
||||
pos.load3(pos_agent.mV);
|
||||
mDrawable->setPositionGroup(pos);
|
||||
}
|
||||
|
||||
BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
|
||||
|
||||
virtual F32 getBinRadius();
|
||||
virtual void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax);
|
||||
virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
|
||||
virtual U32 getPartitionType() const;
|
||||
|
||||
/*virtual*/ void setPixelAreaAndAngle(LLAgent &agent);
|
||||
|
||||
@@ -944,7 +944,13 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
|
||||
|
||||
//step one meter at a time until intersection point found
|
||||
|
||||
const LLVector3* ext = mDrawable->getSpatialExtents();
|
||||
//VECTORIZE THIS
|
||||
const LLVector4a* exta = mDrawable->getSpatialExtents();
|
||||
|
||||
LLVector3 ext[2];
|
||||
ext[0].set(exta[0].getF32ptr());
|
||||
ext[1].set(exta[1].getF32ptr());
|
||||
|
||||
F32 rad = (delta*tdelta).magVecSquared();
|
||||
|
||||
F32 t = 0.f;
|
||||
@@ -1006,13 +1012,16 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
|
||||
void LLVOSurfacePatch::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
|
||||
{
|
||||
LLVector3 posAgent = getPositionAgent();
|
||||
LLVector3 scale = getScale();
|
||||
newMin = posAgent-scale*0.5f; // Changing to 2.f makes the culling a -little- better, but still wrong
|
||||
newMax = posAgent+scale*0.5f;
|
||||
mDrawable->setPositionGroup((newMin+newMax)*0.5f);
|
||||
newMin.load3( (posAgent-scale*0.5f).mV); // Changing to 2.f makes the culling a -little- better, but still wrong
|
||||
newMax.load3( (posAgent+scale*0.5f).mV);
|
||||
LLVector4a pos;
|
||||
pos.setAdd(newMin,newMax);
|
||||
pos.mul(0.5f);
|
||||
mDrawable->setPositionGroup(pos);
|
||||
}
|
||||
|
||||
U32 LLVOSurfacePatch::getPartitionType() const
|
||||
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
/*virtual*/ void updateTextures();
|
||||
/*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area
|
||||
|
||||
/*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax);
|
||||
/*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
|
||||
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
|
||||
|
||||
void setPatch(LLSurfacePatch *patchp);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llvolume.h"
|
||||
#include "pipeline.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llviewerregion.h"
|
||||
|
||||
LLVOTextBubble::LLVOTextBubble(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
|
||||
|
||||
@@ -1274,7 +1274,7 @@ void LLVOTree::updateRadius()
|
||||
mDrawable->setRadius(32.0f);
|
||||
}
|
||||
|
||||
void LLVOTree::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax)
|
||||
void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
|
||||
{
|
||||
F32 radius = getScale().length()*0.05f;
|
||||
LLVector3 center = getRenderPosition();
|
||||
@@ -1284,9 +1284,11 @@ void LLVOTree::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax)
|
||||
|
||||
center += LLVector3(0, 0, size.mV[2]) * getRotation();
|
||||
|
||||
newMin.set(center-size);
|
||||
newMax.set(center+size);
|
||||
mDrawable->setPositionGroup(center);
|
||||
newMin.load3((center-size).mV);
|
||||
newMax.load3((center+size).mV);
|
||||
LLVector4a pos;
|
||||
pos.load3(center.mV);
|
||||
mDrawable->setPositionGroup(pos);
|
||||
}
|
||||
|
||||
BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
|
||||
@@ -1299,8 +1301,13 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const LLVector3* ext = mDrawable->getSpatialExtents();
|
||||
const LLVector4a* exta = mDrawable->getSpatialExtents();
|
||||
|
||||
//VECTORIZE THIS
|
||||
LLVector3 ext[2];
|
||||
ext[0].set(exta[0].getF32ptr());
|
||||
ext[1].set(exta[1].getF32ptr());
|
||||
|
||||
LLVector3 center = (ext[1]+ext[0])*0.5f;
|
||||
LLVector3 size = (ext[1]-ext[0]);
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
|
||||
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
|
||||
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
|
||||
/*virtual*/ void updateSpatialExtents(LLVector3 &min, LLVector3 &max);
|
||||
/*virtual*/ void updateSpatialExtents(LLVector4a &min, LLVector4a &max);
|
||||
|
||||
virtual U32 getPartitionType() const;
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "llflexibleobject.h"
|
||||
#include "llsky.h"
|
||||
#include "lltexturefetch.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerregion.h"
|
||||
@@ -509,7 +510,7 @@ void LLVOVolume::updateTextureVirtualSize()
|
||||
const LLTextureEntry *te = face->getTextureEntry();
|
||||
LLViewerTexture *imagep = face->getTexture();
|
||||
if (!imagep || !te ||
|
||||
face->mExtents[0] == face->mExtents[1])
|
||||
face->mExtents[0].equals3(face->mExtents[1]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1066,10 +1067,14 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
|
||||
{
|
||||
BOOL res = TRUE;
|
||||
|
||||
LLVector3 min,max;
|
||||
LLVector4a min,max;
|
||||
|
||||
min.clear();
|
||||
max.clear();
|
||||
|
||||
BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION);
|
||||
|
||||
LLVolume* volume = getVolume();
|
||||
for (S32 i = 0; i < getVolume()->getNumFaces(); i++)
|
||||
{
|
||||
LLFace *face = mDrawable->getFace(i);
|
||||
@@ -1077,7 +1082,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
res &= face->genVolumeBBoxes(*getVolume(), i,
|
||||
res &= face->genVolumeBBoxes(*volume, i,
|
||||
mRelativeXform, mRelativeXformInvTrans,
|
||||
(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
|
||||
|
||||
@@ -1090,17 +1095,8 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (face->mExtents[0].mV[i] < min.mV[i])
|
||||
{
|
||||
min.mV[i] = face->mExtents[0].mV[i];
|
||||
}
|
||||
if (face->mExtents[1].mV[i] > max.mV[i])
|
||||
{
|
||||
max.mV[i] = face->mExtents[1].mV[i];
|
||||
}
|
||||
}
|
||||
min.setMin(min, face->mExtents[0]);
|
||||
max.setMax(max, face->mExtents[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1108,7 +1104,9 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
|
||||
if (rebuild)
|
||||
{
|
||||
mDrawable->setSpatialExtents(min,max);
|
||||
mDrawable->setPositionGroup((min+max)*0.5f);
|
||||
min.add(max);
|
||||
min.mul(0.5f);
|
||||
mDrawable->setPositionGroup(min);
|
||||
}
|
||||
|
||||
updateRadius();
|
||||
@@ -1339,12 +1337,12 @@ void LLVOVolume::updateFaceSize(S32 idx)
|
||||
LLFace* facep = mDrawable->getFace(idx);
|
||||
if (idx >= getVolume()->getNumVolumeFaces())
|
||||
{
|
||||
facep->setSize(0,0);
|
||||
facep->setSize(0,0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
|
||||
facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
|
||||
facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size(),true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2072,7 +2070,7 @@ void LLVOVolume::setSelected(BOOL sel)
|
||||
}
|
||||
}
|
||||
|
||||
void LLVOVolume::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax)
|
||||
void LLVOVolume::updateSpatialExtents(LLVector4a& min, LLVector4a& max)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2090,7 +2088,7 @@ F32 LLVOVolume::getBinRadius()
|
||||
const S32 attachment_size_factor = llmax(size_factor_setting.get(),1);
|
||||
const LLVector3& distance_factor = distance_factor_setting;
|
||||
const LLVector3& alpha_distance_factor = alpha_distance_factor_setting;
|
||||
const LLVector3* ext = mDrawable->getSpatialExtents();
|
||||
const LLVector4a* ext = mDrawable->getSpatialExtents();
|
||||
|
||||
BOOL shrink_wrap = mDrawable->isAnimating();
|
||||
BOOL alpha_wrap = FALSE;
|
||||
@@ -2124,7 +2122,10 @@ F32 LLVOVolume::getBinRadius()
|
||||
}
|
||||
else if (shrink_wrap)
|
||||
{
|
||||
radius = (ext[1]-ext[0]).length()*0.5f;
|
||||
LLVector4a rad;
|
||||
rad.setSub(ext[1], ext[0]);
|
||||
|
||||
radius = rad.getLength3().getF32()*0.5f;
|
||||
}
|
||||
else if (mDrawable->isStatic())
|
||||
{
|
||||
@@ -2155,7 +2156,7 @@ const LLVector3 LLVOVolume::getPivotPositionAgent() const
|
||||
return LLViewerObject::getPivotPositionAgent();
|
||||
}
|
||||
|
||||
void LLVOVolume::onShift(const LLVector3 &shift_vector)
|
||||
void LLVOVolume::onShift(const LLVector4a &shift_vector)
|
||||
{
|
||||
if (mVolumeImpl)
|
||||
{
|
||||
@@ -2927,7 +2928,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
{
|
||||
facep->updateRebuildFlags();
|
||||
if (!LLPipeline::sDelayVBUpdate)
|
||||
{
|
||||
{ //copy face geometry into vertex buffer
|
||||
LLDrawable* drawablep = facep->getDrawable();
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
LLVolume* volume = vobj->getVolume();
|
||||
@@ -3122,7 +3123,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
|
||||
{
|
||||
vertex_count += facep->getGeomCount();
|
||||
index_count += facep->getIndicesCount();
|
||||
|
||||
llassert(facep->getIndicesCount() < 65536);
|
||||
//remember face (for sorting)
|
||||
mFaceList.push_back(facep);
|
||||
}
|
||||
@@ -3144,7 +3145,7 @@ LLHUDPartition::LLHUDPartition()
|
||||
mLODPeriod = 1;
|
||||
}
|
||||
|
||||
void LLHUDPartition::shift(const LLVector3 &offset)
|
||||
void LLHUDPartition::shift(const LLVector4a &offset)
|
||||
{
|
||||
//HUD objects don't shift with region crossing. That would be silly.
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0;
|
||||
virtual void onSetScale(const LLVector3 &scale, BOOL damped) = 0;
|
||||
virtual void onParameterChanged(U16 param_type, LLNetworkData *data, BOOL in_use, bool local_origin) = 0;
|
||||
virtual void onShift(const LLVector3 &shift_vector) = 0;
|
||||
virtual void onShift(const LLVector4a &shift_vector) = 0;
|
||||
virtual bool isVolumeUnique() const = 0; // Do we need a unique LLVolume instance?
|
||||
virtual bool isVolumeGlobal() const = 0; // Are we in global space?
|
||||
virtual bool isActive() const = 0; // Is this object currently active?
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
|
||||
void markForUpdate(BOOL priority) { LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; }
|
||||
|
||||
/*virtual*/ void onShift(const LLVector3 &shift_vector); // Called when the drawable shifts
|
||||
/*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts
|
||||
|
||||
/*virtual*/ void parameterChanged(U16 param_type, bool local_origin);
|
||||
/*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
void regenFaces();
|
||||
BOOL genBBoxes(BOOL force_global);
|
||||
void preRebuild();
|
||||
virtual void updateSpatialExtents(LLVector3& min, LLVector3& max);
|
||||
virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
|
||||
virtual F32 getBinRadius();
|
||||
|
||||
virtual U32 getPartitionType() const;
|
||||
|
||||
@@ -267,15 +267,21 @@ void LLVOWater::setIsEdgePatch(const BOOL edge_patch)
|
||||
mIsEdgePatch = edge_patch;
|
||||
}
|
||||
|
||||
void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax)
|
||||
void LLVOWater::updateSpatialExtents(LLVector4a &newMin, LLVector4a& newMax)
|
||||
{
|
||||
LLVector3 pos = getPositionAgent();
|
||||
LLVector3 scale = getScale();
|
||||
LLVector4a pos;
|
||||
pos.load3(getPositionAgent().mV);
|
||||
LLVector4a scale;
|
||||
scale.load3(getScale().mV);
|
||||
scale.mul(0.5f);
|
||||
|
||||
newMin = pos - scale * 0.5f;
|
||||
newMax = pos + scale * 0.5f;
|
||||
newMin.setSub(pos, scale);
|
||||
newMax.setAdd(pos, scale);
|
||||
|
||||
pos.setAdd(newMin,newMax);
|
||||
pos.mul(0.5f);
|
||||
|
||||
mDrawable->setPositionGroup((newMin + newMax) * 0.5f);
|
||||
mDrawable->setPositionGroup(pos);
|
||||
}
|
||||
|
||||
U32 LLVOWater::getPartitionType() const
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
/*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
|
||||
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
|
||||
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
|
||||
/*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax);
|
||||
/*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
|
||||
|
||||
/*virtual*/ void updateTextures();
|
||||
/*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area
|
||||
|
||||
@@ -1566,6 +1566,31 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera
|
||||
return radius*radius * F_PI;
|
||||
}
|
||||
|
||||
//static
|
||||
F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera)
|
||||
{
|
||||
LLVector4a origin;
|
||||
origin.load3(camera.getOrigin().mV);
|
||||
|
||||
LLVector4a lookAt;
|
||||
lookAt.setSub(center, origin);
|
||||
F32 dist = lookAt.getLength3().getF32();
|
||||
|
||||
//ramp down distance for nearby objects
|
||||
//shrink dist by dist/16.
|
||||
if (dist < 16.f)
|
||||
{
|
||||
dist /= 16.f;
|
||||
dist *= dist;
|
||||
dist *= 16.f;
|
||||
}
|
||||
|
||||
//get area of circle around node
|
||||
F32 app_angle = atanf(size.getLength3().getF32()/dist);
|
||||
F32 radius = app_angle*LLDrawable::sCurPixelAngle;
|
||||
return radius*radius * F_PI;
|
||||
}
|
||||
|
||||
void LLPipeline::grabReferences(LLCullResult& result)
|
||||
{
|
||||
sCull = &result;
|
||||
@@ -1980,7 +2005,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
|
||||
}
|
||||
|
||||
if (sMinRenderSize > 0.f &&
|
||||
llmax(llmax(group->mBounds[1].mV[0], group->mBounds[1].mV[1]), group->mBounds[1].mV[2]) < sMinRenderSize)
|
||||
llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -2364,6 +2389,9 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
gDepthDirty = TRUE;
|
||||
|
||||
LLVector4a offseta;
|
||||
offseta.load3(offset.mV);
|
||||
|
||||
for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
|
||||
iter != mShiftList.end(); iter++)
|
||||
{
|
||||
@@ -2372,7 +2400,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
drawablep->shiftPos(offset);
|
||||
drawablep->shiftPos(offseta);
|
||||
drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
|
||||
}
|
||||
mShiftList.resize(0);
|
||||
@@ -2386,7 +2414,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
|
||||
LLSpatialPartition* part = region->getSpatialPartition(i);
|
||||
if (part)
|
||||
{
|
||||
part->shift(offset);
|
||||
part->shift(offseta);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2417,7 +2445,7 @@ void LLPipeline::markGLRebuild(LLGLUpdate* glu)
|
||||
void LLPipeline::markPartitionMove(LLDrawable* drawable)
|
||||
{
|
||||
if (!drawable->isState(LLDrawable::PARTITION_MOVE) &&
|
||||
!drawable->getPositionGroup().isExactlyZero())
|
||||
!drawable->getPositionGroup().equals3(LLVector4a::getZero()))
|
||||
{
|
||||
drawable->setState(LLDrawable::PARTITION_MOVE);
|
||||
mPartitionQ.push_back(drawable);
|
||||
@@ -2985,8 +3013,10 @@ void LLPipeline::postSort(LLCamera& camera)
|
||||
{
|
||||
if (sMinRenderSize > 0.f)
|
||||
{
|
||||
LLVector3 bounds = (*k)->mExtents[1]-(*k)->mExtents[0];
|
||||
if (llmax(llmax(bounds.mV[0], bounds.mV[1]), bounds.mV[2]) > sMinRenderSize)
|
||||
LLVector4a bounds;
|
||||
bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]);
|
||||
|
||||
if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize)
|
||||
{
|
||||
sCull->pushDrawInfo(j->first, *k);
|
||||
}
|
||||
@@ -7247,8 +7277,9 @@ void LLPipeline::renderDeferredLighting()
|
||||
}
|
||||
|
||||
|
||||
LLVector3 center = drawablep->getPositionAgent();
|
||||
F32* c = center.mV;
|
||||
LLVector4a center;
|
||||
center.load3(drawablep->getPositionAgent().mV);
|
||||
const F32* c = center.getF32ptr();
|
||||
F32 s = volume->getLightRadius()*1.5f;
|
||||
|
||||
LLColor3 col = volume->getLightColor();
|
||||
@@ -7264,7 +7295,9 @@ void LLPipeline::renderDeferredLighting()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0)
|
||||
LLVector4a sa;
|
||||
sa.splat(s);
|
||||
if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -7341,8 +7374,9 @@ void LLPipeline::renderDeferredLighting()
|
||||
|
||||
LLVOVolume* volume = drawablep->getVOVolume();
|
||||
|
||||
LLVector3 center = drawablep->getPositionAgent();
|
||||
F32* c = center.mV;
|
||||
LLVector4a center;
|
||||
center.load3(drawablep->getPositionAgent().mV);
|
||||
const F32* c = center.getF32ptr();
|
||||
F32 s = volume->getLightRadius()*1.5f;
|
||||
|
||||
sVisibleLightCount++;
|
||||
@@ -8244,7 +8278,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
|
||||
const LLPlane& cp = camera.getAgentPlane(j);
|
||||
const LLVector3& v1 = pp[bs[i*2+0]];
|
||||
const LLVector3& v2 = pp[bs[i*2+1]];
|
||||
const LLVector3 n(cp.mV);
|
||||
LLVector3 n;
|
||||
cp.getVector3(n);
|
||||
|
||||
LLVector3 line = v1-v2;
|
||||
|
||||
@@ -8258,8 +8293,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
|
||||
LLVector3 intersect = v2+line*t;
|
||||
pp.push_back(intersect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//camera frustum line segments
|
||||
const U32 fs[] =
|
||||
@@ -8290,7 +8325,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
|
||||
const LLVector3& v1 = pp[fs[i*2+0]+8];
|
||||
const LLVector3& v2 = pp[fs[i*2+1]+8];
|
||||
const LLPlane& cp = bp[j];
|
||||
const LLVector3 n(cp.mV);
|
||||
LLVector3 n;
|
||||
cp.getVector3(n);
|
||||
|
||||
LLVector3 line = v1-v2;
|
||||
|
||||
@@ -8305,7 +8341,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
|
||||
pp.push_back(intersect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f),
|
||||
max+LLVector3(0.05f,0.05f,0.05f) };
|
||||
@@ -9339,7 +9375,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
|
||||
|
||||
stateSort(*LLViewerCamera::getInstance(), result);
|
||||
|
||||
const LLVector3* ext = avatar->mDrawable->getSpatialExtents();
|
||||
const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
|
||||
LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
|
||||
|
||||
LLCamera camera = *viewer_camera;
|
||||
@@ -9348,25 +9384,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
|
||||
|
||||
LLVector2 tdim;
|
||||
|
||||
LLVector3 half_height = (ext[1]-ext[0])*0.5f;
|
||||
|
||||
LLVector3 left = camera.getLeftAxis();
|
||||
left *= left;
|
||||
left.normalize();
|
||||
LLVector4a half_height;
|
||||
half_height.setSub(ext[1], ext[0]);
|
||||
half_height.mul(0.5f);
|
||||
|
||||
LLVector3 up = camera.getUpAxis();
|
||||
up *= up;
|
||||
up.normalize();
|
||||
LLVector4a left;
|
||||
left.load3(camera.getLeftAxis().mV);
|
||||
left.mul(left);
|
||||
left.normalize3fast();
|
||||
|
||||
tdim.mV[0] = fabsf(half_height * left);
|
||||
tdim.mV[1] = fabsf(half_height * up);
|
||||
LLVector4a up;
|
||||
up.load3(camera.getUpAxis().mV);
|
||||
up.mul(up);
|
||||
up.normalize3fast();
|
||||
|
||||
tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
|
||||
tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
//glh::matrix4f ortho = gl_ortho(-tdim.mV[0], tdim.mV[0], -tdim.mV[1], tdim.mV[1], 1.0, 256.0);
|
||||
|
||||
F32 distance = (pos-camera.getOrigin()).length();
|
||||
F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
|
||||
F32 aspect = tdim.mV[0]/tdim.mV[1]; //128.f/256.f;
|
||||
F32 aspect = tdim.mV[0]/tdim.mV[1];
|
||||
glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
|
||||
glh_set_current_projection(persp);
|
||||
glLoadMatrixf(persp.m);
|
||||
|
||||
@@ -197,6 +197,7 @@ public:
|
||||
|
||||
//calculate pixel area of given box from vantage point of given camera
|
||||
static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera);
|
||||
static F32 calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera);
|
||||
|
||||
void stateSort(LLCamera& camera, LLCullResult& result);
|
||||
void stateSort(LLSpatialGroup* group, LLCamera& camera);
|
||||
|
||||
Reference in New Issue
Block a user