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:
Shyotl
2011-07-20 06:07:13 -05:00
parent 35e0b9b6ff
commit a994df7265
49 changed files with 1533 additions and 765 deletions

View File

@@ -38,6 +38,8 @@
#include <iosfwd>
#include <string>
#include "llpreprocessor.h"
#include "stdtypes.h"
/**

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -34,6 +34,7 @@
#include "stdtypes.h"
#include "xform.h"
#include "llmemory.h"
#include <vector>
template <class T> class LLTreeNode;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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");

View File

@@ -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
}

View File

@@ -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;

View File

@@ -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 &center, 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
{

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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; }

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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))

View File

@@ -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))

View File

@@ -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:

View File

@@ -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)

View File

@@ -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) { }
//////////////////////////////////////
//

View File

@@ -161,8 +161,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_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;

View File

@@ -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];

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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)

View File

@@ -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]);

View File

@@ -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;

View File

@@ -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.
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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);