summaryrefslogtreecommitdiff
path: root/indra/llmath/llvolume.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmath/llvolume.h')
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvolume.h322
1 files changed, 219 insertions, 103 deletions
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index d9f80f0e30..c8476f6897 100644..100755
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -2,31 +2,25 @@
* @file llvolume.h
* @brief LLVolume base class.
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -40,20 +34,29 @@ class LLPathParams;
class LLVolumeParams;
class LLProfile;
class LLPath;
+
+template <class T> class LLOctreeNode;
+
class LLVolumeFace;
class LLVolume;
+class LLVolumeTriangle;
-#include "lldarray.h"
#include "lluuid.h"
#include "v4color.h"
//#include "vmath.h"
#include "v2math.h"
#include "v3math.h"
+#include "v3dmath.h"
+#include "v4math.h"
+#include "llvector4a.h"
+#include "llmatrix4a.h"
#include "llquaternion.h"
#include "llstrider.h"
#include "v4coloru.h"
#include "llrefcount.h"
+#include "llpointer.h"
#include "llfile.h"
+#include "llalignedarray.h"
//============================================================================
@@ -183,12 +186,14 @@ const U8 LL_SCULPT_TYPE_SPHERE = 1;
const U8 LL_SCULPT_TYPE_TORUS = 2;
const U8 LL_SCULPT_TYPE_PLANE = 3;
const U8 LL_SCULPT_TYPE_CYLINDER = 4;
-
-const U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE | LL_SCULPT_TYPE_CYLINDER;
+const U8 LL_SCULPT_TYPE_MESH = 5;
+const U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE |
+ LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH;
const U8 LL_SCULPT_FLAG_INVERT = 64;
const U8 LL_SCULPT_FLAG_MIRROR = 128;
+const S32 LL_SCULPT_MESH_MAX_FACES = 8;
class LLProfileParams
{
@@ -575,6 +580,9 @@ public:
BOOL importLegacyStream(std::istream& input_stream);
BOOL exportLegacyStream(std::ostream& output_stream) const;
+ LLSD sculptAsLLSD() const;
+ bool sculptFromLLSD(LLSD& sd);
+
LLSD asLLSD() const;
operator LLSD() const { return asLLSD(); }
bool fromLLSD(LLSD& sd);
@@ -634,7 +642,8 @@ public:
const F32& getSkew() const { return mPathParams.getSkew(); }
const LLUUID& getSculptID() const { return mSculptID; }
const U8& getSculptType() const { return mSculptType; }
-
+ bool isSculpt() const;
+ bool isMeshSculpt() const;
BOOL isConvex() const;
// 'begin' and 'end' should be in range [0, 1] (they will be clamped)
@@ -683,6 +692,9 @@ public:
BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
BOOL isOpen() const { return mOpen; }
void setDirty() { mDirty = TRUE; }
+
+ static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
+ BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
BOOL isConcave() const { return mConcave; }
@@ -697,16 +709,17 @@ public:
LLFaceID mFaceID;
};
- std::vector<LLVector3> mProfile;
- std::vector<LLVector2> mNormals;
+ LLAlignedArray<LLVector4a, 64> mProfile;
+ //LLAlignedArray<LLVector4a, 64> mNormals;
std::vector<Face> mFaces;
- std::vector<LLVector3> mEdgeNormals;
- std::vector<LLVector3> mEdgeCenters;
+
+ //LLAlignedArray<LLVector4a, 64> mEdgeNormals;
+ //LLAlignedArray<LLVector4a, 64> mEdgeCenters;
friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
protected:
- void genNormals(const LLProfileParams& params);
+ static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
@@ -729,13 +742,29 @@ protected:
class LLPath
{
public:
- struct PathPt
+ class PathPt
{
- LLVector3 mPos;
- LLVector2 mScale;
- LLQuaternion mRot;
+ public:
+ LLMatrix4a mRot;
+ LLVector4a mPos;
+
+ LLVector4a mScale;
F32 mTexT;
- PathPt() { mPos.setVec(0,0,0); mTexT = 0; mScale.setVec(0,0); mRot.loadIdentity(); }
+ F32 pad[3]; //for alignment
+ PathPt()
+ {
+ mPos.clear();
+ mTexT = 0;
+ mScale.clear();
+ mRot.setRows(LLVector4a(1,0,0,0),
+ LLVector4a(0,1,0,0),
+ LLVector4a(0,0,1,0));
+
+ //distinguished data in the pad for debugging
+ pad[0] = 3.14159f;
+ pad[1] = -3.14159f;
+ pad[2] = 0.585f;
+ }
};
public:
@@ -749,6 +778,9 @@ public:
virtual ~LLPath();
+ static S32 getNumPoints(const LLPathParams& params, F32 detail);
+ static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
+
void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0,
BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
@@ -764,7 +796,7 @@ public:
friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
public:
- std::vector<PathPt> mPath;
+ LLAlignedArray<PathPt, 64> mPath;
protected:
BOOL mOpen;
@@ -785,30 +817,88 @@ public:
class LLVolumeFace
{
public:
- LLVolumeFace() :
- mID(0),
- mTypeMask(0),
- mHasBinormals(FALSE),
- mBeginS(0),
- mBeginT(0),
- mNumS(0),
- mNumT(0)
+ class VertexData
{
- }
+ enum
+ {
+ POSITION = 0,
+ NORMAL = 1
+ };
+
+ private:
+ void init();
+ public:
+ 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 makeTriStrip();
+ void createTangents();
- class VertexData
+ void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform);
+
+ void resizeVertices(S32 num_verts);
+ void allocateTangents(S32 num_verts);
+ void allocateWeights(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:
- LLVector3 mPosition;
- LLVector3 mNormal;
- LLVector3 mBinormal;
- LLVector2 mTexCoord;
+ 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
{
SINGLE_MASK = 0x0001,
@@ -827,22 +917,43 @@ public:
public:
S32 mID;
U32 mTypeMask;
- LLVector3 mCenter;
- BOOL mHasBinormals;
-
+
// Only used for INNER/OUTER faces
S32 mBeginS;
S32 mBeginT;
S32 mNumS;
S32 mNumT;
- LLVector3 mExtents[2]; //minimum and maximum point of face
+ LLVector4a* mExtents; //minimum and maximum point of face
+ LLVector4a* mCenter;
+ LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
+
+ S32 mNumVertices;
+ S32 mNumAllocatedVertices;
+ S32 mNumIndices;
+
+ LLVector4a* mPositions;
+ LLVector4a* mNormals;
+ LLVector4a* mTangents;
+ LLVector2* mTexCoords;
+ U16* mIndices;
+
+ //vertex buffer filled in by LLFace to cache this volume face geometry in vram
+ // (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer)
+ mutable LLPointer<LLRefCount> mVertexBuffer;
- std::vector<VertexData> mVertices;
- std::vector<U16> mIndices;
- std::vector<U16> mTriStrip;
std::vector<S32> mEdge;
+ //list of skin weights for rigged volumes
+ // format is mWeights[vertex_index].mV[influence] = <joint_index>.<weight>
+ // mWeights.size() should be empty or match mVertices.size()
+ LLVector4a* mWeights;
+
+ LLOctreeNode<LLVolumeTriangle>* mOctree;
+
+ //whether or not face has been cache optimized
+ BOOL mOptimized;
+
private:
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
@@ -853,16 +964,11 @@ class LLVolume : public LLRefCount
{
friend class LLVolumeLODGroup;
-private:
- LLVolume(const LLVolume&); // Don't implement
+protected:
~LLVolume(); // use unref
public:
- struct Point
- {
- LLVector3 mPos;
- };
-
+
struct FaceParams
{
LLFaceID mFaceID;
@@ -876,21 +982,23 @@ 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; }
+ F32 getSurfaceArea() const { return mSurfaceArea; }
const LLVolumeParams& getParams() const { return mParams; }
LLVolumeParams getCopyOfParams() const { return mParams; }
const LLProfile& getProfile() const { return *mProfilep; }
LLPath& getPath() const { return *mPathp; }
void resizePath(S32 length);
- const std::vector<Point>& getMesh() const { return mMesh; }
- const LLVector3& getMeshPt(const U32 i) const { return mMesh[i].mPos; }
+ const LLAlignedArray<LLVector4a,64>& getMesh() const { return mMesh; }
+ const LLVector4a& getMeshPt(const U32 i) const { return mMesh[i]; }
+
void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
void regen();
- void genBinormals(S32 face);
+ void genTangents(S32 face);
BOOL isConvex() const;
BOOL isCap(S32 face);
@@ -898,15 +1006,15 @@ public:
BOOL isUnique() const { return mUnique; }
S32 getSculptLevel() const { return mSculptLevel; }
+ void setSculptLevel(S32 level) { mSculptLevel = level; }
+
- S32 *getTriangleIndices(U32 &num_indices) const;
+ static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
- // returns number of triangle indeces required for path/profile mesh
- S32 getNumTriangleIndices() const;
+ S32 getNumTriangles(S32* vcount = NULL) const;
void generateSilhouetteVertices(std::vector<LLVector3> &vertices,
std::vector<LLVector3> &normals,
- std::vector<S32> &segments,
const LLVector3& view_vec,
const LLMatrix4& mat,
const LLMatrix3& norm_mat,
@@ -915,25 +1023,14 @@ public:
//get the face index of the face that intersects with the given line segment at the point
//closest to start. Moves end to the point of intersection. Returns -1 if no intersection.
//Line segment must be in volume space.
- S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
-
- // The following cleans up vertices and triangles,
- // getting rid of degenerate triangles and duplicate vertices,
- // and allocates new arrays with the clean data.
- static BOOL cleanupTriangleData( const S32 num_input_vertices,
- const std::vector<Point> &input_vertices,
- const S32 num_input_triangles,
- S32 *input_triangles,
- S32 &num_output_vertices,
- LLVector3 **output_vertices,
- S32 &num_output_triangles,
- S32 **output_triangles);
+
LLFaceID generateFaceMask();
BOOL isFaceMaskValid(LLFaceID face_mask);
@@ -943,11 +1040,16 @@ public:
friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep); // HACK to bypass Windoze confusion over
// conversion if *(LLVolume*) to LLVolume&
const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
-
+
U32 mFaceMask; // bit array of which faces exist in this volume
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 copyFacesTo(std::vector<LLVolumeFace> &faces) const;
+ void copyFacesFrom(const std::vector<LLVolumeFace> &faces);
+ void cacheOptimize();
+
private:
void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
F32 sculptGetSurfaceArea();
@@ -958,35 +1060,49 @@ private:
protected:
BOOL generate();
void createVolumeFaces();
+public:
+ virtual bool unpackVolumeFaces(std::istream& is, S32 size);
+
+ virtual void setMeshAssetLoaded(BOOL loaded);
+ virtual BOOL isMeshAssetLoaded();
protected:
BOOL mUnique;
F32 mDetail;
S32 mSculptLevel;
+ F32 mSurfaceArea; //unscaled surface area
+ BOOL mIsMeshAssetLoaded;
LLVolumeParams mParams;
LLPath *mPathp;
LLProfile *mProfilep;
- std::vector<Point> mMesh;
-
+ LLAlignedArray<LLVector4a,64> mMesh;
+
+
BOOL mGenerateSingleFace;
typedef std::vector<LLVolumeFace> face_list_t;
face_list_t mVolumeFaces;
+
+public:
+ LLVector4a* mHullPoints;
+ U16* mHullIndices;
+ S32 mNumHullPoints;
+ S32 mNumHullIndices;
};
std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
-LLVector3 calc_binormal_from_triangle(
- const LLVector3& pos0,
- const LLVector2& tex0,
- const LLVector3& pos1,
- const LLVector2& tex1,
- const LLVector3& pos2,
- const LLVector2& tex2);
-
+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 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 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);
+
+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);