Vectorized llvolumeface while maintining strided vertexbuffers.

This commit is contained in:
Shyotl
2011-07-22 04:29:19 -05:00
parent 48ef9904c1
commit 07c892480a
16 changed files with 1956 additions and 584 deletions

View File

@@ -299,7 +299,7 @@ public:
{
if (data == NULL)
{
//OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl;
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl;
return false;
}
LLOctreeNode<T>* parent = getOctParent();
@@ -389,7 +389,7 @@ public:
else
{
//it's not in here, give it to the root
//OCT_ERRS << "Octree insertion failed, starting over from root!" << llendl;
OCT_ERRS << "Octree insertion failed, starting over from root!" << llendl;
oct_node* node = this;
@@ -590,7 +590,7 @@ public:
}
}
//OCT_ERRS << "Octree failed to delete requested child." << llendl;
OCT_ERRS << "Octree failed to delete requested child." << llendl;
}
protected:
@@ -670,13 +670,13 @@ public:
{
if (data == NULL)
{
//OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE ROOT !!!" << llendl;
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE ROOT !!!" << llendl;
return false;
}
if (data->getBinRadius() > 4096.0)
{
//OCT_ERRS << "!!! ELEMENT EXCEEDS MAXIMUM SIZE IN OCTREE ROOT !!!" << llendl;
OCT_ERRS << "!!! ELEMENT EXCEEDS MAXIMUM SIZE IN OCTREE ROOT !!!" << llendl;
return false;
}
@@ -692,7 +692,7 @@ public:
if (lt != 0x7)
{
//OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl;
OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl;
return false;
}

File diff suppressed because it is too large Load Diff

View File

@@ -40,8 +40,13 @@ class LLPathParams;
class LLVolumeParams;
class LLProfile;
class LLPath;
template <class T> class LLOctreeNode;
class LLVector4a;
class LLVolumeFace;
class LLVolume;
class LLVolumeTriangle;
#include "lldarray.h"
#include "lluuid.h"
@@ -800,20 +805,84 @@ class LLVolumeFace
public:
class VertexData
{
enum
{
POSITION = 0,
NORMAL = 1
};
private:
void init();
public:
LLVector3 mPosition;
LLVector3 mNormal;
LLVector3 mBinormal;
VertexData();
VertexData(const VertexData& rhs);
const VertexData& operator=(const VertexData& rhs);
~VertexData();
LLVector4a& getPosition();
LLVector4a& getNormal();
const LLVector4a& getPosition() const;
const LLVector4a& getNormal() const;
void setPosition(const LLVector4a& pos);
void setNormal(const LLVector4a& norm);
LLVector2 mTexCoord;
bool operator<(const VertexData& rhs) const;
bool operator==(const VertexData& rhs) const;
bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const;
private:
LLVector4a* mData;
};
LLVolumeFace();
LLVolumeFace(const LLVolumeFace& src);
LLVolumeFace& operator=(const LLVolumeFace& rhs);
~LLVolumeFace();
private:
void freeData();
public:
BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
void createBinormals();
void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform);
void resizeVertices(S32 num_verts);
void allocateBinormals(S32 num_verts);
void resizeIndices(S32 num_indices);
void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx);
void pushVertex(const VertexData& cv);
void pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc);
void pushIndex(const U16& idx);
void swapData(LLVolumeFace& rhs);
void getVertexData(U16 indx, LLVolumeFace::VertexData& cv);
class VertexMapData : public LLVolumeFace::VertexData
{
public:
U16 mIndex;
bool operator==(const LLVolumeFace::VertexData& rhs) const;
struct ComparePosition
{
bool operator()(const LLVector3& a, const LLVector3& b) const;
};
typedef std::map<LLVector3, std::vector<VertexMapData>, VertexMapData::ComparePosition > PointMap;
};
void optimize(F32 angle_cutoff = 2.f);
void cacheOptimize();
void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f));
enum
{
@@ -833,7 +902,6 @@ public:
public:
S32 mID;
U32 mTypeMask;
BOOL mHasBinormals;
// Only used for INNER/OUTER faces
S32 mBeginS;
@@ -845,9 +913,17 @@ public:
LLVector4a* mCenter;
LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
std::vector<VertexData> mVertices;
std::vector<U16> mIndices;
S32 mNumVertices;
S32 mNumIndices;
LLVector4a* mPositions;
LLVector4a* mNormals;
LLVector4a* mBinormals;
LLVector2* mTexCoords;
U16* mIndices;
std::vector<S32> mEdge;
LLOctreeNode<LLVolumeTriangle>* mOctree;
private:
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
@@ -882,7 +958,7 @@ public:
U8 getProfileType() const { return mParams.getProfileParams().getCurveType(); }
U8 getPathType() const { return mParams.getPathParams().getCurveType(); }
S32 getNumFaces() const { return (S32)mProfilep->mFaces.size(); }
S32 getNumFaces() const;
S32 getNumVolumeFaces() const { return mVolumeFaces.size(); }
F32 getDetail() const { return mDetail; }
const LLVolumeParams& getParams() const { return mParams; }
@@ -965,6 +1041,9 @@ public:
LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level);
void copyVolumeFaces(const LLVolume* volume);
void cacheOptimize();
private:
void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
F32 sculptGetSurfaceArea();
@@ -993,12 +1072,13 @@ protected:
std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
LLVector3 calc_binormal_from_triangle(
const LLVector3& pos0,
void calc_binormal_from_triangle(
LLVector4a& binormal,
const LLVector4a& pos0,
const LLVector2& tex0,
const LLVector3& pos1,
const LLVector4a& pos1,
const LLVector2& tex1,
const LLVector3& pos2,
const LLVector4a& pos2,
const LLVector2& tex2);
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);

View File

@@ -74,8 +74,6 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, c
return (grt & 0x7) ? false : true;
}
#if 0 //MESH
LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node)
{
node->addListener(this);
@@ -122,7 +120,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
if (LLLineSegmentBoxIntersect(mStart.getF32ptr(), mEnd.getF32ptr(), vl->mBounds[0].getF32ptr(), vl->mBounds[1].getF32ptr()))
{
node->accept(this);
for (S32 i = 0; i < node->getChildCount(); ++i)
for (U32 i = 0; i < node->getChildCount(); ++i)
{
traverse(node->getChild(i));
}
@@ -253,5 +251,5 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
}
}
}
#endif

View File

@@ -34,7 +34,6 @@
#include "llvolume.h"
#include "llvector4a.h"
#if 0 //MESH
class LLVolumeTriangle : public LLRefCount
{
public:
@@ -131,5 +130,5 @@ class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle>
{
virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch);
};
#endif //0
#endif

View File

@@ -431,7 +431,8 @@ public:
void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); }
void setSearchCallback(void (*search_callback)(const std::string& search_string, void* user_data), void* data) { mSearchCallback = search_callback; mCallbackUserData = data; }
typedef boost::function<void (const std::string&, void *)> search_callback_t;
void setSearchCallback(search_callback_t cb,void *user_data) { mSearchCallback = boost::bind(cb,_1,user_data); }
// LLUICtrl interface
virtual void setValue(const LLSD& value );
@@ -446,7 +447,8 @@ private:
LLLineEditor* mSearchEdit;
class LLButton* mClearSearchButton;
void (*mSearchCallback)(const std::string& search_string, void* user_data);
search_callback_t mSearchCallback;
};

View File

@@ -730,8 +730,8 @@ void LLPreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
}
const LLVolumeFace &vf = mVolume->getVolumeFace(0);
U32 num_indices = vf.mIndices.size();
U32 num_vertices = vf.mVertices.size();
U32 num_indices = vf.mNumIndices;
U32 num_vertices = vf.mNumVertices;
mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL, 0);
mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE);
@@ -747,8 +747,8 @@ void LLPreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
// build vertices and normals
for (U32 i = 0; (S32)i < num_vertices; i++)
{
*(vertex_strider++) = vf.mVertices[i].mPosition;
LLVector3 normal = vf.mVertices[i].mNormal;
(vertex_strider++)->set(vf.mPositions[i].getF32ptr());
LLVector3 normal(vf.mNormals[i].getF32ptr());
normal.normalize();
*(normal_strider++) = normal;
}
@@ -812,7 +812,7 @@ BOOL LLPreviewSculpted::render()
LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
const LLVolumeFace &vf = mVolume->getVolumeFace(0);
U32 num_indices = vf.mIndices.size();
U32 num_indices = vf.mNumIndices;
mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL);

View File

@@ -924,10 +924,8 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po
{
const LLMatrix4& vol_mat = getWorldMatrix();
const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
LLVector4a normal4a;
normal4a.load3(vf.mVertices[0].mNormal.mV);
LLVector4a binormal4a;
binormal4a.load3(vf.mVertices[0].mBinormal.mV);
const LLVector4a& normal4a = vf.mNormals[0];
const LLVector4a& binormal4a = vf.mBinormals[0];
LLVector2 projected_binormal;
planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);
projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform()
@@ -1041,14 +1039,14 @@ bool LLFace::canRenderAsMask()
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
const S32 &f,
const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,
const LLMatrix4& mat_vert_in, const LLMatrix3& mat_norm_in,
const U16 &index_offset,
bool force_rebuild)
{
llassert(verify());
const LLVolumeFace &vf = volume.getVolumeFace(f);
S32 num_vertices = (S32)vf.mVertices.size();
S32 num_indices = (S32)vf.mIndices.size();
S32 num_vertices = (S32)vf.mNumVertices;
S32 num_indices = (S32) vf.mNumIndices;
if (mVertexBuffer.notNull())
{
@@ -1081,7 +1079,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLStrider<LLVector3> binormals;
LLStrider<U16> indicesp;
BOOL full_rebuild = mDrawablep->isState(LLDrawable::REBUILD_VOLUME);
BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME);
BOOL global_volume = mDrawablep->getVOVolume()->isVolumeGlobal();
LLVector3 scale;
@@ -1094,11 +1092,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
scale = mVObjp->getScale();
}
BOOL rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION);
BOOL rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR);
BOOL rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
BOOL rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
BOOL rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL);
bool rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION);
bool rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR);
bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL);
const LLTextureEntry *tep = mVObjp->getTE(f);
if (!tep) rebuild_color = FALSE; // can't get color when tep is NULL
@@ -1130,7 +1129,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->getColorStrider(colors, mGeomIndex);
}
F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
BOOL is_static = mDrawablep->isStatic();
BOOL is_global = is_static;
@@ -1146,59 +1144,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
clearState(GLOBAL);
}
LLVector2 tmin, tmax;
if (rebuild_tcoord)
{
if (tep)
{
r = tep->getRotation();
os = tep->mOffsetS;
ot = tep->mOffsetT;
ms = tep->mScaleS;
mt = tep->mScaleT;
cos_ang = cos(r);
sin_ang = sin(r);
}
else
{
cos_ang = 1.0f;
sin_ang = 0.0f;
os = 0.0f;
ot = 0.0f;
ms = 1.0f;
mt = 1.0f;
}
}
U8 tex_mode = 0;
if (isState(TEXTURE_ANIM))
{
LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
tex_mode = vobj->mTexAnimMode;
if (!tex_mode)
{
clearState(TEXTURE_ANIM);
}
else
{
os = ot = 0.f;
r = 0.f;
cos_ang = 1.f;
sin_ang = 0.f;
ms = mt = 1.f;
}
if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
{ //don't override texture transform during tc bake
tex_mode = 0;
}
}
LLColor4U color = (tep ? LLColor4U(tep->getColor()) : LLColor4U::white);
if (rebuild_color) // FALSE if tep == NULL
@@ -1226,167 +1171,361 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
for (U32 i = 0; i < (U32) num_indices; i++)
{
*indicesp++ = vf.mIndices[i] + index_offset;
indicesp[i] = vf.mIndices[i] + index_offset;
}
}
LLMatrix4a mat_normal;
mat_normal.loadu(mat_norm_in);
//bump setup
LLVector3 binormal_dir( -sin_ang, cos_ang, 0 );
LLVector3 bump_s_primary_light_ray;
LLVector3 bump_t_primary_light_ray;
//if it's not fullbright and has no normals, bake sunlight based on face normal
//bool bake_sunlight = !getTextureEntry()->getFullbright() &&
// !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
LLQuaternion bump_quat;
if (mDrawablep->isActive())
F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
if (rebuild_tcoord)
{
bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
}
if (bump_code)
{
mVObjp->getVolume()->genBinormals(f);
F32 offset_multiple;
switch( bump_code )
bool do_xform;
if (tep)
{
case BE_NO_BUMP:
offset_multiple = 0.f;
break;
case BE_BRIGHTNESS:
case BE_DARKNESS:
if( mTexture.notNull() && mTexture->hasGLTexture())
r = tep->getRotation();
os = tep->mOffsetS;
ot = tep->mOffsetT;
ms = tep->mScaleS;
mt = tep->mScaleT;
cos_ang = cos(r);
sin_ang = sin(r);
if (cos_ang != 1.f ||
sin_ang != 0.f ||
os != 0.f ||
ot != 0.f ||
ms != 1.f ||
mt != 1.f)
{
// Offset by approximately one texel
S32 cur_discard = mTexture->getDiscardLevel();
S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
max_size <<= cur_discard;
const F32 ARTIFICIAL_OFFSET = 2.f;
offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
do_xform = true;
}
else
{
offset_multiple = 1.f/256;
}
break;
default: // Standard bumpmap textures. Assumed to be 256x256
offset_multiple = 1.f / 256;
break;
}
F32 s_scale = 1.f;
F32 t_scale = 1.f;
if( tep )
{
tep->getScale( &s_scale, &t_scale );
}
// Use the nudged south when coming from above sun angle, such
// that emboss mapping always shows up on the upward faces of cubes when
// it's noon (since a lot of builders build with the sun forced to noon).
LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir;
LLVector3 moon_ray = gSky.getMoonDirection();
LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
bump_s_primary_light_ray = offset_multiple * s_scale * primary_light_ray;
bump_t_primary_light_ray = offset_multiple * t_scale * primary_light_ray;
}
U8 texgen = getTextureEntry()->getTexGen();
if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{ //planar texgen needs binormals
mVObjp->getVolume()->genBinormals(f);
}
LLVector4a scalea;
scalea.load3(scale.mV);
for (S32 i = 0; i < num_vertices; i++)
{
if (rebuild_tcoord)
{
LLVector2 tc = vf.mVertices[i].mTexCoord;
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
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, norm, *(vf.mCenter), vec);
break;
case LLTextureEntry::TEX_GEN_SPHERICAL:
sphericalProjection(tc, norm, *(vf.mCenter), vec);
break;
case LLTextureEntry::TEX_GEN_CYLINDRICAL:
cylindricalProjection(tc, norm, *(vf.mCenter), vec);
break;
default:
break;
}
}
if (tex_mode && mTextureMatrix)
{
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
}
else
{
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
}
*tex_coords++ = tc;
if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
{
LLVector3 tangent = vf.mVertices[i].mBinormal % vf.mVertices[i].mNormal;
LLMatrix3 tangent_to_object;
tangent_to_object.setRows(tangent, vf.mVertices[i].mBinormal, vf.mVertices[i].mNormal);
LLVector3 binormal = binormal_dir * tangent_to_object;
binormal = binormal * mat_normal;
if (mDrawablep->isActive())
{
binormal *= bump_quat;
}
binormal.normVec();
tc += LLVector2( bump_s_primary_light_ray * tangent, bump_t_primary_light_ray * binormal );
*tex_coords2++ = tc;
do_xform = false;
}
}
else
{
do_xform = false;
}
//bump setup
LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f);
LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f);
LLQuaternion bump_quat;
if (mDrawablep->isActive())
{
bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
}
if (bump_code)
{
mVObjp->getVolume()->genBinormals(f);
F32 offset_multiple;
switch( bump_code )
{
case BE_NO_BUMP:
offset_multiple = 0.f;
break;
case BE_BRIGHTNESS:
case BE_DARKNESS:
if( mTexture.notNull() && mTexture->hasGLTexture())
{
// Offset by approximately one texel
S32 cur_discard = mTexture->getDiscardLevel();
S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
max_size <<= cur_discard;
const F32 ARTIFICIAL_OFFSET = 2.f;
offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
}
else
{
offset_multiple = 1.f/256;
}
break;
default: // Standard bumpmap textures. Assumed to be 256x256
offset_multiple = 1.f / 256;
break;
}
F32 s_scale = 1.f;
F32 t_scale = 1.f;
if( tep )
{
tep->getScale( &s_scale, &t_scale );
}
// Use the nudged south when coming from above sun angle, such
// that emboss mapping always shows up on the upward faces of cubes when
// it's noon (since a lot of builders build with the sun forced to noon).
LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir;
LLVector3 moon_ray = gSky.getMoonDirection();
LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV);
bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
}
U8 texgen = getTextureEntry()->getTexGen();
if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{ //planar texgen needs binormals
mVObjp->getVolume()->genBinormals(f);
}
U8 tex_mode = 0;
if (isState(TEXTURE_ANIM))
{
LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
tex_mode = vobj->mTexAnimMode;
if (!tex_mode)
{
clearState(TEXTURE_ANIM);
}
else
{
os = ot = 0.f;
r = 0.f;
cos_ang = 1.f;
sin_ang = 0.f;
ms = mt = 1.f;
do_xform = false;
}
if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
{ //don't override texture transform during tc bake
tex_mode = 0;
}
}
LLVector4a scalea;
scalea.load3(scale.mV);
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
bool do_tex_mat = tex_mode && mTextureMatrix;
if (!do_bump)
{ //not in atlas or not bump mapped, might be able to do a cheap update
if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
{
if (!do_tex_mat)
{
/*if (!do_xform)
{
LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
}
else*/
{
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
if(do_xform)
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
*tex_coords++ = tc;
}
}
}
else
{ //do tex mat, no texgen, no atlas, no bump
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
//LLVector4a& norm = vf.mNormals[i];
//LLVector4a& center = *(vf.mCenter);
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
*tex_coords++ = tc;
}
}
}
else
{ //no bump, no atlas, tex gen planar
if (do_tex_mat)
{
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
LLVector4a& norm = vf.mNormals[i];
LLVector4a& center = *(vf.mCenter);
LLVector4a vec = vf.mPositions[i];
vec.mul(scalea);
planarProjection(tc, norm, center, vec);
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
*tex_coords++ = tc;
}
}
else
{
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
LLVector4a& norm = vf.mNormals[i];
LLVector4a& center = *(vf.mCenter);
LLVector4a vec = vf.mPositions[i];
vec.mul(scalea);
planarProjection(tc, norm, center, vec);
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
*tex_coords++ = tc;
}
}
}
}
else
{ //either bump mapped or in atlas, just do the whole expensive loop
std::vector<LLVector2> bump_tc;
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
if (rebuild_pos)
{
*vertices++ = vf.mVertices[i].mPosition * mat_vert;
}
LLVector4a& norm = vf.mNormals[i];
LLVector4a& center = *(vf.mCenter);
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
LLVector4a vec = vf.mPositions[i];
vec.mul(scalea);
switch (texgen)
{
case LLTextureEntry::TEX_GEN_PLANAR:
planarProjection(tc, norm, center, vec);
break;
case LLTextureEntry::TEX_GEN_SPHERICAL:
sphericalProjection(tc, norm, center, vec);
break;
case LLTextureEntry::TEX_GEN_CYLINDRICAL:
cylindricalProjection(tc, norm, center, vec);
break;
default:
break;
}
}
if (tex_mode && mTextureMatrix)
{
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
}
else
{
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
}
*tex_coords++ = tc;
if (do_bump)
{
bump_tc.push_back(tc);
}
}
if (do_bump)
{
if (rebuild_normal)
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a tangent;
tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]);
LLMatrix4a tangent_to_object;
tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]);
LLVector4a t;
tangent_to_object.rotate(binormal_dir, t);
LLVector4a binormal;
mat_normal.rotate(t, binormal);
//VECTORIZE THIS
if (mDrawablep->isActive())
{
LLVector3 t;
t.set(binormal.getF32ptr());
t *= bump_quat;
binormal.load3(t.mV);
}
binormal.normalize3fast();
LLVector2 tc = bump_tc[i];
tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
*tex_coords2++ = tc;
}
}
}
}
if (rebuild_pos)
{
LLMatrix4a mat_vert;
mat_vert.loadu(mat_vert_in);
LLVector4a* src = vf.mPositions;
LLVector4a position;
for (S32 i = 0; i < num_vertices; i++)
{
LLVector3 normal = vf.mVertices[i].mNormal * mat_normal;
normal.normVec();
mat_vert.affineTransform(src[i], position);
vertices[i].set(position.getF32ptr());
}
*normals++ = normal;
}
}
if (rebuild_binormal)
{
LLVector3 binormal = vf.mVertices[i].mBinormal * mat_normal;
binormal.normVec();
*binormals++ = binormal;
if (rebuild_normal)
{
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a normal;
mat_normal.rotate(vf.mNormals[i], normal);
normal.normalize3fast();
normals[i].set(normal.getF32ptr());
}
}
if (rebuild_color)
if (rebuild_binormal)
{
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a binormal;
mat_normal.rotate(vf.mBinormals[i], binormal);
binormal.normalize3fast();
binormals[i].set(binormal.getF32ptr());
}
}
if (rebuild_color)
{
for (S32 i = 0; i < num_vertices; i++)
{
*colors++ = color;
colors[i] = color;
}
}
@@ -1395,7 +1534,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mTexExtents[0].setVec(0,0);
mTexExtents[1].setVec(1,1);
xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt);
xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);
xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);
F32 es = vf.mTexCoordExtents[1].mV[0] - vf.mTexCoordExtents[0].mV[0] ;
F32 et = vf.mTexCoordExtents[1].mV[1] - vf.mTexCoordExtents[0].mV[1] ;

View File

@@ -348,24 +348,7 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename)
{
std::string exten = gDirUtilp->getExtension(src_filename);
U32 codec = IMG_CODEC_INVALID;
std::string temp_str;
if( exten == "bmp")
{
codec = IMG_CODEC_BMP;
}
else if( exten == "tga")
{
codec = IMG_CODEC_TGA;
}
else if( exten == "jpg" || exten == "jpeg")
{
codec = IMG_CODEC_JPEG;
}
else if( exten == "png" )
{
codec = IMG_CODEC_PNG;
}
U32 codec = LLImageBase::getCodecFromExtension(exten);
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
@@ -854,8 +837,8 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
}
const LLVolumeFace &vf = mVolume->getVolumeFace(0);
U32 num_indices = vf.mIndices.size();
U32 num_vertices = vf.mVertices.size();
U32 num_indices = vf.mNumIndices;
U32 num_vertices = vf.mNumVertices;
mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL, 0);
mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE);
@@ -869,12 +852,12 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
mVertexBuffer->getIndexStrider(index_strider);
// build vertices and normals
for (U32 i = 0; (S32)i < num_vertices; i++)
for (U32 i = 0; (U32)i < num_vertices; i++)
{
*(vertex_strider++) = vf.mVertices[i].mPosition;
LLVector3 normal = vf.mVertices[i].mNormal;
normal.normalize();
*(normal_strider++) = normal;
(vertex_strider++)->set(vf.mPositions[i].getF32ptr());
LLVector4a normal(vf.mNormals[i]);
normal.normalize3fast();
(normal_strider++)->set(normal.getF32ptr());
}
// build indices
@@ -936,7 +919,7 @@ BOOL LLImagePreviewSculpted::render()
LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
const LLVolumeFace &vf = mVolume->getVolumeFace(0);
U32 num_indices = vf.mIndices.size();
U32 num_indices = (U32)vf.mNumIndices;
mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL);
@@ -948,8 +931,7 @@ BOOL LLImagePreviewSculpted::render()
gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
gGL.popMatrix();
gGL.popMatrix();
return TRUE;
}

View File

@@ -1426,20 +1426,24 @@ BOOL LLPolyMesh::loadOBJ(LLFILE *fp)
S32 f1 = faces[f][1];
S32 f2 = faces[f][2];
LLVector3& v0 = coords[f0];
LLVector3& v1 = coords[f1];
LLVector3& v2 = coords[f2];
LLVector4a v0;
LLVector4a v1;
LLVector4a v2;
v0.load3(coords[f0].mV);;
v1.load3(coords[f1].mV);;
v2.load3(coords[f2].mV);;
LLVector2& t0 = tex[f0];
LLVector2& t1 = tex[f1];
LLVector2& t2 = tex[f2];
LLVector3 binorm = calc_binormal_from_triangle(v0, t0, v1, t1, v2, t2);
binorm.normVec();
LLVector4a binorm;
calc_binormal_from_triangle(binorm, v0, t0, v1, t1, v2, t2);
binorm.normalize3fast();
binormals[f0] += binorm;
binormals[f1] += binorm;
binormals[f2] += binorm;
LLVector3 binormdelta(binorm.getF32ptr());
binormals[f0] += binormdelta;
binormals[f1] += binormdelta;
binormals[f2] += binormdelta;
}
for ( v=0; v<nverts; v++)

View File

@@ -2378,9 +2378,8 @@ void pushVerts(LLVolume* volume)
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]);
glVertexPointer(3, GL_FLOAT, 16, face.mPositions);
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
}
}

View File

@@ -71,6 +71,18 @@ protected:
~LLDrawInfo();
public:
LLDrawInfo(const LLDrawInfo& rhs)
{
*this = rhs;
}
const LLDrawInfo& operator=(const LLDrawInfo& rhs)
{
llerrs << "Illegal operation!" << llendl;
return *this;
}
LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
LLViewerTexture* image, LLVertexBuffer* buffer,
BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
@@ -164,6 +176,18 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable>
friend class LLSpatialPartition;
friend class LLOctreeStateCheck;
public:
LLSpatialGroup(const LLSpatialGroup& rhs)
{
*this = rhs;
}
const LLSpatialGroup& operator=(const LLSpatialGroup& rhs)
{
llerrs << "Illegal operation!" << llendl;
return *this;
}
static std::set<GLuint> sPendingQueries; //pending occlusion queries
static U32 sNodeCount;
static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE
@@ -173,7 +197,7 @@ public:
typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t;
typedef std::map<U32, drawmap_elem_t > draw_map_t;
typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t;
typedef std::map<LLPointer<LLViewerTexture>, buffer_list_t> buffer_texture_map_t;
typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t;
typedef std::map<U32, buffer_texture_map_t> buffer_map_t;
typedef LLOctreeListener<LLDrawable> BaseType;

View File

@@ -773,10 +773,9 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
for (U32 v = 0; v < face.mVertices.size(); v++)
for (U32 v = 0; v < (U32)face.mNumVertices; v++)
{
LLVector4a src_vec;
src_vec.load3(face.mVertices[v].mPosition.mV);
const LLVector4a& src_vec = face.mPositions[v];
LLVector4a vec;
mata.affineTransform(src_vec, vec);

View File

@@ -216,7 +216,7 @@ void LLVOTextBubble::updateFaceSize(S32 idx)
else
{
const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
face->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
}
}
@@ -234,19 +234,27 @@ void LLVOTextBubble::getGeometry(S32 idx,
const LLVolumeFace& face = getVolume()->getVolumeFace(idx);
LLVector3 pos = getPositionAgent();
LLVector4a pos;
pos.load3(getPositionAgent().mV);
LLVector4a scale;
scale.load3(getScale().mV);
LLColor4U color = LLColor4U(getTE(idx)->getColor());
U32 offset = mDrawable->getFace(idx)->getGeomIndex();
for (U32 i = 0; i < face.mVertices.size(); i++)
for (U32 i = 0; i < (U32)face.mNumVertices; i++)
{
*verticesp++ = face.mVertices[i].mPosition.scaledVec(getScale()) + pos;
*normalsp++ = face.mVertices[i].mNormal;
*texcoordsp++ = face.mVertices[i].mTexCoord;
LLVector4a vertpos;
vertpos.setMul(face.mPositions[i],scale);
vertpos.add(pos);
(verticesp++)->set(vertpos.getF32ptr());
(normalsp++)->set(face.mNormals[i].getF32ptr());
*texcoordsp++ = face.mTexCoords[i];
*colorsp++ = color;
}
for (U32 i = 0; i < face.mIndices.size(); i++)
for (U32 i = 0; i < (U32)face.mNumIndices; i++)
{
*indicesp++ = face.mIndices[i] + offset;
}

View File

@@ -1342,7 +1342,9 @@ void LLVOVolume::updateFaceSize(S32 idx)
else
{
const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size(),true);
facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,
true); // <--- volume faces should be padded for 16-byte alignment
}
}
@@ -2033,6 +2035,49 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
return mDrawable->getWorldMatrix();
}
U32 LLVOVolume::getTriangleCount()
{
U32 count = 0;
LLVolume* volume = getVolume();
if (volume)
{
count = volume->getNumTriangles();
}
return count;
}
U32 LLVOVolume::getHighLODTriangleCount()
{
U32 ret = 0;
LLVolume* volume = getVolume();
if (!isSculpted())
{
LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
ret = ref->getNumTriangles();
LLPrimitive::getVolumeManager()->unrefVolume(ref);
}
/*else if (isMesh())
{
LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
if (ref->isTetrahedron() || ref->getNumVolumeFaces() == 0)
{
gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH);
}
ret = ref->getNumTriangles();
LLPrimitive::getVolumeManager()->unrefVolume(ref);
}*/
else
{ //default sculpts have a constant number of triangles
ret = 31*2*31; //31 rows of 31 columns of quads for a 32x32 vertex patch
}
return ret;
}
//static
void LLVOVolume::preUpdateGeom()
{
@@ -2070,7 +2115,7 @@ void LLVOVolume::setSelected(BOOL sel)
}
}
void LLVOVolume::updateSpatialExtents(LLVector4a& min, LLVector4a& max)
void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
{
}
@@ -2805,6 +2850,32 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
}
}
struct CompareBatchBreakerModified
{
bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
{
const LLTextureEntry* lte = lhs->getTextureEntry();
const LLTextureEntry* rte = rhs->getTextureEntry();
if (lte->getBumpmap() != rte->getBumpmap())
{
return lte->getBumpmap() < rte->getBumpmap();
}
else if (lte->getFullbright() != rte->getFullbright())
{
return lte->getFullbright() < rte->getFullbright();
}
else if (lte->getGlow() != rte->getGlow())
{
return lte->getGlow() < rte->getGlow();
}
else
{
return lhs->getTexture() < rhs->getTexture();
}
}
};
void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort)
{
//calculate maximum number of vertices to store in a single buffer
@@ -2815,7 +2886,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
if (!distance_sort)
{
//sort faces by things that break batches
std::sort(faces.begin(), faces.end(), LLFace::CompareBatchBreaker());
std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
}
else
{
@@ -2859,7 +2930,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 index_count = facep->getIndicesCount();
U32 geom_count = facep->getGeomCount();
//sum up vertices needed for this texture
//sum up vertices needed for this render batch
std::vector<LLFace*>::iterator i = face_iter;
++i;
@@ -2880,7 +2951,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
//create/delete/resize vertex buffer if needed
LLVertexBuffer* buffer = NULL;
LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(tex);
LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);
if (found_iter != group->mBufferMap[mask].end())
{
@@ -2911,7 +2982,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
}
buffer_map[mask][tex].push_back(buffer);
buffer_map[mask][*face_iter].push_back(buffer);
//add face geometry

View File

@@ -118,6 +118,8 @@ public:
/*virtual*/ const LLMatrix4 getRenderMatrix() const;
/*virtual*/ U32 getTriangleCount();
/*virtual*/ U32 getHighLODTriangleCount();
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,