Vectorized llvolumeface while maintining strided vertexbuffers.
This commit is contained in:
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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] ;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user