From 3e80fa3dbc943de9b784fedc202ba38cf238f46d Mon Sep 17 00:00:00 2001 From: David Parks Date: Mon, 2 Nov 2009 19:55:37 +0000 Subject: Sync up with render-pipeline-7 ignore-dead-branch --- indra/llmath/llvolume.cpp | 350 ++++++++++++++++++++++++++++++++++++++++++- indra/llmath/llvolume.h | 22 ++- indra/llmath/llvolumemgr.cpp | 2 +- indra/llmath/m4math.cpp | 11 ++ indra/llmath/m4math.h | 1 + indra/llmath/v2math.cpp | 15 ++ indra/llmath/v2math.h | 3 + 7 files changed, 392 insertions(+), 12 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index b8ef92f9a9..afa82ed399 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -46,6 +46,9 @@ #include "lldarray.h" #include "llvolume.h" #include "llstl.h" +#include "llsdserialize.h" +#include "zlib/zlib.h" + #define DEBUG_SILHOUETTE_BINORMALS 0 #define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette @@ -1688,7 +1691,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mGenerateSingleFace = generate_single_face; generate(); - if (mParams.getSculptID().isNull()) + if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE) { createVolumeFaces(); } @@ -1839,6 +1842,295 @@ BOOL LLVolume::generate() return FALSE; } +bool LLVolumeFace::VertexData::operator<(const LLVolumeFace::VertexData& rhs)const +{ + const U8* l = (const U8*) this; + const U8* r = (const U8*) &rhs; + + for (U32 i = 0; i < sizeof(VertexData); ++i) + { + if (l[i] != r[i]) + { + return r[i] < l[i]; + } + } + + return false; +} + +bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)const +{ + const U8* l = (const U8*) this; + const U8* r = (const U8*) &rhs; + + for (U32 i = 0; i < sizeof(VertexData); ++i) + { + if (l[i] != r[i]) + { + return false; + } + } + + return true; +} + + +BOOL LLVolume::createVolumeFacesFromFile(const std::string& file_name) +{ + std::ifstream is; + + is.open(file_name.c_str(), std::ifstream::in | std::ifstream::binary); + + BOOL success = createVolumeFacesFromStream(is); + + is.close(); + + return success; +} + +BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) +{ + mSculptLevel = -1; // default is an error occured + + LLSD header; + { + if (!LLSDSerialize::deserialize(header, is, 1024*1024*1024)) + { + llwarns << "not a valid mesh asset!" << llendl; + return FALSE; + } + } + + std::string nm[] = + { + "impostor", + "low_lod", + "medium_lod", + "high_lod" + }; + + S32 lod = llclamp((S32) mDetail, 0, 3); + + while (lod < 4 && header[nm[lod]]["offset"].asInteger() == -1) + { + ++lod; + } + + if (lod >= 4) + { + llwarns << "Couldn't load model for given lod" << llendl; + return FALSE; + } + + is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur); + + + U8* result = NULL; + U32 cur_size = 0; + + { + //input stream is now pointing at a zlib compressed block of LLSD + //decompress block + z_stream strm; + + const U32 CHUNK = 65536; + + S32 size = header[nm[lod]]["size"].asInteger(); + U8 *in = new U8[size]; + is.read((char*) in, size); + + U8 out[CHUNK]; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = size; + strm.next_in = in; + + S32 ret = inflateInit(&strm); + + if (ret != Z_OK) + { + llerrs << "WTF?" << llendl; + } + + do + { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR) + { + inflateEnd(&strm); + free(result); + delete [] in; + return FALSE; + } + + switch (ret) + { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; + case Z_DATA_ERROR: + case Z_MEM_ERROR: + inflateEnd(&strm); + free(result); + delete [] in; + return FALSE; + break; + } + + U32 have = CHUNK-strm.avail_out; + + result = (U8*) realloc(result, cur_size + have); + memcpy(result+cur_size, out, have); + cur_size += have; + + } while (strm.avail_out == 0); + + inflateEnd(&strm); + delete [] in; + + if (ret != Z_STREAM_END) + { + free(result); + return FALSE; + } + } + + //result now points to the decompressed LLSD block + + LLSD mdl; + + { + std::string res_str((char*) result, cur_size); + std::istringstream istr(res_str); + + if (!LLSDSerialize::deserialize(mdl, istr, cur_size)) + { + llwarns << "not a valid mesh asset!" << llendl; + return FALSE; + } + } + + + free(result); + + + { + U32 face_count = mdl.size(); + + mVolumeFaces.resize(face_count); + + for (U32 i = 0; i < face_count; ++i) + { + LLSD::Binary pos = mdl[i]["Position"]; + LLSD::Binary norm = mdl[i]["Normal"]; + LLSD::Binary tc = mdl[i]["TexCoord0"]; + LLSD::Binary idx = mdl[i]["TriangleList"]; + + LLVolumeFace& face = mVolumeFaces[i]; + + face.mHasBinormals = FALSE; + + //copy out indices + face.mIndices.resize(idx.size()/2); + if (idx.empty()) + { //why is there an empty index list? + continue; + } + + U16* indices = (U16*) &(idx[0]); + for (U32 j = 0; j < idx.size()/2; ++j) + { + face.mIndices[j] = indices[j]; + } + + //copy out vertices + U32 num_verts = pos.size()/(3*2); + face.mVertices.resize(num_verts); + + LLVector3 min_pos; + LLVector3 max_pos; + LLVector2 min_tc; + LLVector2 max_tc; + + min_pos.setValue(mdl[i]["PositionDomain"]["Min"]); + max_pos.setValue(mdl[i]["PositionDomain"]["Max"]); + min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); + max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); + + F32 scale = llclamp((F32) mdl[i]["Scale"].asReal(), 1.f, 10.f); + + LLVector3 pos_range = max_pos - min_pos; + LLVector2 tc_range = max_tc - min_tc; + + LLVector3& min = face.mExtents[0]; + LLVector3& max = face.mExtents[1]; + + min = max = LLVector3(0,0,0); + + for (U32 j = 0; j < num_verts; ++j) + { + U16* v = (U16*) &(pos[j*3*2]); + + face.mVertices[j].mPosition.setVec( + (F32) v[0] / 65535.f * pos_range.mV[0] + min_pos.mV[0], + (F32) v[1] / 65535.f * pos_range.mV[1] + min_pos.mV[1], + (F32) v[2] / 65535.f * pos_range.mV[2] + min_pos.mV[2]); + + face.mVertices[j].mPosition *= scale; + + if (j == 0) + { + min = max = face.mVertices[j].mPosition; + } + else + { + update_min_max(min,max,face.mVertices[j].mPosition); + } + + U16* n = (U16*) &(norm[j*3*2]); + + face.mVertices[j].mNormal.setVec( + (F32) n[0] / 65535.f * 2.f - 1.f, + (F32) n[1] / 65535.f * 2.f - 1.f, + (F32) n[2] / 65535.f * 2.f - 1.f); + + U16* t = (U16*) &(tc[j*2*2]); + + face.mVertices[j].mTexCoord.setVec( + (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0], + (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]); + } + + } + } + + mSculptLevel = 0; // success! + return TRUE; +} + +void LLVolume::copyVolumeFaces(LLVolume* volume) +{ + mVolumeFaces = volume->mVolumeFaces; + mSculptLevel = 0; +} + +S32 const LL_SCULPT_MESH_MAX_FACES = 8; + +S32 LLVolume::getNumFaces() const +{ + U8 sculpt_type = (mParams.getSculptType() & LL_SCULPT_TYPE_MASK); + + if (sculpt_type == LL_SCULPT_TYPE_MESH) + { + return LL_SCULPT_MESH_MAX_FACES; + } + + return (S32)mProfilep->mFaces.size(); +} + void LLVolume::createVolumeFaces() { @@ -1864,6 +2156,11 @@ void LLVolume::createVolumeFaces() LLProfile::Face& face = mProfilep->mFaces[i]; vf.mBeginS = face.mIndex; vf.mNumS = face.mCount; + if (vf.mNumS < 0) + { + llerrs << "Volume face corruption detected." << llendl; + } + vf.mBeginT = 0; vf.mNumT= getPath().mPath.size(); vf.mID = i; @@ -1907,6 +2204,10 @@ void LLVolume::createVolumeFaces() if (face.mFlat && vf.mNumS > 2) { //flat inner faces have to copy vert normals vf.mNumS = vf.mNumS*2; + if (vf.mNumS < 0) + { + llerrs << "Volume face corruption detected." << llendl; + } } } else @@ -2309,7 +2610,6 @@ bool LLVolumeParams::operator<(const LLVolumeParams ¶ms) const return mSculptID < params.mSculptID; } - return mSculptType < params.mSculptType; @@ -3379,22 +3679,29 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, S32 face_mask) { LLMemType m1(LLMemType::MTYPE_VOLUME); - + vertices.clear(); normals.clear(); segments.clear(); + if (mParams.getSculptType() == LL_SCULPT_TYPE_MESH) + { + return; + } + S32 cur_index = 0; //for each face for (face_list_t::iterator iter = mVolumeFaces.begin(); iter != mVolumeFaces.end(); ++iter) { - const LLVolumeFace& face = *iter; + LLVolumeFace& face = *iter; - if (!(face_mask & (0x1 << cur_index++))) + if (!(face_mask & (0x1 << cur_index++)) || + face.mIndices.empty() || face.mEdge.empty()) { continue; } + if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) { } @@ -3594,6 +3901,8 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, F32 closest_t = 2.f; // must be larger than 1 + end_face = llmin(end_face, getNumVolumeFaces()-1); + for (S32 i = start_face; i <= end_face; i++) { const LLVolumeFace &face = getVolumeFace((U32)i); @@ -4103,11 +4412,28 @@ BOOL LLVolumeParams::exportLegacyStream(std::ostream& output_stream) const return TRUE; } +LLSD LLVolumeParams::sculptAsLLSD() const +{ + LLSD sd = LLSD(); + sd["id"] = getSculptID(); + sd["type"] = getSculptType(); + + return sd; +} + +bool LLVolumeParams::sculptFromLLSD(LLSD& sd) +{ + setSculptID(sd["id"].asUUID(), (U8)sd["type"].asInteger()); + return true; +} + LLSD LLVolumeParams::asLLSD() const { LLSD sd = LLSD(); sd["path"] = mPathParams; sd["profile"] = mProfileParams; + sd["sculpt"] = sculptAsLLSD(); + return sd; } @@ -4115,6 +4441,8 @@ bool LLVolumeParams::fromLLSD(LLSD& sd) { mPathParams.fromLLSD(sd["path"]); mProfileParams.fromLLSD(sd["profile"]); + sculptFromLLSD(sd["sculpt"]); + return true; } @@ -4157,6 +4485,12 @@ const F32 MIN_CONCAVE_PATH_WEDGE = 0.111111f; // 1/9 unity // for collison purposes BOOL LLVolumeParams::isConvex() const { + if (!getSculptID().isNull()) + { + // can't determine, be safe and say no: + return FALSE; + } + F32 path_length = mPathParams.getEnd() - mPathParams.getBegin(); F32 hollow = mProfileParams.getHollow(); @@ -5011,7 +5345,11 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) if (!partial_build) { mIndices.resize(num_indices); - mEdge.resize(num_indices); + + if (volume->getParams().getSculptType() != LL_SCULPT_TYPE_MESH) + { + mEdge.resize(num_indices); + } } else { diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 871b334452..9f595ccbc4 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -186,6 +186,9 @@ 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; +// need to change this (these) names +const U8 LL_SCULPT_TYPE_MESH = 5; + const U8 LL_SCULPT_FLAG_INVERT = 64; const U8 LL_SCULPT_FLAG_MIRROR = 128; @@ -575,6 +578,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 +640,6 @@ public: const F32& getSkew() const { return mPathParams.getSkew(); } const LLUUID& getSculptID() const { return mSculptID; } const U8& getSculptType() const { return mSculptType; } - BOOL isConvex() const; // 'begin' and 'end' should be in range [0, 1] (they will be clamped) @@ -798,7 +803,7 @@ public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); void createBinormals(); - + class VertexData { public: @@ -806,6 +811,9 @@ public: LLVector3 mNormal; LLVector3 mBinormal; LLVector2 mTexCoord; + + bool operator<(const VertexData& rhs) const; + bool operator==(const VertexData& rhs) const; }; enum @@ -851,8 +859,7 @@ class LLVolume : public LLRefCount { friend class LLVolumeLODGroup; -private: - LLVolume(const LLVolume&); // Don't implement +protected: ~LLVolume(); // use unref public: @@ -874,7 +881,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; } @@ -946,6 +953,8 @@ 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(LLVolume* volume); + private: void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); F32 sculptGetSurfaceArea(); @@ -956,6 +965,9 @@ private: protected: BOOL generate(); void createVolumeFaces(); +public: + virtual BOOL createVolumeFacesFromFile(const std::string& file_name); + virtual BOOL createVolumeFacesFromStream(std::istream& is); protected: BOOL mUnique; diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index 53641fceab..61c5a0adc9 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -320,7 +320,7 @@ BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep) { llassert_always(mLODRefs[i] > 0); mLODRefs[i]--; -#if 1 // SJB: Possible opt: keep other lods around +#if 0 // SJB: Possible opt: keep other lods around if (!mLODRefs[i]) { mVolumeLODs[i] = NULL; diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index d8e7b4aaf9..7c7f60154d 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -428,6 +428,17 @@ const LLMatrix4& LLMatrix4::initRotTrans(const LLQuaternion &q, const LLVector return (*this); } +const LLMatrix4& LLMatrix4::initScale(const LLVector3 &scale) +{ + setIdentity(); + + mMatrix[VX][VX] = scale.mV[VX]; + mMatrix[VY][VY] = scale.mV[VY]; + mMatrix[VZ][VZ] = scale.mV[VZ]; + + return (*this); +} + const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos) { F32 sx, sy, sz; diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index e74b7afe9b..de981b7646 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -159,6 +159,7 @@ public: const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos); // Set with Quaternion and position + const LLMatrix4& initScale(const LLVector3 &scale); // Set all const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos); diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp index 555e1f92bb..220336e0c2 100644 --- a/indra/llmath/v2math.cpp +++ b/indra/llmath/v2math.cpp @@ -115,3 +115,18 @@ LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u) a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u ); } + +LLSD LLVector2::getValue() const +{ + LLSD ret; + ret[0] = mV[0]; + ret[1] = mV[1]; + return ret; +} + +void LLVector2::setValue(LLSD& sd) +{ + mV[0] = (F32) sd[0].asReal(); + mV[1] = (F32) sd[1].asReal(); +} + diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h index 9fef8851cc..f9f1c024f2 100644 --- a/indra/llmath/v2math.h +++ b/indra/llmath/v2math.h @@ -66,6 +66,9 @@ class LLVector2 void set(const LLVector2 &vec); // Sets LLVector2 to vec void set(const F32 *vec); // Sets LLVector2 to vec + LLSD getValue() const; + void setValue(LLSD& sd); + void setVec(F32 x, F32 y); // deprecated void setVec(const LLVector2 &vec); // deprecated void setVec(const F32 *vec); // deprecated -- cgit v1.2.3 From 88292104d9a2332e6169f2add8f0b590bb22dbff Mon Sep 17 00:00:00 2001 From: David Parks Date: Wed, 4 Nov 2009 14:19:05 +0000 Subject: Fix for crash when loading some meshes. Added button to auto-fill LODs. --- indra/llmath/llvolume.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index afa82ed399..ddd1b4b3db 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1690,9 +1690,11 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mGenerateSingleFace = generate_single_face; - generate(); + mLODScaleBias.setVec(1,1,1); + if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE) { + generate(); createVolumeFaces(); } } -- cgit v1.2.3 From 10069e0e13e3214ba9320fdce915440b2e12f938 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 5 Nov 2009 19:58:10 -0600 Subject: Fix for prims all being 0 lod. Fix for dangling prim references. --- indra/llmath/llvolume.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ddd1b4b3db..33a8d33ce1 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1692,9 +1692,10 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mLODScaleBias.setVec(1,1,1); + generate(); + if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE) { - generate(); createVolumeFaces(); } } -- cgit v1.2.3 From 4e420a36c67e611cd7d85652b43d9cd65315e563 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 7 Nov 2009 08:22:39 -0600 Subject: Fix for missing LOD spam. --- indra/llmath/llvolume.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 33a8d33ce1..c8ef911cc1 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1676,7 +1676,8 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mFaceMask = 0x0; mDetail = detail; mSculptLevel = -2; - + mLODScaleBias.setVec(1,1,1); + // set defaults if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE) { @@ -1690,8 +1691,6 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mGenerateSingleFace = generate_single_face; - mLODScaleBias.setVec(1,1,1); - generate(); if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE) @@ -1899,7 +1898,7 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) { if (!LLSDSerialize::deserialize(header, is, 1024*1024*1024)) { - llwarns << "not a valid mesh asset!" << llendl; + llwarns << "Mesh header parse error. Not a valid mesh asset!" << llendl; return FALSE; } } @@ -1921,8 +1920,18 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) if (lod >= 4) { - llwarns << "Couldn't load model for given lod" << llendl; - return FALSE; + lod = llclamp((S32) mDetail, 0, 3); + + while (lod >= 0 && header[nm[lod]]["offset"].asInteger() == -1) + { + --lod; + } + + if (lod < 0) + { + llwarns << "Mesh header missing LOD offsets. Not a valid mesh asset!" << llendl; + return FALSE; + } } is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur); -- cgit v1.2.3 From c02702f3871979cb7745b49aa502ac3c71f77681 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 13 Nov 2009 17:01:56 -0600 Subject: CTS-7 Add hard edge threshold capability to normal generation. --- indra/llmath/llvolume.cpp | 12 ++++++++++++ indra/llmath/llvolume.h | 1 + 2 files changed, 13 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 6286d1bcea..f252b2a232 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1876,6 +1876,18 @@ bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)co return true; } +bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const +{ + bool retval = false; + if (rhs.mPosition == mPosition && rhs.mTexCoord == mTexCoord) + { + F32 cur_angle = rhs.mNormal*mNormal; + + retval = cur_angle > angle_cutoff; + } + + return retval; +} BOOL LLVolume::createVolumeFacesFromFile(const std::string& file_name) { diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 9f595ccbc4..d2727d8f21 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -814,6 +814,7 @@ public: bool operator<(const VertexData& rhs) const; bool operator==(const VertexData& rhs) const; + bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; }; enum -- cgit v1.2.3 From 81bfdcbfae4f203e60f00794966383b01475995b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 18 Nov 2009 18:10:48 -0600 Subject: Tetrahedron displays in place of unloaded mesh. Still has some LOD issues. --- indra/llmath/llvolume.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++++++- indra/llmath/llvolume.h | 1 + 2 files changed, 95 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index f252b2a232..84da1b3c62 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1925,7 +1925,9 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) S32 lod = llclamp((S32) mDetail, 0, 3); - while (lod < 4 && header[nm[lod]]["offset"].asInteger() == -1) + while (lod < 4 && + (header[nm[lod]]["offset"].asInteger() == -1 || + header[nm[lod]]["size"].asInteger() == 0 )) { ++lod; } @@ -1934,7 +1936,9 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) { lod = llclamp((S32) mDetail, 0, 3); - while (lod >= 0 && header[nm[lod]]["offset"].asInteger() == -1) + while (lod >= 0 && + (header[nm[lod]]["offset"].asInteger() == -1 || + header[nm[lod]]["size"].asInteger() == 0) ) { --lod; } @@ -2135,6 +2139,94 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) return TRUE; } +void tetrahedron_set_normal(LLVolumeFace::VertexData* cv) +{ + LLVector3 nrm = (cv[1].mPosition-cv[0].mPosition)%(cv[2].mPosition-cv[0].mPosition); + + nrm.normVec(); + + cv[0].mNormal = nrm; + cv[1].mNormal = nrm; + cv[2].mNormal = nrm; +} + +void LLVolume::makeTetrahedron() +{ + mVolumeFaces.clear(); + + LLVolumeFace face; + + F32 x = 0.5f; + LLVector3 p[] = + { //unit tetrahedron corners + LLVector3(x,x,x), + LLVector3(-x,-x,x), + LLVector3(-x,x,-x), + LLVector3(x,-x,-x) + }; + + LLVolumeFace::VertexData cv[3]; + + //set texture coordinates + cv[0].mTexCoord = LLVector2(0,0); + cv[1].mTexCoord = LLVector2(1,0); + cv[2].mTexCoord = LLVector2(0.5f, 0.5f*F_SQRT3); + + + //side 1 + cv[0].mPosition = p[1]; + cv[1].mPosition = p[0]; + cv[2].mPosition = p[2]; + + tetrahedron_set_normal(cv); + + face.mVertices.push_back(cv[0]); + face.mVertices.push_back(cv[1]); + face.mVertices.push_back(cv[2]); + + //side 2 + cv[0].mPosition = p[3]; + cv[1].mPosition = p[0]; + cv[2].mPosition = p[1]; + + tetrahedron_set_normal(cv); + + face.mVertices.push_back(cv[0]); + face.mVertices.push_back(cv[1]); + face.mVertices.push_back(cv[2]); + + //side 3 + cv[0].mPosition = p[3]; + cv[1].mPosition = p[1]; + cv[2].mPosition = p[2]; + + tetrahedron_set_normal(cv); + + face.mVertices.push_back(cv[0]); + face.mVertices.push_back(cv[1]); + face.mVertices.push_back(cv[2]); + + //side 4 + cv[0].mPosition = p[2]; + cv[1].mPosition = p[0]; + cv[2].mPosition = p[3]; + + tetrahedron_set_normal(cv); + + face.mVertices.push_back(cv[0]); + face.mVertices.push_back(cv[1]); + face.mVertices.push_back(cv[2]); + + //set index buffer + for (U32 i = 0; i < 12; i++) + { + face.mIndices.push_back(i); + } + + mVolumeFaces.push_back(face); + mSculptLevel = 0; +} + void LLVolume::copyVolumeFaces(LLVolume* volume) { mVolumeFaces = volume->mVolumeFaces; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index d2727d8f21..bf2854ede9 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -969,6 +969,7 @@ protected: public: virtual BOOL createVolumeFacesFromFile(const std::string& file_name); virtual BOOL createVolumeFacesFromStream(std::istream& is); + virtual void makeTetrahedron(); protected: BOOL mUnique; -- cgit v1.2.3 From 62233f22469cdc66042fc7bbbbd367dbb7212fde Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 24 Nov 2009 07:38:04 -0600 Subject: Fix for copying of tetrahedrons in place of mesh LODs. Fix for bad tetrahedron bounding box. Bad fix for simultaneous loading of multiple LODs. --- indra/llmath/llvolume.cpp | 31 +++++++++++++++++++++++++++++-- indra/llmath/llvolume.h | 5 ++++- indra/llmath/llvolumemgr.cpp | 13 +++++++++++++ indra/llmath/llvolumemgr.h | 1 + 4 files changed, 47 insertions(+), 3 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 84da1b3c62..515b1061f9 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1676,6 +1676,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mFaceMask = 0x0; mDetail = detail; mSculptLevel = -2; + mIsTetrahedron = FALSE; mLODScaleBias.setVec(1,1,1); // set defaults @@ -1905,7 +1906,7 @@ BOOL LLVolume::createVolumeFacesFromFile(const std::string& file_name) BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) { mSculptLevel = -1; // default is an error occured - + LLSD header; { if (!LLSDSerialize::deserialize(header, is, 1024*1024*1024)) @@ -2048,6 +2049,11 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) { U32 face_count = mdl.size(); + if (face_count == 0) + { + llerrs << "WTF?" << llendl; + } + mVolumeFaces.resize(face_count); for (U32 i = 0; i < face_count; ++i) @@ -2063,8 +2069,9 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) //copy out indices face.mIndices.resize(idx.size()/2); - if (idx.empty()) + if (idx.empty() || face.mIndices.size() < 3) { //why is there an empty index list? + llerrs <<"WTF?" << llendl; continue; } @@ -2150,6 +2157,11 @@ void tetrahedron_set_normal(LLVolumeFace::VertexData* cv) cv[2].mNormal = nrm; } +BOOL LLVolume::isTetrahedron() +{ + return mIsTetrahedron; +} + void LLVolume::makeTetrahedron() { mVolumeFaces.clear(); @@ -2165,6 +2177,9 @@ void LLVolume::makeTetrahedron() LLVector3(x,-x,-x) }; + face.mExtents[0].setVec(-x,-x,-x); + face.mExtents[1].setVec(x,x,x); + LLVolumeFace::VertexData cv[3]; //set texture coordinates @@ -2225,12 +2240,19 @@ void LLVolume::makeTetrahedron() mVolumeFaces.push_back(face); mSculptLevel = 0; + mIsTetrahedron = TRUE; } void LLVolume::copyVolumeFaces(LLVolume* volume) { + if (volume->isTetrahedron()) + { + llerrs << "WTF?" << llendl; + } + mVolumeFaces = volume->mVolumeFaces; mSculptLevel = 0; + mIsTetrahedron = FALSE; } S32 const LL_SCULPT_MESH_MAX_FACES = 8; @@ -2615,6 +2637,11 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, LLMemType m1(LLMemType::MTYPE_VOLUME); U8 sculpt_type = mParams.getSculptType(); + if (sculpt_type & LL_SCULPT_TYPE_MASK == LL_SCULPT_TYPE_MESH) + { + llerrs << "WTF?" << llendl; + } + BOOL data_is_empty = FALSE; if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index bf2854ede9..8e57f2e280 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -904,7 +904,8 @@ public: BOOL isUnique() const { return mUnique; } S32 getSculptLevel() const { return mSculptLevel; } - + void setSculptLevel(S32 level) { mSculptLevel = level; } + S32 *getTriangleIndices(U32 &num_indices) const; // returns number of triangle indeces required for path/profile mesh @@ -970,11 +971,13 @@ public: virtual BOOL createVolumeFacesFromFile(const std::string& file_name); virtual BOOL createVolumeFacesFromStream(std::istream& is); virtual void makeTetrahedron(); + virtual BOOL isTetrahedron(); protected: BOOL mUnique; F32 mDetail; S32 mSculptLevel; + BOOL mIsTetrahedron; LLVolumeParams mParams; LLPath *mPathp; diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index 61c5a0adc9..419e0015ba 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -375,6 +375,19 @@ F32 LLVolumeLODGroup::getVolumeScaleFromDetail(const S32 detail) return mDetailScales[detail]; } +S32 LLVolumeLODGroup::getVolumeDetailFromScale(const F32 detail) +{ + for (S32 i = 1; i < 4; i++) + { + if (mDetailScales[i] > detail) + { + return i-1; + } + } + + return 3; +} + F32 LLVolumeLODGroup::dump() { F32 usage = 0.f; diff --git a/indra/llmath/llvolumemgr.h b/indra/llmath/llvolumemgr.h index a78ea76a1a..f5dc4cd748 100644 --- a/indra/llmath/llvolumemgr.h +++ b/indra/llmath/llvolumemgr.h @@ -59,6 +59,7 @@ public: static S32 getDetailFromTan(const F32 tan_angle); static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher); static F32 getVolumeScaleFromDetail(const S32 detail); + static S32 getVolumeDetailFromScale(F32 scale); LLVolume* refLOD(const S32 detail); BOOL derefLOD(LLVolume *volumep); -- cgit v1.2.3 From 6d66910c6e2fbb25bf8b5c7b90e795f350342104 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 25 Nov 2009 11:35:41 -0600 Subject: Fix for spam on invalid mesh asset. Fix for index buffer overflow spam and crash in llvertexbuffer. --- indra/llmath/llvolume.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 515b1061f9..3e547aec6f 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2245,11 +2245,6 @@ void LLVolume::makeTetrahedron() void LLVolume::copyVolumeFaces(LLVolume* volume) { - if (volume->isTetrahedron()) - { - llerrs << "WTF?" << llendl; - } - mVolumeFaces = volume->mVolumeFaces; mSculptLevel = 0; mIsTetrahedron = FALSE; -- cgit v1.2.3 From 062a2dd309ca5521d4045eb721496476f43d24dc Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 30 Nov 2009 15:32:10 -0600 Subject: Remove zero area triangles from meshes post-import. --- indra/llmath/llvolume.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 3e547aec6f..1d36da7f52 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1692,10 +1692,9 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mGenerateSingleFace = generate_single_face; - generate(); - if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE) { + generate(); createVolumeFaces(); } } -- cgit v1.2.3 From f039fa98efedc91965338ef53624279f99914205 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 30 Nov 2009 17:02:38 -0600 Subject: Fix for silly crash due to LLPrimitive having 0 texture entries. --- indra/llmath/llvolume.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 1d36da7f52..858bd9edea 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1692,9 +1692,10 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mGenerateSingleFace = generate_single_face; + generate(); + if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE) { - generate(); createVolumeFaces(); } } -- cgit v1.2.3 From bb2631180a85df343e6d816fc37d881af31d49fb Mon Sep 17 00:00:00 2001 From: "Karl Stiefvater (qarl)" Date: Tue, 1 Dec 2009 17:40:52 -0600 Subject: CTS-4 Only part of an uploaded mesh renders. --- indra/llmath/llvolume.cpp | 1 - indra/llmath/llvolume.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 858bd9edea..fb2de92e35 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2250,7 +2250,6 @@ void LLVolume::copyVolumeFaces(LLVolume* volume) mIsTetrahedron = FALSE; } -S32 const LL_SCULPT_MESH_MAX_FACES = 8; S32 LLVolume::getNumFaces() const { diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 8e57f2e280..59c60ccd92 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -192,6 +192,7 @@ const U8 LL_SCULPT_TYPE_MESH = 5; const U8 LL_SCULPT_FLAG_INVERT = 64; const U8 LL_SCULPT_FLAG_MIRROR = 128; +const S32 LL_SCULPT_MESH_MAX_FACES = 8; class LLProfileParams { -- cgit v1.2.3 From 695969c77066de5032bdc9caefecf9b32b076b2f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 11 Dec 2009 14:47:11 -0600 Subject: HTTP Mesh fetch FTW.. still busted --- indra/llmath/llvolume.cpp | 7 +++++-- indra/llmath/llvolume.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index fb2de92e35..44ff173502 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1952,8 +1952,12 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) } is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur); - + return unpackVolumeFaces(is, header[nm[lod]]["size"].asInteger()); +} + +BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) +{ U8* result = NULL; U32 cur_size = 0; @@ -1964,7 +1968,6 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) const U32 CHUNK = 65536; - S32 size = header[nm[lod]]["size"].asInteger(); U8 *in = new U8[size]; is.read((char*) in, size); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 59c60ccd92..9970b24a94 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -971,6 +971,8 @@ protected: public: virtual BOOL createVolumeFacesFromFile(const std::string& file_name); virtual BOOL createVolumeFacesFromStream(std::istream& is); + virtual BOOL unpackVolumeFaces(std::istream& is, S32 size); + virtual void makeTetrahedron(); virtual BOOL isTetrahedron(); -- cgit v1.2.3 From 081fa98a47d2b592ada0fbb049ff959ac2cd6294 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 15 Dec 2009 17:43:05 -0600 Subject: HTTP Mesh transfer relatively blocking-free. --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 44ff173502..844918432d 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2171,7 +2171,7 @@ void LLVolume::makeTetrahedron() LLVolumeFace face; - F32 x = 0.5f; + F32 x = 0.25f; LLVector3 p[] = { //unit tetrahedron corners LLVector3(x,x,x), -- cgit v1.2.3 From 512a5736dceb1cc6db286e5f5baad867ac7a5935 Mon Sep 17 00:00:00 2001 From: "Karl Stiefvater (qarl)" Date: Wed, 23 Dec 2009 14:40:48 -0600 Subject: LODs for scene upload --- indra/llmath/llvolume.cpp | 14 ++++++++++++++ indra/llmath/llvolume.h | 2 ++ 2 files changed, 16 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 844918432d..de32070da1 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -3807,6 +3807,20 @@ S32 LLVolume::getNumTriangleIndices() const return count; } + +S32 LLVolume::getNumTriangles() const +{ + U32 triangle_count = 0; + + for (S32 i = 0; i < getNumVolumeFaces(); ++i) + { + triangle_count += getVolumeFace(i).mIndices.size()/3; + } + + return triangle_count; +} + + //----------------------------------------------------------------------------- // generateSilhouetteVertices() //----------------------------------------------------------------------------- diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 9970b24a94..e3ab648fe3 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -912,6 +912,8 @@ public: // returns number of triangle indeces required for path/profile mesh S32 getNumTriangleIndices() const; + S32 getNumTriangles() const; + void generateSilhouetteVertices(std::vector &vertices, std::vector &normals, std::vector &segments, -- cgit v1.2.3 From d3e84ea77baa7d60fe225f7b440297e9a49318a6 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 20 Jan 2010 15:08:29 -0600 Subject: First stab at making model importer act more like scene importer. Upload button still doesn't work. --- indra/llmath/m4math.cpp | 17 +++++++++++++++++ indra/llmath/m4math.h | 1 + 2 files changed, 18 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 7c7f60154d..3700142982 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -785,6 +785,23 @@ bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b) return FALSE; } +bool operator<(const LLMatrix4& a, const LLMatrix4 &b) +{ + U32 i, j; + for (i = 0; i < NUM_VALUES_IN_MAT4; i++) + { + for (j = 0; j < NUM_VALUES_IN_MAT4; j++) + { + if (a.mMatrix[i][j] != b.mMatrix[i][j]) + { + return a.mMatrix[i][j] < b.mMatrix[i][j]; + } + } + } + + return false; +} + const LLMatrix4& operator*=(LLMatrix4 &a, F32 k) { U32 i, j; diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index de981b7646..6007b96bd9 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -237,6 +237,7 @@ public: friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b); // Return a == b friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b); // Return a != b + friend bool operator<(const LLMatrix4 &a, const LLMatrix4& b); // Return a < b friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b); // Return a + b friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b); // Return a - b -- cgit v1.2.3 From 024c0ebe19588f8452bae7ea01756fd7b4b30540 Mon Sep 17 00:00:00 2001 From: "Karl Stiefvater (qarl)" Date: Fri, 29 Jan 2010 14:33:04 -0600 Subject: enable mirror and invert flags for meshes. --- indra/llmath/llvolume.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++--- indra/llmath/llvolume.h | 7 +++--- 2 files changed, 59 insertions(+), 7 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index de32070da1..0328c09c9a 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1694,7 +1694,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge generate(); - if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE) + if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) { createVolumeFaces(); } @@ -2142,6 +2142,59 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]); } + + // modifier flags? + BOOL do_mirror = (mParams.getSculptType() & LL_SCULPT_FLAG_MIRROR); + BOOL do_invert = (mParams.getSculptType() &LL_SCULPT_FLAG_INVERT); + + + // translate to actions: + BOOL do_reflect_x = FALSE; + BOOL do_reverse_triangles = FALSE; + BOOL do_invert_normals = FALSE; + + if (do_mirror) + { + do_reflect_x = TRUE; + do_reverse_triangles = !do_reverse_triangles; + } + + if (do_invert) + { + do_invert_normals = TRUE; + do_reverse_triangles = !do_reverse_triangles; + } + + // now do the work + + if (do_reflect_x) + { + for (S32 i = 0; i < face.mVertices.size(); i++) + { + face.mVertices[i].mPosition.mV[VX] *= -1.0f; + face.mVertices[i].mNormal.mV[VX] *= -1.0f; + } + } + + if (do_invert_normals) + { + for (S32 i = 0; i < face.mVertices.size(); i++) + { + face.mVertices[i].mNormal *= -1.0f; + } + } + + if (do_reverse_triangles) + { + for (U32 j = 0; j < face.mIndices.size(); j += 3) + { + // swap the 2nd and 3rd index + S32 swap = face.mIndices[j+1]; + face.mIndices[j+1] = face.mIndices[j+2]; + face.mIndices[j+2] = swap; + } + } + } } @@ -3838,7 +3891,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, normals.clear(); segments.clear(); - if (mParams.getSculptType() == LL_SCULPT_TYPE_MESH) + if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { return; } @@ -5500,7 +5553,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { mIndices.resize(num_indices); - if (volume->getParams().getSculptType() != LL_SCULPT_TYPE_MESH) + if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { mEdge.resize(num_indices); } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index e3ab648fe3..0bc64f4487 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -183,12 +183,11 @@ 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; - -// need to change this (these) names 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; -- cgit v1.2.3 From 1805369b58d98677c726bb0bcb52618bd66e8fdd Mon Sep 17 00:00:00 2001 From: "Karl Stiefvater (qarl)" Date: Wed, 3 Feb 2010 18:08:19 -0600 Subject: handle reflected geometry in scene import implement determinant for 4x4 matrices fix materials for collada --- indra/llmath/m4math.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 3700142982..5c112b52b2 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -221,8 +221,33 @@ const LLMatrix4& LLMatrix4::transpose() F32 LLMatrix4::determinant() const { - llerrs << "Not implemented!" << llendl; - return 0.f; + F32 value = + mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][0] - + mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][0] - + mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][0] + + mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][0] + + mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][0] - + mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][0] - + mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][1] + + mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][1] + + mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][1] - + mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][1] - + mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][1] + + mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][1] + + mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][2] - + mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][2] - + mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][2] + + mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][2] + + mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][2] - + mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][2] - + mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][3] + + mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][3] + + mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][3] - + mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][3] - + mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][3] + + mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][3]; + + return value; } // Only works for pure orthonormal, homogeneous transform matrices. -- cgit v1.2.3 From 095a5e84408b47ef3c5610e111aefe51d77633ca Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 6 Feb 2010 17:33:12 -0600 Subject: Draw prims using triangle strips instead of triangle lists. --- indra/llmath/llvolume.cpp | 201 ++++++++++++++++++++++++++++++++++++---------- indra/llmath/llvolume.h | 4 +- 2 files changed, 160 insertions(+), 45 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index df4c618ac1..cd7d7a12e3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4520,15 +4520,65 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) if (!partial_build) { - int idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; - for(int gx = 0;gx=0;i--)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); - }else{ - for(int i=0;i<6;i++)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); + mTriStrip.clear(); + S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; + for(S32 gx = 0;gx=0;i--) + { + mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); + } + + if (gy == 0) + { + mTriStrip.push_back((gx+1)*(grid_size+1)); + mTriStrip.push_back((gx+1)*(grid_size+1)); + mTriStrip.push_back(gx*(grid_size+1)); + } + + mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1)); + mTriStrip.push_back(gy+1+gx*(grid_size+1)); + + + if (gy == grid_size-1) + { + mTriStrip.push_back(gy+1+gx*(grid_size+1)); + } + } + else + { + for(S32 i=0;i<6;i++) + { + mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); + } + + if (gy == 0) + { + mTriStrip.push_back(gx*(grid_size+1)); + mTriStrip.push_back(gx*(grid_size+1)); + mTriStrip.push_back((gx+1)*(grid_size+1)); + } + + mTriStrip.push_back(gy+1+gx*(grid_size+1)); + mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1)); + + if (gy == grid_size-1) + { + mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1)); + } } } + + } + + if (mTriStrip.size()%2 == 1) + { + mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); } } @@ -4770,6 +4820,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) pt2--; } } + + makeTriStrip(); } else { @@ -4874,67 +4926,108 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) pt2--; } } + + makeTriStrip(); } } else { // Not hollow, generate the triangle fan. + U16 v1 = 2; + U16 v2 = 1; + if (mTypeMask & TOP_MASK) { - if (mTypeMask & OPEN_MASK) - { - // SOLID OPEN TOP - // Generate indices - // This is a tri-fan, so we reuse the same first point for all triangles. - for (S32 i = 0; i < (num_vertices - 2); i++) - { - mIndices[3*i] = num_vertices - 1; - mIndices[3*i+1] = i; - mIndices[3*i+2] = i + 1; - } - } - else - { - // SOLID CLOSED TOP - for (S32 i = 0; i < (num_vertices - 2); i++) - { - //MSMSM fix these caps but only for the un-cut case - mIndices[3*i] = num_vertices - 1; - mIndices[3*i+1] = i; - mIndices[3*i+2] = i + 1; - } - } + v1 = 1; + v2 = 2; + } + + for (S32 i = 0; i < (num_vertices - 2); i++) + { + mIndices[3*i] = num_vertices - 1; + mIndices[3*i+v1] = i; + mIndices[3*i+v2] = i + 1; + } + + //make tri strip + if (mTypeMask & OPEN_MASK) + { + makeTriStrip(); } else { - if (mTypeMask & OPEN_MASK) + S32 j = num_vertices-2; + if (mTypeMask & TOP_MASK) { - // SOLID OPEN BOTTOM - // Generate indices - // This is a tri-fan, so we reuse the same first point for all triangles. - for (S32 i = 0; i < (num_vertices - 2); i++) + mTriStrip.push_back(0); + for (S32 i = 1; i <= j; ++i) { - mIndices[3*i] = num_vertices - 1; - mIndices[3*i+1] = i + 1; - mIndices[3*i+2] = i; + mTriStrip.push_back(i); + if (i != j) + { + mTriStrip.push_back(j); + } + --j; } } else { - // SOLID CLOSED BOTTOM - for (S32 i = 0; i < (num_vertices - 2); i++) + mTriStrip.push_back(j); + for (S32 i = 1; i <= j; ++i) { - //MSMSM fix these caps but only for the un-cut case - mIndices[3*i] = num_vertices - 1; - mIndices[3*i+1] = i + 1; - mIndices[3*i+2] = i; + if (i != j) + { + mTriStrip.push_back(j); + } + mTriStrip.push_back(i); + --j; } } + + mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); + + if (mTriStrip.size()%2 == 1) + { + mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); + } } } + return TRUE; } +void LLVolumeFace::makeTriStrip() +{ + for (U32 i = 0; i < mIndices.size(); i+=3) + { + U16 i0 = mIndices[i]; + U16 i1 = mIndices[i+1]; + U16 i2 = mIndices[i+2]; + + if ((i/3)%2 == 1) + { + mTriStrip.push_back(i0); + mTriStrip.push_back(i0); + mTriStrip.push_back(i1); + mTriStrip.push_back(i2); + mTriStrip.push_back(i2); + } + else + { + mTriStrip.push_back(i2); + mTriStrip.push_back(i2); + mTriStrip.push_back(i1); + mTriStrip.push_back(i0); + mTriStrip.push_back(i0); + } + } + + if (mTriStrip.size()%2 == 1) + { + mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); + } +} + void LLVolumeFace::createBinormals() { LLMemType m1(LLMemType::MTYPE_VOLUME); @@ -5135,9 +5228,14 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) if (!partial_build) { + mTriStrip.clear(); + // Now we generate the indices. for (t = 0; t < (mNumT-1); t++) { + //prepend terminating index to strip + mTriStrip.push_back(mNumS*t); + for (s = 0; s < (mNumS-1); s++) { mIndices[cur_index++] = s + mNumS*t; //bottom left @@ -5147,6 +5245,14 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) mIndices[cur_index++] = s+1 + mNumS*t; //bottom right mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right + if (s == 0) + { + mTriStrip.push_back(s+mNumS*t); + mTriStrip.push_back(s+mNumS*(t+1)); + } + mTriStrip.push_back(s+1+mNumS*t); + mTriStrip.push_back(s+1+mNumS*(t+1)); + mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face if (t < mNumT-2) { //top right/top left neighbor face mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; @@ -5187,6 +5293,13 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face } + //append terminating vertex to strip + mTriStrip.push_back(mNumS-1+mNumS*(t+1)); + } + + if (mTriStrip.size()%2 == 1) + { + mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); } } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 871b334452..d9f80f0e30 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -798,7 +798,8 @@ public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); void createBinormals(); - + void makeTriStrip(); + class VertexData { public: @@ -839,6 +840,7 @@ public: std::vector mVertices; std::vector mIndices; + std::vector mTriStrip; std::vector mEdge; private: -- cgit v1.2.3 From 42df75bafeab49b408f23d79feb4f2213d2560eb Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 8 Feb 2010 10:14:11 -0600 Subject: Enable FBO multisampling for OSX. Fix bad triangle in prim caps. --- indra/llmath/llvolume.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index cd7d7a12e3..ae5c9bc8cf 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4960,7 +4960,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) if (mTypeMask & TOP_MASK) { mTriStrip.push_back(0); - for (S32 i = 1; i <= j; ++i) + for (S32 i = 0; i <= j; ++i) { mTriStrip.push_back(i); if (i != j) @@ -4973,7 +4973,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) else { mTriStrip.push_back(j); - for (S32 i = 1; i <= j; ++i) + for (S32 i = 0; i <= j; ++i) { if (i != j) { -- cgit v1.2.3 From 2cb5b0b66ec9633d4c6563acf5ff9d0f7bc7cbf7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 9 Feb 2010 12:26:09 -0600 Subject: consolidate button work in progress --- indra/llmath/llvolume.cpp | 19 +++++++++++++++++++ indra/llmath/llvolume.h | 2 ++ 2 files changed, 21 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index de32070da1..596c5fe231 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5468,6 +5468,25 @@ void LLVolumeFace::createBinormals() } } +void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& norm_transform) +{ + for (U32 i = 0; i < face.mVertices.size(); ++i) + { + VertexData v = face.mVertices[i]; + v.mPosition *= mat; + v.mNormal *= norm_transform; + + + mVertices.push_back(v); + } + + U16 offset = mIndices.size(); + for (U32 i = 0; i < face.mIndices.size(); ++i) + { + mIndices.push_back(face.mIndices[i]+offset); + } +} + BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { LLMemType m1(LLMemType::MTYPE_VOLUME); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index e3ab648fe3..1bf6fac305 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -805,6 +805,8 @@ public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); void createBinormals(); + void appendFace(const LLVolumeFace& face); + class VertexData { public: -- cgit v1.2.3 From ffcbbf4aaabc652c2050ca6147a9388217cfcaa7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 11 Feb 2010 18:00:00 -0600 Subject: Multi-threaded asset uploading with proper ordering first draft. --- indra/llmath/llvolume.cpp | 20 ++++++++++++++++---- indra/llmath/llvolume.h | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d1716e1407..7e1517fba7 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5614,19 +5614,31 @@ void LLVolumeFace::createBinormals() } } -void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& norm_transform) +void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat, LLMatrix4& norm_mat) { + U16 offset = mVertices.size(); + + for (U32 i = 0; i < face.mVertices.size(); ++i) { VertexData v = face.mVertices[i]; - v.mPosition *= mat; - v.mNormal *= norm_transform; + v.mPosition = v.mPosition*mat; + v.mNormal = v.mNormal * norm_mat; mVertices.push_back(v); + + if (offset == 0 && i == 0) + { + mExtents[0] = mExtents[1] = v.mPosition; + } + else + { + update_min_max(mExtents[0], mExtents[1], v.mPosition); + } } - U16 offset = mIndices.size(); + for (U32 i = 0; i < face.mIndices.size(); ++i) { mIndices.push_back(face.mIndices[i]+offset); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 1059c29566..36811785dc 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -805,7 +805,7 @@ public: void createBinormals(); void makeTriStrip(); - void appendFace(const LLVolumeFace& face); + void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform); class VertexData { -- cgit v1.2.3 From ee8036712847315141c78d37646d629796442d09 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 17 Feb 2010 18:08:00 -0600 Subject: 16-bit limit awareness when consolidating models. --- indra/llmath/llvolume.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 7c98536e72..33a00b80ca 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5619,6 +5619,10 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat, LLMatrix { U16 offset = mVertices.size(); + if (face.mVertices.size() + mVertices.size() > 65536) + { + llerrs << "Cannot append face -- 16-bit overflow will occur." << llendl; + } for (U32 i = 0; i < face.mVertices.size(); ++i) { -- cgit v1.2.3 From 237f1a1ba362aa2dfd9bb386e431713bdfcad2dc Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 19 Feb 2010 12:41:08 -0600 Subject: Consolidate now preserves materials. --- indra/llmath/v4color.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index d6fbdec61e..6b63b976b0 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -114,6 +114,7 @@ class LLColor4 const LLColor4& operator=(const LLColor3 &a); // Assigns vec3 to vec4 and returns vec4 + bool operator<(const LLColor4& rhs) const; friend std::ostream& operator<<(std::ostream& s, const LLColor4 &a); // Print a friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b); // Return vector a + b friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b @@ -595,6 +596,23 @@ inline LLColor4 lerp(const LLColor4 &a, const LLColor4 &b, F32 u) a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u); } +inline bool LLColor4::operator<(const LLColor4& rhs) const +{ + if (mV[0] != rhs.mV[0]) + { + return mV[0] < rhs.mV[0]; + } + if (mV[1] != rhs.mV[1]) + { + return mV[1] < rhs.mV[1]; + } + if (mV[2] != rhs.mV[2]) + { + return mV[2] < rhs.mV[2]; + } + + return mV[3] < rhs.mV[3]; +} void LLColor4::clamp() { -- cgit v1.2.3 From 066f9de07ecfcf142103f646695e5be63a22a667 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 23 Feb 2010 16:57:06 -0600 Subject: Fix for normals getting squished on consolidation. Replaced some magic numbers with constants. Switched up throttling of mesh upload HTTP posts to prevent overloading one capability at a time. Added some feedback on upload progress via debug text. Made debug text move with side panel (keep debug text from rendering on top of side panel). --- indra/llmath/llvolume.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 33a00b80ca..704308f20f 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5630,6 +5630,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat, LLMatrix v.mPosition = v.mPosition*mat; v.mNormal = v.mNormal * norm_mat; + v.mNormal.normalize(); mVertices.push_back(v); -- cgit v1.2.3 From 3c78771acee787e087bd2e2391397794d4d98f6d Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 24 Feb 2010 22:02:01 -0600 Subject: Removed scale from model importer. Removed support for scale entry in mesh assets. Fixed MeshMaxConcurrentRequests being ignored. Added mesh download queue debug text. --- indra/llmath/llvolume.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 704308f20f..904786079f 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2098,8 +2098,6 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); - F32 scale = llclamp((F32) mdl[i]["Scale"].asReal(), 1.f, 10.f); - LLVector3 pos_range = max_pos - min_pos; LLVector2 tc_range = max_tc - min_tc; @@ -2117,8 +2115,6 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) (F32) v[1] / 65535.f * pos_range.mV[1] + min_pos.mV[1], (F32) v[2] / 65535.f * pos_range.mV[2] + min_pos.mV[2]); - face.mVertices[j].mPosition *= scale; - if (j == 0) { min = max = face.mVertices[j].mPosition; -- cgit v1.2.3 From b414b5067e3e47da7d9baf490d94534b4c65a8eb Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sun, 28 Feb 2010 16:40:30 -0600 Subject: Remove some dead code. Add LH transform to LLVector3 Add DebugShowUploadCost Make LOD generation on model preview less finnicky. Remove error level based LOD generation. Better framing of model before upload. Better error handling for model uploader. Remove [COST] argument from model upload menu item. Remove L$ check from model upload menu item being enabled. --- indra/llmath/m4math.cpp | 31 ------------------------------- indra/llmath/m4math.h | 5 +---- indra/llmath/v3math.cpp | 22 ++++++++++++++++++++++ indra/llmath/v3math.h | 3 +++ 4 files changed, 26 insertions(+), 35 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 5c112b52b2..ce5428f0e1 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -684,37 +684,6 @@ const LLMatrix4& LLMatrix4::initMatrix(const LLMatrix3 &mat, const LLVector4 & // LLMatrix4 Operators - -/* Not implemented to help enforce code consistency with the syntax of - row-major notation. This is a Good Thing. -LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b) -{ - // Operate "to the right" on column-vector b - LLVector4 vec; - vec.mV[VX] = a.mMatrix[VX][VX] * b.mV[VX] + - a.mMatrix[VY][VX] * b.mV[VY] + - a.mMatrix[VZ][VX] * b.mV[VZ] + - a.mMatrix[VW][VX] * b.mV[VW]; - - vec.mV[VY] = a.mMatrix[VX][VY] * b.mV[VX] + - a.mMatrix[VY][VY] * b.mV[VY] + - a.mMatrix[VZ][VY] * b.mV[VZ] + - a.mMatrix[VW][VY] * b.mV[VW]; - - vec.mV[VZ] = a.mMatrix[VX][VZ] * b.mV[VX] + - a.mMatrix[VY][VZ] * b.mV[VY] + - a.mMatrix[VZ][VZ] * b.mV[VZ] + - a.mMatrix[VW][VZ] * b.mV[VW]; - - vec.mV[VW] = a.mMatrix[VX][VW] * b.mV[VX] + - a.mMatrix[VY][VW] * b.mV[VY] + - a.mMatrix[VZ][VW] * b.mV[VZ] + - a.mMatrix[VW][VW] * b.mV[VW]; - return vec; -} -*/ - - LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b) { // Operate "to the left" on row-vector a diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index 6007b96bd9..40599a0886 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -226,10 +226,7 @@ public: // Operators // -// Not implemented to enforce code that agrees with symbolic syntax -// friend LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b); // Apply rotation a to vector b - -// friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b); // Return a * b + // friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b); // Return a * b friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b); // Return transform of vector a by matrix b friend const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b); // Return full transform of a by matrix b friend LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b); // Rotates a but does not translate diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index 63683ed496..82aad6550b 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -197,6 +197,28 @@ const LLVector3& LLVector3::rotVec(const LLQuaternion &q) return *this; } +const LLVector3& LLVector3::transVec(const LLMatrix4& mat) +{ + setVec( + mV[VX] * mat.mMatrix[VX][VX] + + mV[VY] * mat.mMatrix[VX][VY] + + mV[VZ] * mat.mMatrix[VX][VZ] + + mat.mMatrix[VX][VW], + + mV[VX] * mat.mMatrix[VY][VX] + + mV[VY] * mat.mMatrix[VY][VY] + + mV[VZ] * mat.mMatrix[VY][VZ] + + mat.mMatrix[VY][VW], + + mV[VX] * mat.mMatrix[VZ][VX] + + mV[VY] * mat.mMatrix[VZ][VY] + + mV[VZ] * mat.mMatrix[VZ][VZ] + + mat.mMatrix[VZ][VW]); + + return *this; +} + + const LLVector3& LLVector3::rotVec(F32 angle, const LLVector3 &vec) { if ( !vec.isExactlyZero() && angle ) diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 73738cffd2..76dd938887 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -36,10 +36,12 @@ #include "llerror.h" #include "llmath.h" + #include "llsd.h" class LLVector2; class LLVector4; class LLMatrix3; +class LLMatrix4; class LLVector3d; class LLQuaternion; @@ -115,6 +117,7 @@ class LLVector3 const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians const LLVector3& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat const LLVector3& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q + const LLVector3& transVec(const LLMatrix4& mat); // Transforms by LLMatrix4 mat (mat * v) const LLVector3& scaleVec(const LLVector3& vec); // scales per component by vec LLVector3 scaledVec(const LLVector3& vec) const; // get a copy of this vector scaled by vec -- cgit v1.2.3 From d60f5e937f2ed264f3e01eec7e32b9260e3d772f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 9 Mar 2010 14:28:06 -0600 Subject: Tool tips for model preview. Rename "Impostor" to "Lowest" --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 904786079f..d85c56046f 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1918,7 +1918,7 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) std::string nm[] = { - "impostor", + "lowest_lod", "low_lod", "medium_lod", "high_lod" -- cgit v1.2.3 From 4c0e2f79219913b57424bfe136b75a6a58fb8639 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 11 Mar 2010 12:02:37 -0600 Subject: "Generate Normals" is less busted now. --- indra/llmath/llvolume.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++--- indra/llmath/llvolume.h | 33 +++++++++++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d85c56046f..9ea3912a88 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1882,9 +1882,15 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs bool retval = false; if (rhs.mPosition == mPosition && rhs.mTexCoord == mTexCoord) { - F32 cur_angle = rhs.mNormal*mNormal; - - retval = cur_angle > angle_cutoff; + if (angle_cutoff > 1.f) + { + retval = (mNormal == rhs.mNormal); + } + else + { + F32 cur_angle = rhs.mNormal*mNormal; + retval = cur_angle > angle_cutoff; + } } return retval; @@ -4953,6 +4959,61 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) } } +void LLVolumeFace::optimize(F32 angle_cutoff) +{ + LLVolumeFace new_face; + + VertexMapData::PointMap point_map; + + //remove redundant vertices + for (U32 i = 0; i < mIndices.size(); ++i) + { + U16 index = mIndices[i]; + + LLVolumeFace::VertexData cv = mVertices[index]; + + BOOL found = FALSE; + VertexMapData::PointMap::iterator point_iter = point_map.find(cv.mPosition); + if (point_iter != point_map.end()) + { //duplicate point might exist + for (U32 j = 0; j < point_iter->second.size(); ++j) + { + LLVolumeFace::VertexData& tv = (point_iter->second)[j]; + if (tv.compareNormal(cv, angle_cutoff)) + { + found = TRUE; + new_face.mIndices.push_back((point_iter->second)[j].mIndex); + break; + } + } + } + + if (!found) + { + new_face.mVertices.push_back(cv); + U16 index = (U16) new_face.mVertices.size()-1; + new_face.mIndices.push_back(index); + + VertexMapData d; + d.mPosition = cv.mPosition; + d.mTexCoord = cv.mTexCoord; + d.mNormal = cv.mNormal; + d.mIndex = index; + if (point_iter != point_map.end()) + { + point_iter->second.push_back(d); + } + else + { + point_map[d.mPosition].push_back(d); + } + } + } + + mVertices = new_face.mVertices; + mIndices = new_face.mIndices; +} + void LerpPlanarVertex(LLVolumeFace::VertexData& v0, LLVolumeFace::VertexData& v1, LLVolumeFace::VertexData& v2, diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 36811785dc..f1c1fdceba 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -820,6 +820,39 @@ public: bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; }; + class VertexMapData : public LLVolumeFace::VertexData + { + public: + U16 mIndex; + + bool operator==(const LLVolumeFace::VertexData& rhs) const + { + return mPosition == rhs.mPosition && + mTexCoord == rhs.mTexCoord && + mNormal == rhs.mNormal; + } + + struct ComparePosition + { + bool operator()(const LLVector3& a, const LLVector3& b) const + { + if (a.mV[0] != b.mV[0]) + { + return a.mV[0] < b.mV[0]; + } + if (a.mV[1] != b.mV[1]) + { + return a.mV[1] < b.mV[1]; + } + return a.mV[2] < b.mV[2]; + } + }; + + typedef std::map, VertexMapData::ComparePosition > PointMap; + }; + + void optimize(F32 angle_cutoff = 2.f); + enum { SINGLE_MASK = 0x0001, -- cgit v1.2.3 From 71d11af31083ced30da7b67a2a63e624c93b44a3 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 13 Mar 2010 17:39:32 -0600 Subject: Mesh cache. Has a bug. --- indra/llmath/llvolume.cpp | 28 ++++++++++++++-------------- indra/llmath/llvolume.h | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 9ea3912a88..52a3fb2195 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1962,7 +1962,7 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) return unpackVolumeFaces(is, header[nm[lod]]["size"].asInteger()); } -BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) +bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { U8* result = NULL; U32 cur_size = 0; @@ -2002,7 +2002,7 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) inflateEnd(&strm); free(result); delete [] in; - return FALSE; + return false; } switch (ret) @@ -2014,7 +2014,7 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) inflateEnd(&strm); free(result); delete [] in; - return FALSE; + return false; break; } @@ -2032,7 +2032,7 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) if (ret != Z_STREAM_END) { free(result); - return FALSE; + return false; } } @@ -2047,7 +2047,7 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) if (!LLSDSerialize::deserialize(mdl, istr, cur_size)) { llwarns << "not a valid mesh asset!" << llendl; - return FALSE; + return false; } } @@ -2074,7 +2074,7 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLVolumeFace& face = mVolumeFaces[i]; - face.mHasBinormals = FALSE; + face.mHasBinormals = false; //copy out indices face.mIndices.resize(idx.size()/2); @@ -2146,24 +2146,24 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) // modifier flags? - BOOL do_mirror = (mParams.getSculptType() & LL_SCULPT_FLAG_MIRROR); - BOOL do_invert = (mParams.getSculptType() &LL_SCULPT_FLAG_INVERT); + bool do_mirror = (mParams.getSculptType() & LL_SCULPT_FLAG_MIRROR); + bool do_invert = (mParams.getSculptType() &LL_SCULPT_FLAG_INVERT); // translate to actions: - BOOL do_reflect_x = FALSE; - BOOL do_reverse_triangles = FALSE; - BOOL do_invert_normals = FALSE; + bool do_reflect_x = false; + bool do_reverse_triangles = false; + bool do_invert_normals = false; if (do_mirror) { - do_reflect_x = TRUE; + do_reflect_x = true; do_reverse_triangles = !do_reverse_triangles; } if (do_invert) { - do_invert_normals = TRUE; + do_invert_normals = true; do_reverse_triangles = !do_reverse_triangles; } @@ -2201,7 +2201,7 @@ BOOL LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } mSculptLevel = 0; // success! - return TRUE; + return true; } void tetrahedron_set_normal(LLVolumeFace::VertexData* cv) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index f1c1fdceba..60c1569e55 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1009,7 +1009,7 @@ protected: public: virtual BOOL createVolumeFacesFromFile(const std::string& file_name); virtual BOOL createVolumeFacesFromStream(std::istream& is); - virtual BOOL unpackVolumeFaces(std::istream& is, S32 size); + virtual bool unpackVolumeFaces(std::istream& is, S32 size); virtual void makeTetrahedron(); virtual BOOL isTetrahedron(); -- cgit v1.2.3 From 807d835c2bfc5d794a74f9690d1fafbe55ff88cc Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 2 Apr 2010 14:43:05 -0500 Subject: First draft of skin weights in .mesh asset --- indra/llmath/llvolume.cpp | 135 ++++++++++++++++------------------------------ indra/llmath/llvolume.h | 6 +++ 2 files changed, 51 insertions(+), 90 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 52a3fb2195..c563af592f 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -47,8 +47,6 @@ #include "llvolume.h" #include "llstl.h" #include "llsdserialize.h" -#include "zlib/zlib.h" - #define DEBUG_SILHOUETTE_BINORMALS 0 #define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette @@ -1964,97 +1962,15 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { - U8* result = NULL; - U32 cur_size = 0; - - { - //input stream is now pointing at a zlib compressed block of LLSD - //decompress block - z_stream strm; - - const U32 CHUNK = 65536; - - U8 *in = new U8[size]; - is.read((char*) in, size); - - U8 out[CHUNK]; - - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.avail_in = size; - strm.next_in = in; - - S32 ret = inflateInit(&strm); - - if (ret != Z_OK) - { - llerrs << "WTF?" << llendl; - } - - do - { - strm.avail_out = CHUNK; - strm.next_out = out; - ret = inflate(&strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR) - { - inflateEnd(&strm); - free(result); - delete [] in; - return false; - } - - switch (ret) - { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; - case Z_DATA_ERROR: - case Z_MEM_ERROR: - inflateEnd(&strm); - free(result); - delete [] in; - return false; - break; - } - - U32 have = CHUNK-strm.avail_out; - - result = (U8*) realloc(result, cur_size + have); - memcpy(result+cur_size, out, have); - cur_size += have; - - } while (strm.avail_out == 0); - - inflateEnd(&strm); - delete [] in; - - if (ret != Z_STREAM_END) - { - free(result); - return false; - } - } - - //result now points to the decompressed LLSD block - + //input stream is now pointing at a zlib compressed block of LLSD + //decompress block LLSD mdl; - + if (!unzip_llsd(mdl, is, size)) { - std::string res_str((char*) result, cur_size); - std::istringstream istr(res_str); - - if (!LLSDSerialize::deserialize(mdl, istr, cur_size)) - { - llwarns << "not a valid mesh asset!" << llendl; - return false; - } + llwarns << "not a valid mesh asset!" << llendl; + return false; } - - - free(result); - - + { U32 face_count = mdl.size(); @@ -2094,11 +2010,50 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) U32 num_verts = pos.size()/(3*2); face.mVertices.resize(num_verts); + if (mdl[i].has("Weights")) + { + face.mWeights.resize(num_verts); + LLSD::Binary weights = mdl[i]["Weights"]; + + LLSD::Binary::iterator iter = weights.begin(); + + U32 cur_vertex = 0; + while (iter != weights.end()) + { + const S32 END_INFLUENCES = 0xFF; + U8 joint = *(iter++); + + U32 cur_influence = 0; + while (joint != END_INFLUENCES) + { + U16 influence = *(iter++); + influence = influence << 8; + influence |= *(iter++); + + F32 w = llmin((F32) influence / 65535.f, 0.99999f); + face.mWeights[cur_vertex].mV[cur_influence++] = (F32) joint + w; + + if (cur_influence >= 4) + { + joint = END_INFLUENCES; + } + else + { + joint = *(iter++); + } + } + + cur_vertex++; + iter++; + } + } + LLVector3 min_pos; LLVector3 max_pos; LLVector2 min_tc; LLVector2 max_tc; + min_pos.setValue(mdl[i]["PositionDomain"]["Min"]); max_pos.setValue(mdl[i]["PositionDomain"]["Max"]); min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 60c1569e55..c6a156ae37 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -49,6 +49,7 @@ class LLVolume; //#include "vmath.h" #include "v2math.h" #include "v3math.h" +#include "v4math.h" #include "llquaternion.h" #include "llstrider.h" #include "v4coloru.h" @@ -887,6 +888,11 @@ public: std::vector mTriStrip; std::vector mEdge; + //list of skin weights for rigged volumes + // format is mWeights[vertex_index].mV[influence] = . + // mWeights.size() should be empty or match mVertices.size() + std::vector mWeights; + private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); -- cgit v1.2.3 From 47ffcdb93d6e2ac1f9d497e43e0213c98d129254 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 6 Apr 2010 16:24:08 -0500 Subject: Rigged attachments (almost works). --- indra/llmath/llvolume.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c563af592f..fdd48b9e9e 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2013,22 +2013,23 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) if (mdl[i].has("Weights")) { face.mWeights.resize(num_verts); + LLSD::Binary weights = mdl[i]["Weights"]; - LLSD::Binary::iterator iter = weights.begin(); + U32 idx = 0; U32 cur_vertex = 0; - while (iter != weights.end()) + while (idx < weights.size() && cur_vertex < num_verts) { - const S32 END_INFLUENCES = 0xFF; - U8 joint = *(iter++); + const U8 END_INFLUENCES = 0xFF; + U8 joint = weights[idx++]; U32 cur_influence = 0; while (joint != END_INFLUENCES) { - U16 influence = *(iter++); + U16 influence = weights[idx++]; influence = influence << 8; - influence |= *(iter++); + influence |= weights[idx++]; F32 w = llmin((F32) influence / 65535.f, 0.99999f); face.mWeights[cur_vertex].mV[cur_influence++] = (F32) joint + w; @@ -2039,13 +2040,18 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } else { - joint = *(iter++); + joint = weights[idx++]; } } cur_vertex++; - iter++; } + + if (cur_vertex != num_verts || idx != weights.size()) + { + llwarns << "Vertex weight count does not match vertex count!" << llendl; + } + } LLVector3 min_pos; -- cgit v1.2.3 From bd216c96498585ca01e1634877d4b184f20fa45f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 22 Apr 2010 16:52:05 -0500 Subject: Fix for shadows from skyboxes hitting the ground. --- indra/llmath/llcamera.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 0c81067919..d6c5f7bbb1 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -143,7 +143,7 @@ private: public: LLVector3 mAgentFrustum[8]; //8 corners of 6-plane frustum F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane - LLPlane getAgentPlane(U32 idx) { return mAgentPlanes[idx].p; } + LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx].p; } public: LLCamera(); -- cgit v1.2.3 From 07c0389f50ccef13ad2699e149dc4b87de3dbd70 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 27 Apr 2010 01:50:06 -0500 Subject: Proper byte ordering when decoding skin weights. --- indra/llmath/llvolume.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index fdd48b9e9e..9d2d157c76 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2028,8 +2028,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) while (joint != END_INFLUENCES) { U16 influence = weights[idx++]; - influence = influence << 8; - influence |= weights[idx++]; + influence |= ((U16) weights[idx++] << 8); F32 w = llmin((F32) influence / 65535.f, 0.99999f); face.mWeights[cur_vertex].mV[cur_influence++] = (F32) joint + w; -- cgit v1.2.3 From d71716aa6dde434b6356cfe85e3a8fce376056dd Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 28 Apr 2010 02:53:12 -0500 Subject: Make LLVolume::createSide a little faster. --- indra/llmath/llvolume.cpp | 82 ++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 37 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 9d2d157c76..5ffc61ce9c 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -87,6 +87,8 @@ const F32 SKEW_MAX = 0.95f; const F32 SCULPT_MIN_AREA = 0.002f; const S32 SCULPT_MIN_AREA_DETAIL = 1; +#define GEN_TRI_STRIP 0 + BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { LLVector3 test = (pt2-pt1)%(pt3-pt2); @@ -5079,7 +5081,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) if (!partial_build) { +#if GEN_TRI_STRIP mTriStrip.clear(); +#endif S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; for(S32 gx = 0;gx 2) ? mNumS/2 : mNumS; @@ -5771,15 +5779,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) mVertices[cur_vertex].mNormal = LLVector3(0,0,0); mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); - - if (cur_vertex == 0) - { - face_min = face_max = mesh[i].mPos; - } - else - { - update_min_max(face_min, face_max, mesh[i].mPos); - } cur_vertex++; @@ -5813,12 +5812,22 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) mVertices[cur_vertex].mNormal = LLVector3(0,0,0); mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); - update_min_max(face_min,face_max,mesh[i].mPos); - cur_vertex++; } } + + //get bounding box for this side + LLVector3& face_min = mExtents[0]; + LLVector3& face_max = mExtents[1]; + mCenter.clearVec(); + + face_min = face_max = mVertices[0].mPosition; + for (U32 i = 1; i < mVertices.size(); ++i) + { + update_min_max(face_min, face_max, mVertices[i].mPosition); + } + mCenter = (face_min + face_max) * 0.5f; S32 cur_index = 0; @@ -5827,13 +5836,17 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) if (!partial_build) { +#if GEN_TRI_STRIP mTriStrip.clear(); +#endif // Now we generate the indices. for (t = 0; t < (mNumT-1); t++) { +#if GEN_TRI_STRIP //prepend terminating index to strip mTriStrip.push_back(mNumS*t); +#endif for (s = 0; s < (mNumS-1); s++) { @@ -5844,6 +5857,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) mIndices[cur_index++] = s+1 + mNumS*t; //bottom right mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right +#if GEN_TRI_STRIP if (s == 0) { mTriStrip.push_back(s+mNumS*t); @@ -5851,6 +5865,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } mTriStrip.push_back(s+1+mNumS*t); mTriStrip.push_back(s+1+mNumS*(t+1)); +#endif mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face if (t < mNumT-2) { //top right/top left neighbor face @@ -5892,44 +5907,37 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face } +#if GEN_TRI_STRIP //append terminating vertex to strip mTriStrip.push_back(mNumS-1+mNumS*(t+1)); +#endif } +#if GEN_TRI_STRIP if (mTriStrip.size()%2 == 1) { mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); } +#endif } //generate normals for (U32 i = 0; i < mIndices.size()/3; i++) //for each triangle { - const S32 i0 = mIndices[i*3+0]; - const S32 i1 = mIndices[i*3+1]; - const S32 i2 = mIndices[i*3+2]; - const VertexData& v0 = mVertices[i0]; - const VertexData& v1 = mVertices[i1]; - const VertexData& v2 = mVertices[i2]; + const U16* idx = &(mIndices[i*3]); + + VertexData* v[] = + { &mVertices[idx[0]], &mVertices[idx[1]], &mVertices[idx[2]] }; //calculate triangle normal - LLVector3 norm = (v0.mPosition-v1.mPosition) % (v0.mPosition-v2.mPosition); + LLVector3 norm = (v[0]->mPosition-v[1]->mPosition) % (v[0]->mPosition-v[2]->mPosition); - for (U32 j = 0; j < 3; j++) - { //add triangle normal to vertices - const S32 idx = mIndices[i*3+j]; - mVertices[idx].mNormal += norm; // * (weight_sum - d[j])/weight_sum; - } + v[0]->mNormal += norm; + v[1]->mNormal += norm; + v[2]->mNormal += norm; //even out quad contributions - if ((i & 1) == 0) - { - mVertices[i2].mNormal += norm; - } - else - { - mVertices[i1].mNormal += norm; - } + v[i%2+1]->mNormal += norm; } // adjust normals based on wrapping and stitching -- cgit v1.2.3 From 8919f4811a7dcaf47dc58159e0ba4ba042183325 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 21 May 2010 23:55:18 -0500 Subject: blah --- indra/llmath/llvolume.cpp | 262 +++++++++++++++++++++++++++++++++------------- indra/llmath/llvolume.h | 27 +++-- indra/llmath/v3math.h | 15 +++ 3 files changed, 226 insertions(+), 78 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 5ffc61ce9c..4e342b0b48 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -43,10 +43,12 @@ #include "v4math.h" #include "m4math.h" #include "m3math.h" +#include "llmatrix4a.h" #include "lldarray.h" #include "llvolume.h" #include "llstl.h" #include "llsdserialize.h" +#include "llvector4a.h" #define DEBUG_SILHOUETTE_BINORMALS 0 #define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette @@ -1992,11 +1994,10 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLVolumeFace& face = mVolumeFaces[i]; - face.mHasBinormals = false; - //copy out indices - face.mIndices.resize(idx.size()/2); - if (idx.empty() || face.mIndices.size() < 3) + face.resizeIndices(idx.size()/2); + + if (idx.empty() || face.mNumIndices < 3) { //why is there an empty index list? llerrs <<"WTF?" << llendl; continue; @@ -2010,7 +2011,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) //copy out vertices U32 num_verts = pos.size()/(3*2); - face.mVertices.resize(num_verts); + face.resizeVertices(num_verts); if (mdl[i].has("Weights")) { @@ -2059,7 +2060,6 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLVector3 max_pos; LLVector2 min_tc; LLVector2 max_tc; - min_pos.setValue(mdl[i]["PositionDomain"]["Min"]); max_pos.setValue(mdl[i]["PositionDomain"]["Max"]); @@ -2074,36 +2074,44 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min = max = LLVector3(0,0,0); + F32* pos_out = face.mPositions; + F32* norm_out = face.mNormals; + F32* tc_out = face.mTexCoords; + for (U32 j = 0; j < num_verts; ++j) { U16* v = (U16*) &(pos[j*3*2]); - face.mVertices[j].mPosition.setVec( - (F32) v[0] / 65535.f * pos_range.mV[0] + min_pos.mV[0], - (F32) v[1] / 65535.f * pos_range.mV[1] + min_pos.mV[1], - (F32) v[2] / 65535.f * pos_range.mV[2] + min_pos.mV[2]); + pos_out[0] = (F32) v[0] / 65535.f * pos_range.mV[0] + min_pos.mV[0]; + pos_out[1] = (F32) v[1] / 65535.f * pos_range.mV[1] + min_pos.mV[1]; + pos_out[2] = (F32) v[2] / 65535.f * pos_range.mV[2] + min_pos.mV[2]; + if (j == 0) { - min = max = face.mVertices[j].mPosition; + min = max = LLVector3(pos_out); } else { - update_min_max(min,max,face.mVertices[j].mPosition); + update_min_max(min,max,pos_out); } + pos_out += 4; + U16* n = (U16*) &(norm[j*3*2]); - face.mVertices[j].mNormal.setVec( - (F32) n[0] / 65535.f * 2.f - 1.f, - (F32) n[1] / 65535.f * 2.f - 1.f, - (F32) n[2] / 65535.f * 2.f - 1.f); + + norm_out[0] = (F32) n[0] / 65535.f * 2.f - 1.f; + norm_out[1] = (F32) n[1] / 65535.f * 2.f - 1.f; + norm_out[2] = (F32) n[2] / 65535.f * 2.f - 1.f; + norm_out += 4; U16* t = (U16*) &(tc[j*2*2]); - face.mVertices[j].mTexCoord.setVec( - (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0], - (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]); + tc_out[0] = (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0]; + tc_out[1] = (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]; + + tc_out += 8; } @@ -2133,24 +2141,29 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) if (do_reflect_x) { - for (S32 i = 0; i < face.mVertices.size(); i++) + LLVector4a* p = (LLVector4a*) face.mPositions; + LLVector4a* n = (LLVector4a*) face.mNormals; + + for (S32 i = 0; i < face.mNumVertices; i++) { - face.mVertices[i].mPosition.mV[VX] *= -1.0f; - face.mVertices[i].mNormal.mV[VX] *= -1.0f; + p[i].mul(-1.0f); + n[i].mul(-1.0f); } } if (do_invert_normals) { - for (S32 i = 0; i < face.mVertices.size(); i++) + LLVector4a* n = (LLVector4a*) face.mNormals; + + for (S32 i = 0; i < face.mNumVertices; i++) { - face.mVertices[i].mNormal *= -1.0f; + n[i].mul(-1.0f); } } if (do_reverse_triangles) { - for (U32 j = 0; j < face.mIndices.size(); j += 3) + for (U32 j = 0; j < face.mNumIndices; j += 3) { // swap the 2nd and 3rd index S32 swap = face.mIndices[j+1]; @@ -2215,9 +2228,28 @@ void LLVolume::makeTetrahedron() tetrahedron_set_normal(cv); - face.mVertices.push_back(cv[0]); - face.mVertices.push_back(cv[1]); - face.mVertices.push_back(cv[2]); + face.resizeVertices(12); + face.resizeIndices(12); + + LLVector4a* v = (LLVector4a*) face.mPositions; + LLVector4a* n = (LLVector4a*) face.mNormals; + LLVector2* tc = (LLVector2*) face.mTexCoords; + + v[0].load3(cv[0].mPosition.mV); + v[1].load3(cv[1].mPosition.mV); + v[2].load3(cv[2].mPosition.mV); + v += 3; + + n[0].load3(cv[0].mNormal.mV); + n[1].load3(cv[1].mNormal.mV); + n[2].load3(cv[2].mNormal.mV); + n += 3; + + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + //side 2 cv[0].mPosition = p[3]; @@ -2226,9 +2258,20 @@ void LLVolume::makeTetrahedron() tetrahedron_set_normal(cv); - face.mVertices.push_back(cv[0]); - face.mVertices.push_back(cv[1]); - face.mVertices.push_back(cv[2]); + v[0].load3(cv[0].mPosition.mV); + v[1].load3(cv[1].mPosition.mV); + v[2].load3(cv[2].mPosition.mV); + v += 3; + + n[0].load3(cv[0].mNormal.mV); + n[1].load3(cv[1].mNormal.mV); + n[2].load3(cv[2].mNormal.mV); + n += 3; + + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; //side 3 cv[0].mPosition = p[3]; @@ -2237,9 +2280,20 @@ void LLVolume::makeTetrahedron() tetrahedron_set_normal(cv); - face.mVertices.push_back(cv[0]); - face.mVertices.push_back(cv[1]); - face.mVertices.push_back(cv[2]); + v[0].load3(cv[0].mPosition.mV); + v[1].load3(cv[1].mPosition.mV); + v[2].load3(cv[2].mPosition.mV); + v += 3; + + n[0].load3(cv[0].mNormal.mV); + n[1].load3(cv[1].mNormal.mV); + n[2].load3(cv[2].mNormal.mV); + n += 3; + + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; //side 4 cv[0].mPosition = p[2]; @@ -2248,14 +2302,25 @@ void LLVolume::makeTetrahedron() tetrahedron_set_normal(cv); - face.mVertices.push_back(cv[0]); - face.mVertices.push_back(cv[1]); - face.mVertices.push_back(cv[2]); + v[0].load3(cv[0].mPosition.mV); + v[1].load3(cv[1].mPosition.mV); + v[2].load3(cv[2].mPosition.mV); + v += 3; + + n[0].load3(cv[0].mNormal.mV); + n[1].load3(cv[1].mNormal.mV); + n[2].load3(cv[2].mNormal.mV); + n += 3; + + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; //set index buffer - for (U32 i = 0; i < 12; i++) + for (U16 i = 0; i < 12; i++) { - face.mIndices.push_back(i); + face.mIndices[i] = i; } mVolumeFaces.push_back(face); @@ -3831,7 +3896,7 @@ S32 LLVolume::getNumTriangles() const for (S32 i = 0; i < getNumVolumeFaces(); ++i) { - triangle_count += getVolumeFace(i).mIndices.size()/3; + triangle_count += getVolumeFace(i).mNumIndices/3; } return triangle_count; @@ -3844,13 +3909,22 @@ S32 LLVolume::getNumTriangles() const void LLVolume::generateSilhouetteVertices(std::vector &vertices, std::vector &normals, std::vector &segments, - const LLVector3& obj_cam_vec, - const LLMatrix4& mat, - const LLMatrix3& norm_mat, + const LLVector3& obj_cam_vec_in, + const LLMatrix4& mat_in, + const LLMatrix3& norm_mat_in, S32 face_mask) { LLMemType m1(LLMemType::MTYPE_VOLUME); + LLMatrix4a mat; + mat.loadu(mat_in); + + LLMatrix4a norm_mat; + norm_mat.loadu(norm_mat_in); + + LLVector4a obj_cam_vec; + obj_cam_vec.load3(obj_cam_vec_in.mV); + vertices.clear(); normals.clear(); segments.clear(); @@ -3868,7 +3942,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, LLVolumeFace& face = *iter; if (!(face_mask & (0x1 << cur_index++)) || - face.mIndices.empty() || face.mEdge.empty()) + face.mNumIndices == 0 || face.mEdge.empty()) { continue; } @@ -3885,7 +3959,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, #if DEBUG_SILHOUETTE_EDGE_MAP //for each triangle - U32 count = face.mIndices.size(); + U32 count = face.mNumIndices; for (U32 j = 0; j < count/3; j++) { //get vertices S32 v1 = face.mIndices[j*3+0]; @@ -3938,7 +4012,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, #elif DEBUG_SILHOUETTE_NORMALS //for each vertex - for (U32 j = 0; j < face.mVertices.size(); j++) { + for (U32 j = 0; j < face.mNumVertices; j++) { vertices.push_back(face.mVertices[j].mPosition); vertices.push_back(face.mVertices[j].mPosition + face.mVertices[j].mNormal*0.1f); normals.push_back(LLVector3(0,0,1)); @@ -3964,26 +4038,36 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, //for each triangle std::vector fFacing; - vector_append(fFacing, face.mIndices.size()/3); - for (U32 j = 0; j < face.mIndices.size()/3; j++) + vector_append(fFacing, face.mNumIndices/3); + + LLVector4a* v = (LLVector4a*) face.mPositions; + LLVector4a* n = (LLVector4a*) face.mNormals; + + for (U32 j = 0; j < face.mNumIndices/3; j++) { //approximate normal S32 v1 = face.mIndices[j*3+0]; S32 v2 = face.mIndices[j*3+1]; S32 v3 = face.mIndices[j*3+2]; - LLVector3 norm = (face.mVertices[v1].mPosition - face.mVertices[v2].mPosition) % - (face.mVertices[v2].mPosition - face.mVertices[v3].mPosition); - - if (norm.magVecSquared() < 0.00000001f) + LLVector4a c1,c2; + c1.setSub(v[v1], v[v2]); + c2.setSub(v[v2], v[v3]); + + LLVector4a norm; + + norm.setCross3(c1, c2); + + if (norm.dot3(norm) < 0.00000001f) { fFacing[j] = AWAY | TOWARDS; } else { //get view vector - LLVector3 view = (obj_cam_vec-face.mVertices[v1].mPosition); - bool away = view * norm > 0.0f; + LLVector4a view; + view.setSub(obj_cam_vec, v[v1]); + bool away = view.dot3(norm) > 0.0f; if (away) { fFacing[j] = AWAY; @@ -3996,7 +4080,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, } //for each triangle - for (U32 j = 0; j < face.mIndices.size()/3; j++) + for (U32 j = 0; j < face.mNumIndices/3; j++) { if (fFacing[j] == (AWAY | TOWARDS)) { //this is a degenerate triangle @@ -4029,9 +4113,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, S32 v1 = face.mIndices[j*3+k]; S32 v2 = face.mIndices[j*3+((k+1)%3)]; - vertices.push_back(face.mVertices[v1].mPosition*mat); - LLVector3 norm1 = face.mVertices[v1].mNormal * norm_mat; - norm1.normVec(); + LLVector4a t; + mat.affineTransform(v[v1], t); + vertices.push_back(LLVector3(t[0], t[1], t[2])); + + norm_mat.rotate(n[v1], t); + + t.normalize3Fast(); + LLVector3 norm1 = LLVector3(t[0], t[1], t[2]); normals.push_back(norm1); vertices.push_back(face.mVertices[v2].mPosition*mat); @@ -4088,7 +4177,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, genBinormals(i); } - for (U32 tri = 0; tri < face.mIndices.size()/3; tri++) + for (U32 tri = 0; tri < face.mNumIndices/3; tri++) { S32 index1 = face.mIndices[tri*3+0]; S32 index2 = face.mIndices[tri*3+1]; @@ -4928,7 +5017,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) VertexMapData::PointMap point_map; //remove redundant vertices - for (U32 i = 0; i < mIndices.size(); ++i) + for (U32 i = 0; i < mNumIndices; ++i) { U16 index = mIndices[i]; @@ -4953,7 +5042,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) if (!found) { new_face.mVertices.push_back(cv); - U16 index = (U16) new_face.mVertices.size()-1; + U16 index = (U16) new_face.mNumVertices-1; new_face.mIndices.push_back(index); VertexMapData d; @@ -5053,7 +5142,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) mVertices.clear(); } - S32 vtop = mVertices.size(); + S32 vtop = mNumVertices; for(int gx = 0;gx 65536) + if (face.mNumVertices + mNumVertices > 65536) { llerrs << "Cannot append face -- 16-bit overflow will occur." << llendl; } - for (U32 i = 0; i < face.mVertices.size(); ++i) + for (U32 i = 0; i < face.mNumVertices; ++i) { VertexData v = face.mVertices[i]; v.mPosition = v.mPosition*mat; @@ -5676,7 +5796,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat, LLMatrix } - for (U32 i = 0; i < face.mIndices.size(); ++i) + for (U32 i = 0; i < face.mNumIndices; ++i) { mIndices.push_back(face.mIndices[i]+offset); } @@ -5823,7 +5943,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) mCenter.clearVec(); face_min = face_max = mVertices[0].mPosition; - for (U32 i = 1; i < mVertices.size(); ++i) + for (U32 i = 1; i < mNumVertices; ++i) { update_min_max(face_min, face_max, mVertices[i].mPosition); } @@ -5922,7 +6042,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } //generate normals - for (U32 i = 0; i < mIndices.size()/3; i++) //for each triangle + for (U32 i = 0; i < mNumIndices/3; i++) //for each triangle { const U16* idx = &(mIndices[i*3]); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c6a156ae37..17be642d4a 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -794,20 +794,28 @@ public: LLVolumeFace() : mID(0), mTypeMask(0), - mHasBinormals(FALSE), mBeginS(0), mBeginT(0), mNumS(0), - mNumT(0) + mNumT(0), + mNumVertices(0), + mNumIndices(0), + mPositions(NULL), + mNormals(NULL), + mBinormals(NULL), + mTexCoords(NULL), + mIndices(NULL) { } BOOL create(LLVolume* volume, BOOL partial_build = FALSE); void createBinormals(); - void makeTriStrip(); void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform); + void resizeVertices(S32 num_verts); + void resizeIndices(S32 num_indices); + class VertexData { public: @@ -873,7 +881,6 @@ public: S32 mID; U32 mTypeMask; LLVector3 mCenter; - BOOL mHasBinormals; // Only used for INNER/OUTER faces S32 mBeginS; @@ -883,9 +890,15 @@ public: LLVector3 mExtents[2]; //minimum and maximum point of face - std::vector mVertices; - std::vector mIndices; - std::vector mTriStrip; + S32 mNumVertices; + S32 mNumIndices; + + F32* mPositions; + F32* mNormals; + F32* mBinormals; + F32* mTexCoords; + U16* mIndices; + std::vector mEdge; //list of skin weights for rigged volumes diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 76dd938887..0e7d72e958 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -532,6 +532,21 @@ inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos) } } +inline void update_min_max(LLVector3& min, LLVector3& max, const F32* pos) +{ + for (U32 i = 0; i < 3; i++) + { + if (min.mV[i] > pos[i]) + { + min.mV[i] = pos[i]; + } + if (max.mV[i] < pos[i]) + { + max.mV[i] = pos[i]; + } + } +} + inline F32 angle_between(const LLVector3& a, const LLVector3& b) { LLVector3 an = a; -- cgit v1.2.3 From 4d57cb3c0975ff0bcea0d6fb3498f2d90962ff16 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 22 May 2010 04:35:02 -0500 Subject: Vectorize/memory align buffers in llvolumeface WIP --- indra/llmath/llvolume.cpp | 720 +++++++++++++++++++++++----------------------- indra/llmath/llvolume.h | 35 ++- 2 files changed, 386 insertions(+), 369 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 4e342b0b48..01fe2be371 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1,4 +1,5 @@ /** + * @file llvolume.cpp * * $LicenseInfo:firstyear=2002&license=viewergpl$ @@ -89,8 +90,6 @@ const F32 SKEW_MAX = 0.95f; const F32 SCULPT_MIN_AREA = 0.002f; const S32 SCULPT_MIN_AREA_DETAIL = 1; -#define GEN_TRI_STRIP 0 - BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { LLVector3 test = (pt2-pt1)%(pt3-pt2); @@ -134,21 +133,25 @@ BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, con // and returns the intersection point along dir in intersection_t. // Moller-Trumbore algorithm -BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, +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 two_sided) { F32 u, v, t; /* find vectors for two edges sharing vert0 */ - LLVector3 edge1 = vert1 - vert0; + LLVector4a edge1; + edge1.setSub(vert1, vert0); - LLVector3 edge2 = vert2 - vert0;; + + LLVector4a edge2; + edge2.setSub(vert2, vert0); /* begin calculating determinant - also used to calculate U parameter */ - LLVector3 pvec = dir % edge2; - + LLVector4a pvec; + pvec.setCross3(dir, edge2); + /* if determinant is near zero, ray lies in plane of triangle */ - F32 det = edge1 * pvec; + F32 det = edge1.dot3(pvec); if (!two_sided) { @@ -158,10 +161,11 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } /* calculate distance from vert0 to ray origin */ - LLVector3 tvec = orig - vert0; + LLVector4a tvec; + tvec.setSub(orig, vert0); /* calculate U parameter and test bounds */ - u = tvec * pvec; + u = tvec.dot3(pvec); if (u < 0.f || u > det) { @@ -169,17 +173,18 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } /* prepare to test V parameter */ - LLVector3 qvec = tvec % edge1; + LLVector4a qvec; + qvec.setCross3(tvec, edge1); /* calculate V parameter and test bounds */ - v = dir * qvec; + v = dir.dot3(qvec); if (v < 0.f || u + v > det) { return FALSE; } /* calculate t, scale parameters, ray intersects triangle */ - t = edge2 * qvec; + t = edge2.dot3(qvec); F32 inv_det = 1.0 / det; t *= inv_det; u *= inv_det; @@ -195,20 +200,22 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons F32 inv_det = 1.0 / det; /* calculate distance from vert0 to ray origin */ - LLVector3 tvec = orig - vert0; + LLVector4a tvec; + tvec.setSub(orig, vert0); /* calculate U parameter and test bounds */ - u = (tvec * pvec) * inv_det; + u = (tvec.dot3(pvec)) * inv_det; if (u < 0.f || u > 1.f) { return FALSE; } /* prepare to test V parameter */ - LLVector3 qvec = tvec - edge1; + LLVector4a qvec; + qvec.setSub(tvec, edge1); /* calculate V parameter and test bounds */ - v = (dir * qvec) * inv_det; + v = (dir.dot3(qvec)) * inv_det; if (v < 0.f || u + v > 1.f) { @@ -216,7 +223,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } /* calculate t, ray intersects triangle */ - t = (edge2 * qvec) * inv_det; + t = (edge2.dot3(qvec)) * inv_det; } if (intersection_a != NULL) @@ -4120,13 +4127,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, norm_mat.rotate(n[v1], t); t.normalize3Fast(); - LLVector3 norm1 = LLVector3(t[0], t[1], t[2]); - normals.push_back(norm1); + normals.push_back(LLVector3(t[0], t[1], t[2])); - vertices.push_back(face.mVertices[v2].mPosition*mat); - LLVector3 norm2 = face.mVertices[v2].mNormal * norm_mat; - norm2.normVec(); - normals.push_back(norm2); + mat.affineTransform(v[v2], t); + vertices.push_back(LLVector3(t[0], t[1], t[2])); + + norm_mat.rotate(n[v2], t); + t.normalize3Fast(); + normals.push_back(LLVector3(t[0], t[1], t[2])); segments.push_back(vertices.size()); } @@ -4177,6 +4185,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, genBinormals(i); } + LLVector4a starta, dira; + + LLVector4a* p = (LLVector4a*) face.mPositions; + for (U32 tri = 0; tri < face.mNumIndices/3; tri++) { S32 index1 = face.mIndices[tri*3+0]; @@ -4185,15 +4197,15 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, F32 a, b, t; - if (LLTriangleRayIntersect(face.mVertices[index1].mPosition, - face.mVertices[index2].mPosition, - face.mVertices[index3].mPosition, - start, dir, &a, &b, &t, FALSE)) + if (LLTriangleRayIntersect(p[index1], + p[index2], + p[index3], + starta, dira, &a, &b, &t, FALSE)) { if ((t >= 0.f) && // if hit is after start (t <= 1.f) && // and before end (t < closest_t)) // and this hit is closer - { + { closest_t = t; hit_face = i; @@ -4201,27 +4213,35 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, { *intersection = start + dir * closest_t; } - + + if (tex_coord != NULL) - { - *tex_coord = ((1.f - a - b) * face.mVertices[index1].mTexCoord + - a * face.mVertices[index2].mTexCoord + - b * face.mVertices[index3].mTexCoord); + { + LLVector2* tc = (LLVector2*) face.mTexCoords; + *tex_coord = ((1.f - a - b) * tc[index1] + + a * tc[index2] + + b * tc[index3]); } if (normal != NULL) - { - *normal = ((1.f - a - b) * face.mVertices[index1].mNormal + - a * face.mVertices[index2].mNormal + - b * face.mVertices[index3].mNormal); + { + LLVector4* norm = (LLVector4*) face.mNormals; + + *normal = ((1.f - a - b) * LLVector3(norm[index1]) + + a * LLVector3(norm[index2]) + + b * LLVector3(norm[index3])); } if (bi_normal != NULL) - { - *bi_normal = ((1.f - a - b) * face.mVertices[index1].mBinormal + - a * face.mVertices[index2].mBinormal + - b * face.mVertices[index3].mBinormal); + { + LLVector4* binormal = (LLVector4*) face.mBinormals; + if (binormal) + { + *bi_normal = ((1.f - a - b) * LLVector3(binormal[index1]) + + a * LLVector3(binormal[index2]) + + b * LLVector3(binormal[index3])); + } } } @@ -4992,6 +5012,14 @@ std::ostream& operator<<(std::ostream &s, const LLVolume *volumep) return s; } +LLVolumeFace::~LLVolumeFace() +{ + _mm_free(mPositions); + _mm_free(mNormals); + _mm_free(mTexCoords); + _mm_free(mIndices); + _mm_free(mBinormals); +} BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { @@ -5012,6 +5040,7 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) void LLVolumeFace::optimize(F32 angle_cutoff) { +#if 0 //disabling until a vectorized version is available LLVolumeFace new_face; VertexMapData::PointMap point_map; @@ -5063,6 +5092,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) mVertices = new_face.mVertices; mIndices = new_face.mIndices; +#endif } void LerpPlanarVertex(LLVolumeFace::VertexData& v0, @@ -5127,20 +5157,22 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) corners[1].mTexCoord=corners[2].mTexCoord; corners[2].mTexCoord=swap; } - baseVert.mBinormal = calc_binormal_from_triangle( + + LLVector4a binormal; + + calc_binormal_from_triangle( binormal, corners[0].mPosition, corners[0].mTexCoord, corners[1].mPosition, corners[1].mTexCoord, corners[2].mPosition, corners[2].mTexCoord); - for(int t = 0; t < 4; t++){ - corners[t].mBinormal = baseVert.mBinormal; - corners[t].mNormal = baseVert.mNormal; - } - mHasBinormals = TRUE; - if (partial_build) - { - mVertices.clear(); - } + S32 size = (grid_size+1)*(grid_size+1); + resizeVertices(size); + allocateBinormals(size); + + LLVector4a* pos = (LLVector4a*) mPositions; + LLVector4a* norm = (LLVector4a*) mNormals; + LLVector4a* binorm = (LLVector4a*) mBinormals; + LLVector2* tc = (LLVector2*) mTexCoords; S32 vtop = mNumVertices; for(int gx = 0;gx=0;i--) { - mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); - } - -#if GEN_TRI_STRIP - if (gy == 0) - { - mTriStrip.push_back((gx+1)*(grid_size+1)); - mTriStrip.push_back((gx+1)*(grid_size+1)); - mTriStrip.push_back(gx*(grid_size+1)); - } - - mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1)); - mTriStrip.push_back(gy+1+gx*(grid_size+1)); - - - if (gy == grid_size-1) - { - mTriStrip.push_back(gy+1+gx*(grid_size+1)); - } -#endif + *out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]); + } } else { for(S32 i=0;i<6;i++) { - mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); - } - -#if GEN_TRI_STRIP - if (gy == 0) - { - mTriStrip.push_back(gx*(grid_size+1)); - mTriStrip.push_back(gx*(grid_size+1)); - mTriStrip.push_back((gx+1)*(grid_size+1)); + *out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]); } - - mTriStrip.push_back(gy+1+gx*(grid_size+1)); - mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1)); - - if (gy == grid_size-1) - { - mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1)); - } -#endif } } } - -#if GEN_TRI_STRIP - if (mTriStrip.size()%2 == 1) - { - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - } -#endif } return TRUE; @@ -5267,11 +5262,25 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) num_vertices = profile.size(); num_indices = (profile.size() - 2)*3; - mVertices.resize(num_vertices); + if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) + { + resizeVertices(num_vertices+1); + allocateBinormals(num_vertices+1); - if (!partial_build) + if (!partial_build) + { + resizeIndices(num_indices+3); + } + } + else { - mIndices.resize(num_indices); + resizeVertices(num_vertices); + allocateBinormals(num_vertices); + + if (!partial_build) + { + resizeIndices(num_indices); + } } S32 max_s = volume->getProfile().getTotal(); @@ -5298,79 +5307,87 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) LLVector3& min = mExtents[0]; LLVector3& max = mExtents[1]; + LLVector2* tc = (LLVector2*) mTexCoords; + LLVector4a* pos = (LLVector4a*) mPositions; + LLVector4a* norm = (LLVector4a*) mNormals; + LLVector4a* binorm = (LLVector4a*) mBinormals; + // Copy the vertices into the array for (S32 i = 0; i < num_vertices; i++) { if (mTypeMask & TOP_MASK) { - mVertices[i].mTexCoord.mV[0] = profile[i].mV[0]+0.5f; - mVertices[i].mTexCoord.mV[1] = profile[i].mV[1]+0.5f; + tc[i].mV[0] = profile[i].mV[0]+0.5f; + tc[i].mV[1] = profile[i].mV[1]+0.5f; } else { // Mirror for underside. - mVertices[i].mTexCoord.mV[0] = profile[i].mV[0]+0.5f; - mVertices[i].mTexCoord.mV[1] = 0.5f - profile[i].mV[1]; + tc[i].mV[0] = profile[i].mV[0]+0.5f; + tc[i].mV[1] = 0.5f - profile[i].mV[1]; } - mVertices[i].mPosition = mesh[i + offset].mPos; + pos[i].load3(mesh[i + offset].mPos.mV); if (i == 0) { - min = max = mVertices[i].mPosition; - min_uv = max_uv = mVertices[i].mTexCoord; + min = max = mesh[i+offset].mPos; + min_uv = max_uv = tc[i]; } else { - update_min_max(min,max, mVertices[i].mPosition); - update_min_max(min_uv, max_uv, mVertices[i].mTexCoord); + update_min_max(min,max, mesh[i+offset].mPos); + update_min_max(min_uv, max_uv, tc[i]); } } mCenter = (min+max)*0.5f; cuv = (min_uv + max_uv)*0.5f; - LLVector3 binormal = calc_binormal_from_triangle( + LLVector4a binormal; + calc_binormal_from_triangle(binormal, mCenter, cuv, - mVertices[0].mPosition, mVertices[0].mTexCoord, - mVertices[1].mPosition, mVertices[1].mTexCoord); - binormal.normVec(); + mesh[0+offset].mPos, tc[0], + mesh[1+offset].mPos, tc[1]); + binormal.normalize3Fast(); + + LLVector4a normal; + LLVector4a d0, d1; + LLVector4a center; + + center.load3(mCenter.mV); - LLVector3 d0; - LLVector3 d1; - LLVector3 normal; + d0.setSub(center, pos[0]); + d1.setSub(center, pos[1]); - d0 = mCenter-mVertices[0].mPosition; - d1 = mCenter-mVertices[1].mPosition; + if (mTypeMask & TOP_MASK) + { + normal.setCross3(d0, d1); + } + else + { + normal.setCross3(d1, d0); + } - normal = (mTypeMask & TOP_MASK) ? (d0%d1) : (d1%d0); - normal.normVec(); + normal.normalize3Fast(); VertexData vd; vd.mPosition = mCenter; - vd.mNormal = normal; - vd.mBinormal = binormal; vd.mTexCoord = cuv; if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) { - mVertices.push_back(vd); + pos[num_vertices].load4a((F32*) ¢er.mQ); + tc[num_vertices] = cuv; num_vertices++; - if (!partial_build) - { - vector_append(mIndices, 3); - } } - for (S32 i = 0; i < num_vertices; i++) { - mVertices[i].mBinormal = binormal; - mVertices[i].mNormal = normal; + binorm[i].load4a((F32*) &binormal.mQ); + norm[i].load4a((F32*) &normal.mQ); } - mHasBinormals = TRUE; - if (partial_build) { return TRUE; @@ -5478,8 +5495,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) pt2--; } } - - makeTriStrip(); } else { @@ -5584,8 +5599,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) pt2--; } } - - makeTriStrip(); } } else @@ -5607,131 +5620,63 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) mIndices[3*i+v2] = i + 1; } -#if GEN_TRI_STRIP - //make tri strip - if (mTypeMask & OPEN_MASK) - { - makeTriStrip(); - } - else - { - S32 j = num_vertices-2; - if (mTypeMask & TOP_MASK) - { - mTriStrip.push_back(0); - for (S32 i = 0; i <= j; ++i) - { - mTriStrip.push_back(i); - if (i != j) - { - mTriStrip.push_back(j); - } - --j; - } - } - else - { - mTriStrip.push_back(j); - for (S32 i = 0; i <= j; ++i) - { - if (i != j) - { - mTriStrip.push_back(j); - } - mTriStrip.push_back(i); - --j; - } - } - - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - if (mTriStrip.size()%2 == 1) - { - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - } - } -#endif } return TRUE; } -void LLVolumeFace::makeTriStrip() -{ -#if GEN_TRI_STRIP - for (U32 i = 0; i < mNumIndices; i+=3) - { - U16 i0 = mIndices[i]; - U16 i1 = mIndices[i+1]; - U16 i2 = mIndices[i+2]; - - if ((i/3)%2 == 1) - { - mTriStrip.push_back(i0); - mTriStrip.push_back(i0); - mTriStrip.push_back(i1); - mTriStrip.push_back(i2); - mTriStrip.push_back(i2); - } - else - { - mTriStrip.push_back(i2); - mTriStrip.push_back(i2); - mTriStrip.push_back(i1); - mTriStrip.push_back(i0); - mTriStrip.push_back(i0); - } - } - - if (mTriStrip.size()%2 == 1) - { - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - } -#endif -} - void LLVolumeFace::createBinormals() { LLMemType m1(LLMemType::MTYPE_VOLUME); - if (!mHasBinormals) + if (!mBinormals) { + allocateBinormals(mNumVertices); + //generate binormals + LLStrider pos; + pos = (LLVector3*) mPositions; + pos.setStride(16); + + LLVector2* tc = (LLVector2*) mTexCoords; + LLVector4a* binorm = (LLVector4a*) mBinormals; + for (U32 i = 0; i < mNumIndices/3; i++) { //for each triangle - const VertexData& v0 = mVertices[mIndices[i*3+0]]; - const VertexData& v1 = mVertices[mIndices[i*3+1]]; - const VertexData& v2 = mVertices[mIndices[i*3+2]]; + const U16& i0 = mIndices[i*3+0]; + const U16& i1 = mIndices[i*3+1]; + const U16& i2 = mIndices[i*3+2]; //calculate binormal - LLVector3 binorm = calc_binormal_from_triangle(v0.mPosition, v0.mTexCoord, - v1.mPosition, v1.mTexCoord, - v2.mPosition, v2.mTexCoord); + LLVector4a binormal; + calc_binormal_from_triangle(binormal, + pos[i0], tc[i0], + pos[i1], tc[i1], + pos[i2], tc[i2]); - for (U32 j = 0; j < 3; j++) - { //add triangle normal to vertices - mVertices[mIndices[i*3+j]].mBinormal += binorm; // * (weight_sum - d[j])/weight_sum; - } + + //add triangle normal to vertices + binorm[i0].add(binormal); + binorm[i1].add(binormal); + binorm[i2].add(binormal); //even out quad contributions if (i % 2 == 0) { - mVertices[mIndices[i*3+2]].mBinormal += binorm; + binorm[i2].add(binormal); } else { - mVertices[mIndices[i*3+1]].mBinormal += binorm; + binorm[i1].add(binormal); } } //normalize binormals for (U32 i = 0; i < mNumVertices; i++) { - mVertices[i].mBinormal.normVec(); - mVertices[i].mNormal.normVec(); + binorm[i].normalize3Fast(); } - - mHasBinormals = TRUE; } } @@ -5754,6 +5699,13 @@ void LLVolumeFace::resizeVertices(S32 num_verts) mNumVertices = num_verts; } +void LLVolumeFace::allocateBinormals(S32 num_verts) +{ + _mm_free(mBinormals); + mBinormals = (F32*) _mm_malloc(num_verts*16, 16); +} + + void LLVolumeFace::resizeIndices(S32 num_indices) { _mm_free(mIndices); @@ -5761,44 +5713,107 @@ void LLVolumeFace::resizeIndices(S32 num_indices) //pad index block end to allow for QWORD reads S32 size = ((num_indices*2) + 0xF) & ~0xF; - mIndices = (U16*) _mm_malloc(size); + mIndices = (U16*) _mm_malloc(size,16); mNumIndices = num_indices; } -void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat, LLMatrix4& norm_mat) +void LLVolumeFace::fillFromLegacyData(std::vector& v, std::vector& idx) +{ + resizeVertices(v.size()); + resizeIndices(idx.size()); + + for (U32 i = 0; i < v.size(); ++i) + { + for (U32 j = 0; j < 3; ++j) + { + mPositions[i*4+j] = v[i].mPosition[j]; + mNormals[i*4+j] = v[i].mNormal[j]; + } + + mTexCoords[i*2+0] = v[i].mTexCoord.mV[0]; + mTexCoords[i*2+1] = v[i].mTexCoord.mV[1]; + } + + for (U32 i = 0; i < idx.size(); ++i) + { + mIndices[i] = idx[i]; + } +} + +void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMatrix4& norm_mat_in) { U16 offset = mNumVertices; - if (face.mNumVertices + mNumVertices > 65536) + S32 new_count = face.mNumVertices + mNumVertices; + + if (new_count > 65536) { llerrs << "Cannot append face -- 16-bit overflow will occur." << llendl; } + + F32* new_pos = (F32*) _mm_malloc(new_count*16, 16); + F32* new_norm = (F32*) _mm_malloc(new_count*16, 16); + F32* new_tc = (F32*) _mm_malloc((new_count*8+0xF) & ~0xF, 16); + + LLVector4a::memcpyNonAliased16(new_pos, mPositions, new_count*4); + LLVector4a::memcpyNonAliased16(new_norm, mNormals, new_count*4); + LLVector4a::memcpyNonAliased16(new_tc, mTexCoords, new_count*2); + + _mm_free(mPositions); + _mm_free(mNormals); + _mm_free(mTexCoords); + + mPositions = new_pos; + mNormals = new_norm; + mTexCoords = new_tc; + + mNumVertices = new_count; + + LLVector4a* dst_pos = (LLVector4a*) mPositions+offset; + LLVector2* dst_tc = (LLVector2*) mTexCoords+offset; + LLVector4a* dst_norm = (LLVector4a*) mNormals+offset; + + LLVector4a* src_pos = (LLVector4a*) face.mPositions; + LLVector2* src_tc = (LLVector2*) face.mTexCoords; + LLVector4a* src_norm = (LLVector4a*) face.mNormals; + + LLMatrix4a mat, norm_mat; + mat.loadu(mat_in); + norm_mat.loadu(norm_mat_in); + for (U32 i = 0; i < face.mNumVertices; ++i) { - VertexData v = face.mVertices[i]; - v.mPosition = v.mPosition*mat; - v.mNormal = v.mNormal * norm_mat; + mat.affineTransform(src_pos[i], dst_pos[i]); + norm_mat.rotate(src_norm[i], dst_norm[i]); + dst_norm[i].normalize3Fast(); - v.mNormal.normalize(); - - mVertices.push_back(v); + dst_tc[i] = src_tc[i]; if (offset == 0 && i == 0) { - mExtents[0] = mExtents[1] = v.mPosition; + mExtents[0] = mExtents[1] = LLVector3((F32*) &(dst_pos[i].mQ)); } else { - update_min_max(mExtents[0], mExtents[1], v.mPosition); + update_min_max(mExtents[0], mExtents[1], (F32*) &(dst_pos[i].mQ)); } } - + + new_count = mNumIndices + face.mNumIndices; + U16* new_indices = (U16*) _mm_malloc((new_count*2+0xF) & ~0xF, 16); + LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, new_count/2); + _mm_free(mIndices); + mIndices = new_indices; + mNumIndices = new_count; + + U16* dst_idx = mIndices+offset; + for (U32 i = 0; i < face.mNumIndices; ++i) { - mIndices.push_back(face.mIndices[i]+offset); + dst_idx[i] = face.mIndices[i]+offset; } } @@ -5828,21 +5843,20 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) num_vertices = mNumS*mNumT; num_indices = (mNumS-1)*(mNumT-1)*6; - mVertices.resize(num_vertices); - if (!partial_build) { - mIndices.resize(num_indices); + resizeVertices(num_vertices); + resizeIndices(num_indices); if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { mEdge.resize(num_indices); } } - else - { - mHasBinormals = FALSE; - } + + LLVector4a* pos = (LLVector4a*) mPositions; + LLVector4a* norm = (LLVector4a*) mNormals; + LLVector2* tc = (LLVector2*) mTexCoords; S32 begin_stex = llfloor( profile[mBeginS].mV[2] ); S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS; @@ -5894,21 +5908,21 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) i = mBeginS + s + max_s*t; } - mVertices[cur_vertex].mPosition = mesh[i].mPos; - mVertices[cur_vertex].mTexCoord = LLVector2(ss,tt); + pos[cur_vertex].load3(mesh[i].mPos.mV); + tc[cur_vertex] = LLVector2(ss,tt); - mVertices[cur_vertex].mNormal = LLVector3(0,0,0); - mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); + norm[cur_vertex].clear(); cur_vertex++; if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2 && s > 0) { - mVertices[cur_vertex].mPosition = mesh[i].mPos; - mVertices[cur_vertex].mTexCoord = LLVector2(ss,tt); + + pos[cur_vertex].load3(mesh[i].mPos.mV); + tc[cur_vertex] = LLVector2(ss,tt); - mVertices[cur_vertex].mNormal = LLVector3(0,0,0); - mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); + norm[cur_vertex].clear(); + cur_vertex++; } } @@ -5926,12 +5940,10 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) i = mBeginS + s + max_s*t; ss = profile[mBeginS + s].mV[2] - begin_stex; - mVertices[cur_vertex].mPosition = mesh[i].mPos; - mVertices[cur_vertex].mTexCoord = LLVector2(ss,tt); - - mVertices[cur_vertex].mNormal = LLVector3(0,0,0); - mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); - + pos[cur_vertex].load3(mesh[i].mPos.mV); + tc[cur_vertex] = LLVector2(ss,tt); + norm[cur_vertex].clear(); + cur_vertex++; } } @@ -5942,10 +5954,11 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector3& face_max = mExtents[1]; mCenter.clearVec(); - face_min = face_max = mVertices[0].mPosition; + face_min = face_max = LLVector3((F32*) &(pos[i].mQ)); + for (U32 i = 1; i < mNumVertices; ++i) { - update_min_max(face_min, face_max, mVertices[i].mPosition); + update_min_max(face_min, face_max, (F32*) &(pos[i].mQ)); } mCenter = (face_min + face_max) * 0.5f; @@ -5956,18 +5969,9 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) if (!partial_build) { -#if GEN_TRI_STRIP - mTriStrip.clear(); -#endif - // Now we generate the indices. for (t = 0; t < (mNumT-1); t++) { -#if GEN_TRI_STRIP - //prepend terminating index to strip - mTriStrip.push_back(mNumS*t); -#endif - for (s = 0; s < (mNumS-1); s++) { mIndices[cur_index++] = s + mNumS*t; //bottom left @@ -5977,16 +5981,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) mIndices[cur_index++] = s+1 + mNumS*t; //bottom right mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right -#if GEN_TRI_STRIP - if (s == 0) - { - mTriStrip.push_back(s+mNumS*t); - mTriStrip.push_back(s+mNumS*(t+1)); - } - mTriStrip.push_back(s+1+mNumS*t); - mTriStrip.push_back(s+1+mNumS*(t+1)); -#endif - mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face if (t < mNumT-2) { //top right/top left neighbor face mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; @@ -6027,52 +6021,55 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face } -#if GEN_TRI_STRIP - //append terminating vertex to strip - mTriStrip.push_back(mNumS-1+mNumS*(t+1)); -#endif } - -#if GEN_TRI_STRIP - if (mTriStrip.size()%2 == 1) - { - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - } -#endif } //generate normals for (U32 i = 0; i < mNumIndices/3; i++) //for each triangle { const U16* idx = &(mIndices[i*3]); - - VertexData* v[] = - { &mVertices[idx[0]], &mVertices[idx[1]], &mVertices[idx[2]] }; - - //calculate triangle normal - LLVector3 norm = (v[0]->mPosition-v[1]->mPosition) % (v[0]->mPosition-v[2]->mPosition); + - v[0]->mNormal += norm; - v[1]->mNormal += norm; - v[2]->mNormal += norm; + LLVector4a* v[] = + { pos+idx[0], pos+idx[1], pos+idx[2] }; + + LLVector4a* n[] = + { norm+idx[0], norm+idx[1], norm+idx[2] }; + + //calculate triangle normal + LLVector4a a, b, c; + + a.setSub(*v[0], *v[1]); + b.setSub(*v[0], *v[2]); + c.setCross3(a,b); + n[0]->add(c); + n[1]->add(c); + n[2]->add(c); + //even out quad contributions - v[i%2+1]->mNormal += norm; + n[i%2+1]->add(c); } // adjust normals based on wrapping and stitching - BOOL s_bottom_converges = ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f); - BOOL s_top_converges = ((mVertices[mNumS-1].mPosition - mVertices[mNumS*(mNumT-2)+mNumS-1].mPosition).magVecSquared() < 0.000001f); + LLVector4a top; + top.setSub(pos[0], pos[mNumS*(mNumT-2)]); + BOOL s_bottom_converges = (top.dot3(top) < 0.000001f); + + top.setSub(pos[mNumS-1], pos[mNumS*(mNumT-2)+mNumS-1]); + BOOL s_top_converges = (top.dot3(top) < 0.000001f); + if (sculpt_stitching == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes { if (volume->getPath().isOpen() == FALSE) { //wrap normals on T for (S32 i = 0; i < mNumS; i++) { - LLVector3 norm = mVertices[i].mNormal + mVertices[mNumS*(mNumT-1)+i].mNormal; - mVertices[i].mNormal = norm; - mVertices[mNumS*(mNumT-1)+i].mNormal = norm; + LLVector4a n; + n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); + norm[i] = n; + norm[mNumS*(mNumT-1)+i] = n; } } @@ -6080,9 +6077,10 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { //wrap normals on S for (S32 i = 0; i < mNumT; i++) { - LLVector3 norm = mVertices[mNumS*i].mNormal + mVertices[mNumS*i+mNumS-1].mNormal; - mVertices[mNumS * i].mNormal = norm; - mVertices[mNumS * i+mNumS-1].mNormal = norm; + LLVector4a n; + n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); + norm[mNumS * i] = n; + norm[mNumS * i+mNumS-1] = n; } } @@ -6093,7 +6091,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { //all lower S have same normal for (S32 i = 0; i < mNumT; i++) { - mVertices[mNumS*i].mNormal = LLVector3(1,0,0); + norm[mNumS*i].set(1,0,0); } } @@ -6101,7 +6099,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { //all upper S have same normal for (S32 i = 0; i < mNumT; i++) { - mVertices[mNumS*i+mNumS-1].mNormal = LLVector3(-1,0,0); + norm[mNumS*i+mNumS-1].set(-1,0,0); } } } @@ -6129,30 +6127,33 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { // average normals for north pole - LLVector3 average(0.0, 0.0, 0.0); + LLVector4a average; + average.clear(); + for (S32 i = 0; i < mNumS; i++) { - average += mVertices[i].mNormal; + average.add(norm[i]); } // set average for (S32 i = 0; i < mNumS; i++) { - mVertices[i].mNormal = average; + norm[i] = average; } // average normals for south pole - average = LLVector3(0.0, 0.0, 0.0); + average.clear(); + for (S32 i = 0; i < mNumS; i++) { - average += mVertices[i + mNumS * (mNumT - 1)].mNormal; + average.add(norm[i + mNumS * (mNumT - 1)]); } // set average for (S32 i = 0; i < mNumS; i++) { - mVertices[i + mNumS * (mNumT - 1)].mNormal = average; + norm[i + mNumS * (mNumT - 1)] = average; } } @@ -6162,23 +6163,22 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { for (S32 i = 0; i < mNumT; i++) { - LLVector3 norm = mVertices[mNumS*i].mNormal + mVertices[mNumS*i+mNumS-1].mNormal; - mVertices[mNumS * i].mNormal = norm; - mVertices[mNumS * i+mNumS-1].mNormal = norm; + LLVector4a n; + n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); + norm[mNumS * i] = n; + norm[mNumS * i+mNumS-1] = n; } } - - if (wrap_t) { for (S32 i = 0; i < mNumS; i++) { - LLVector3 norm = mVertices[i].mNormal + mVertices[mNumS*(mNumT-1)+i].mNormal; - mVertices[i].mNormal = norm; - mVertices[mNumS*(mNumT-1)+i].mNormal = norm; + LLVector4a n; + n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); + norm[i] = n; + norm[mNumS*(mNumT-1)+i] = n; } - } } @@ -6188,7 +6188,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) // Finds binormal based on three vertices with texture coordinates. // Fills in dummy values if the triangle has degenerate texture coordinates. -LLVector3 calc_binormal_from_triangle( +void calc_binormal_from_triangle(LLVector4a& binormal, + const LLVector3& pos0, const LLVector2& tex0, const LLVector3& pos1, @@ -6196,33 +6197,42 @@ LLVector3 calc_binormal_from_triangle( const LLVector3& pos2, const LLVector2& tex2) { - LLVector3 rx0( pos0.mV[VX], tex0.mV[VX], tex0.mV[VY] ); - LLVector3 rx1( pos1.mV[VX], tex1.mV[VX], tex1.mV[VY] ); - LLVector3 rx2( pos2.mV[VX], tex2.mV[VX], tex2.mV[VY] ); + LLVector4a rx0; rx0.set( pos0.mV[VX], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a rx1; rx1.set( pos1.mV[VX], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a rx2; rx2.set( pos2.mV[VX], tex2.mV[VX], tex2.mV[VY] ); - LLVector3 ry0( pos0.mV[VY], tex0.mV[VX], tex0.mV[VY] ); - LLVector3 ry1( pos1.mV[VY], tex1.mV[VX], tex1.mV[VY] ); - LLVector3 ry2( pos2.mV[VY], tex2.mV[VX], tex2.mV[VY] ); + LLVector4a ry0; ry0.set( pos0.mV[VY], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a ry1; ry1.set( pos1.mV[VY], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a ry2; ry2.set( pos2.mV[VY], tex2.mV[VX], tex2.mV[VY] ); - LLVector3 rz0( pos0.mV[VZ], tex0.mV[VX], tex0.mV[VY] ); - LLVector3 rz1( pos1.mV[VZ], tex1.mV[VX], tex1.mV[VY] ); - LLVector3 rz2( pos2.mV[VZ], tex2.mV[VX], tex2.mV[VY] ); + LLVector4a rz0; rz0.set( pos0.mV[VZ], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a rz1; rz1.set( pos1.mV[VZ], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a rz2; rz2.set( pos2.mV[VZ], tex2.mV[VX], tex2.mV[VY] ); - LLVector3 r0 = (rx0 - rx1) % (rx0 - rx2); - LLVector3 r1 = (ry0 - ry1) % (ry0 - ry2); - LLVector3 r2 = (rz0 - rz1) % (rz0 - rz2); + LLVector4a lhs, rhs; + + LLVector4a r0; + lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2); + r0.setCross3(lhs, rhs); + + LLVector4a r1; + lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2); + r1.setCross3(lhs, rhs); + + LLVector4a r2; + lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2); + r2.setCross3(lhs, rhs); - if( r0.mV[VX] && r1.mV[VX] && r2.mV[VX] ) + if( r0[VX] && r1[VX] && r2[VX] ) { - LLVector3 binormal( - -r0.mV[VZ] / r0.mV[VX], - -r1.mV[VZ] / r1.mV[VX], - -r2.mV[VZ] / r2.mV[VX]); + binormal.set( + -r0[VZ] / r0[VX], + -r1[VZ] / r1[VX], + -r2[VZ] / r2[VX]); // binormal.normVec(); - return binormal; } else { - return LLVector3( 0, 1 , 0 ); + binormal.set( 0, 1 , 0 ); } } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 17be642d4a..911db6f94b 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -40,6 +40,7 @@ class LLPathParams; class LLVolumeParams; class LLProfile; class LLPath; +class LLVector4a; class LLVolumeFace; class LLVolume; @@ -791,6 +792,19 @@ public: class LLVolumeFace { public: + class VertexData + { + public: + LLVector3 mPosition; + LLVector3 mNormal; + LLVector3 mBinormal; + LLVector2 mTexCoord; + + bool operator<(const VertexData& rhs) const; + bool operator==(const VertexData& rhs) const; + bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; + }; + LLVolumeFace() : mID(0), mTypeMask(0), @@ -808,26 +822,18 @@ public: { } + ~LLVolumeFace(); + 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& v, std::vector& idx); - class VertexData - { - public: - LLVector3 mPosition; - LLVector3 mNormal; - LLVector3 mBinormal; - LLVector2 mTexCoord; - - bool operator<(const VertexData& rhs) const; - bool operator==(const VertexData& rhs) const; - bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; - }; class VertexMapData : public LLVolumeFace::VertexData { @@ -1051,7 +1057,8 @@ public: std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); -LLVector3 calc_binormal_from_triangle( +void calc_binormal_from_triangle( + LLVector4a& binormal, const LLVector3& pos0, const LLVector2& tex0, const LLVector3& pos1, @@ -1060,7 +1067,7 @@ LLVector3 calc_binormal_from_triangle( const LLVector2& tex2); 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, +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 two_sided); -- cgit v1.2.3 From d7cab99ba74b214c557d9b5e02a7800b6a25c109 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 22 May 2010 12:37:53 -0500 Subject: Fix for a couple dumb mistakes. --- indra/llmath/llvolume.cpp | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 01fe2be371..88969af4bd 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5206,7 +5206,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) if (!partial_build) { - resizeIndices(grid_size*6); + resizeIndices(grid_size*grid_size*6); U16* out = mIndices; @@ -5689,12 +5689,21 @@ void LLVolumeFace::resizeVertices(S32 num_verts) mBinormals = NULL; - mPositions = (F32*) _mm_malloc(num_verts*16, 16); - mNormals = (F32*) _mm_malloc(num_verts*16, 16); + if (num_verts) + { + mPositions = (F32*) _mm_malloc(num_verts*16, 16); + mNormals = (F32*) _mm_malloc(num_verts*16, 16); - //pad texture coordinate block end to allow for QWORD reads - S32 size = ((num_verts*8) + 0xF) & ~0xF; - mTexCoords = (F32*) _mm_malloc(size, 16); + //pad texture coordinate block end to allow for QWORD reads + S32 size = ((num_verts*8) + 0xF) & ~0xF; + mTexCoords = (F32*) _mm_malloc(size, 16); + } + else + { + mPositions = NULL; + mNormals = NULL; + mTexCoords = NULL; + } mNumVertices = num_verts; } @@ -5710,10 +5719,17 @@ void LLVolumeFace::resizeIndices(S32 num_indices) { _mm_free(mIndices); - //pad index block end to allow for QWORD reads - S32 size = ((num_indices*2) + 0xF) & ~0xF; - - mIndices = (U16*) _mm_malloc(size,16); + if (num_indices) + { + //pad index block end to allow for QWORD reads + S32 size = ((num_indices*2) + 0xF) & ~0xF; + + mIndices = (U16*) _mm_malloc(size,16); + } + else + { + mIndices = NULL; + } mNumIndices = num_indices; } @@ -5954,7 +5970,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector3& face_max = mExtents[1]; mCenter.clearVec(); - face_min = face_max = LLVector3((F32*) &(pos[i].mQ)); + face_min = face_max = LLVector3((F32*) &(pos[0].mQ)); for (U32 i = 1; i < mNumVertices; ++i) { -- cgit v1.2.3 From 8c32e3bf29337e330a313d0e4865ebd03ad9ca50 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 24 May 2010 14:03:10 -0500 Subject: Fix for bad indexes on cube faces. Extra validation on vertex buffers. --- indra/llmath/llvolume.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 88969af4bd..31544016db 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4173,7 +4173,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, for (S32 i = start_face; i <= end_face; i++) { - const LLVolumeFace &face = getVolumeFace((U32)i); + LLVolumeFace &face = mVolumeFaces[i]; LLVector3 box_center = (face.mExtents[0] + face.mExtents[1]) / 2.f; LLVector3 box_size = face.mExtents[1] - face.mExtents[0]; @@ -4235,6 +4235,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, if (bi_normal != NULL) { + if (!face.mBinormals) + { + face.createBinormals(); + } LLVector4* binormal = (LLVector4*) face.mBinormals; if (binormal) { @@ -5174,7 +5178,6 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) LLVector4a* binorm = (LLVector4a*) mBinormals; LLVector2* tc = (LLVector2*) mTexCoords; - S32 vtop = mNumVertices; for(int gx = 0;gx=0;i--) { - *out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]); + *out++ = ((gy*(grid_size+1))+gx+idxs[i]); } } else { for(S32 i=0;i<6;i++) { - *out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]); + *out++ = ((gy*(grid_size+1))+gx+idxs[i]); } } } -- cgit v1.2.3 From a2eb86b00927439afcf27219e38e58eba421294f Mon Sep 17 00:00:00 2001 From: "Matthew Breindel (Falcon)" Date: Mon, 24 May 2010 13:37:59 -0700 Subject: Ack. Fixed a bunch of stupid type mistakes in llvector4a. --- indra/llmath/CMakeLists.txt | 2 ++ indra/llmath/llvolume.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index e93fe90650..367486eee7 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -62,6 +62,8 @@ set(llmath_HEADER_FILES llv4matrix3.h llv4matrix4.h llv4vector3.h + llvector4a.h + llmatrix4a.h llvolume.h llvolumemgr.h llsdutil_math.h diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 88969af4bd..d7d36d901d 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4126,14 +4126,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, norm_mat.rotate(n[v1], t); - t.normalize3Fast(); + t.normalize3fast(); normals.push_back(LLVector3(t[0], t[1], t[2])); mat.affineTransform(v[v2], t); vertices.push_back(LLVector3(t[0], t[1], t[2])); norm_mat.rotate(n[v2], t); - t.normalize3Fast(); + t.normalize3fast(); normals.push_back(LLVector3(t[0], t[1], t[2])); segments.push_back(vertices.size()); @@ -5349,7 +5349,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) mCenter, cuv, mesh[0+offset].mPos, tc[0], mesh[1+offset].mPos, tc[1]); - binormal.normalize3Fast(); + binormal.normalize3fast(); LLVector4a normal; LLVector4a d0, d1; @@ -5369,7 +5369,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) normal.setCross3(d1, d0); } - normal.normalize3Fast(); + normal.normalize3fast(); VertexData vd; vd.mPosition = mCenter; @@ -5675,7 +5675,7 @@ void LLVolumeFace::createBinormals() //normalize binormals for (U32 i = 0; i < mNumVertices; i++) { - binorm[i].normalize3Fast(); + binorm[i].normalize3fast(); } } } @@ -5803,7 +5803,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat { mat.affineTransform(src_pos[i], dst_pos[i]); norm_mat.rotate(src_norm[i], dst_norm[i]); - dst_norm[i].normalize3Fast(); + dst_norm[i].normalize3fast(); dst_tc[i] = src_tc[i]; -- cgit v1.2.3 From c0b654dd4bee466a2ccbf050e532fb4a05acc549 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 24 May 2010 17:33:41 -0500 Subject: Fix for bad feeding of vectorized raycast. --- indra/llmath/llvolume.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 2ff1463b7c..f05e6eb9d9 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4187,6 +4187,9 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector4a starta, dira; + starta.load3(start.mV); + dira.load3(dir.mV); + LLVector4a* p = (LLVector4a*) face.mPositions; for (U32 tri = 0; tri < face.mNumIndices/3; tri++) @@ -4235,17 +4238,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, if (bi_normal != NULL) { - if (!face.mBinormals) - { - face.createBinormals(); - } LLVector4* binormal = (LLVector4*) face.mBinormals; - if (binormal) - { - *bi_normal = ((1.f - a - b) * LLVector3(binormal[index1]) + + *bi_normal = ((1.f - a - b) * LLVector3(binormal[index1]) + a * LLVector3(binormal[index2]) + b * LLVector3(binormal[index3])); - } } } -- cgit v1.2.3 From e6fe3b1f1aa888e4594c89154ef895b3cf5498e9 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 25 May 2010 03:55:01 -0500 Subject: Better vectorization of various things. Turn off debug gl by default. --- indra/llmath/llvolume.cpp | 383 ++++++++++++++++++++++++++++++---------------- indra/llmath/llvolume.h | 110 ++++++++++--- 2 files changed, 333 insertions(+), 160 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index f05e6eb9d9..d8fbc081fa 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -237,6 +237,21 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co return TRUE; } +//helper for non-aligned vectors +BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, + F32* intersection_a, F32* intersection_b, F32* intersection_t, BOOL two_sided) +{ + LLVector4a vert0a, vert1a, vert2a, origa, dira; + vert0a.load3(vert0.mV); + vert1a.load3(vert1.mV); + vert2a.load3(vert2.mV); + origa.load3(orig.mV); + dira.load3(dir.mV); + + return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira, + intersection_a, intersection_b, intersection_t, two_sided); +} + //------------------------------------------------------------------- // statics @@ -1889,15 +1904,15 @@ bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)co bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const { bool retval = false; - if (rhs.mPosition == mPosition && rhs.mTexCoord == mTexCoord) + if (rhs.mData[POSITION].equal3(mData[POSITION]) && rhs.mTexCoord == mTexCoord) { if (angle_cutoff > 1.f) { - retval = (mNormal == rhs.mNormal); + retval = (mData[NORMAL].equal3(rhs.mData[NORMAL])); } else { - F32 cur_angle = rhs.mNormal*mNormal; + F32 cur_angle = rhs.mData[NORMAL].dot3(mData[NORMAL]); retval = cur_angle > angle_cutoff; } } @@ -2081,9 +2096,9 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min = max = LLVector3(0,0,0); - F32* pos_out = face.mPositions; - F32* norm_out = face.mNormals; - F32* tc_out = face.mTexCoords; + F32* pos_out = (F32*) face.mPositions; + F32* norm_out = (F32*) face.mNormals; + F32* tc_out = (F32*) face.mTexCoords; for (U32 j = 0; j < num_verts; ++j) { @@ -2188,13 +2203,15 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) void tetrahedron_set_normal(LLVolumeFace::VertexData* cv) { - LLVector3 nrm = (cv[1].mPosition-cv[0].mPosition)%(cv[2].mPosition-cv[0].mPosition); - - nrm.normVec(); - - cv[0].mNormal = nrm; - cv[1].mNormal = nrm; - cv[2].mNormal = nrm; + LLVector4a v0; + v0.setSub(cv[1].getPosition(), cv[0].getNormal()); + LLVector4a v1; + v1.setSub(cv[2].getNormal(), cv[0].getPosition()); + + cv[0].getNormal().setCross3(v0,v1); + cv[0].getNormal().normalize3fast(); + cv[1].setNormal(cv[0].getNormal()); + cv[2].setNormal(cv[1].getNormal()); } BOOL LLVolume::isTetrahedron() @@ -2209,12 +2226,12 @@ void LLVolume::makeTetrahedron() LLVolumeFace face; F32 x = 0.25f; - LLVector3 p[] = + LLVector4a p[] = { //unit tetrahedron corners - LLVector3(x,x,x), - LLVector3(-x,-x,x), - LLVector3(-x,x,-x), - LLVector3(x,-x,-x) + LLVector4a(x,x,x), + LLVector4a(-x,-x,x), + LLVector4a(-x,x,-x), + LLVector4a(x,-x,-x) }; face.mExtents[0].setVec(-x,-x,-x); @@ -2229,9 +2246,9 @@ void LLVolume::makeTetrahedron() //side 1 - cv[0].mPosition = p[1]; - cv[1].mPosition = p[0]; - cv[2].mPosition = p[2]; + cv[0].setPosition(p[1]); + cv[1].setPosition(p[0]); + cv[2].setPosition(p[2]); tetrahedron_set_normal(cv); @@ -2242,14 +2259,14 @@ void LLVolume::makeTetrahedron() LLVector4a* n = (LLVector4a*) face.mNormals; LLVector2* tc = (LLVector2*) face.mTexCoords; - v[0].load3(cv[0].mPosition.mV); - v[1].load3(cv[1].mPosition.mV); - v[2].load3(cv[2].mPosition.mV); + v[0] = cv[0].getPosition(); + v[1] = cv[1].getPosition(); + v[2] = cv[2].getPosition(); v += 3; - n[0].load3(cv[0].mNormal.mV); - n[1].load3(cv[1].mNormal.mV); - n[2].load3(cv[2].mNormal.mV); + n[0] = cv[0].getNormal(); + n[1] = cv[1].getNormal(); + n[2] = cv[2].getNormal(); n += 3; tc[0] = cv[0].mTexCoord; @@ -2259,20 +2276,20 @@ void LLVolume::makeTetrahedron() //side 2 - cv[0].mPosition = p[3]; - cv[1].mPosition = p[0]; - cv[2].mPosition = p[1]; + cv[0].setPosition(p[3]); + cv[1].setPosition(p[0]); + cv[2].setPosition(p[1]); tetrahedron_set_normal(cv); - v[0].load3(cv[0].mPosition.mV); - v[1].load3(cv[1].mPosition.mV); - v[2].load3(cv[2].mPosition.mV); + v[0] = cv[0].getPosition(); + v[1] = cv[1].getPosition(); + v[2] = cv[2].getPosition(); v += 3; - n[0].load3(cv[0].mNormal.mV); - n[1].load3(cv[1].mNormal.mV); - n[2].load3(cv[2].mNormal.mV); + n[0] = cv[0].getNormal(); + n[1] = cv[1].getNormal(); + n[2] = cv[2].getNormal(); n += 3; tc[0] = cv[0].mTexCoord; @@ -2281,20 +2298,20 @@ void LLVolume::makeTetrahedron() tc += 3; //side 3 - cv[0].mPosition = p[3]; - cv[1].mPosition = p[1]; - cv[2].mPosition = p[2]; + cv[0].setPosition(p[3]); + cv[1].setPosition(p[1]); + cv[2].setPosition(p[2]); tetrahedron_set_normal(cv); - v[0].load3(cv[0].mPosition.mV); - v[1].load3(cv[1].mPosition.mV); - v[2].load3(cv[2].mPosition.mV); + v[0] = cv[0].getPosition(); + v[1] = cv[1].getPosition(); + v[2] = cv[2].getPosition(); v += 3; - n[0].load3(cv[0].mNormal.mV); - n[1].load3(cv[1].mNormal.mV); - n[2].load3(cv[2].mNormal.mV); + n[0] = cv[0].getNormal(); + n[1] = cv[1].getNormal(); + n[2] = cv[2].getNormal(); n += 3; tc[0] = cv[0].mTexCoord; @@ -2303,20 +2320,20 @@ void LLVolume::makeTetrahedron() tc += 3; //side 4 - cv[0].mPosition = p[2]; - cv[1].mPosition = p[0]; - cv[2].mPosition = p[3]; + cv[0].setPosition(p[2]); + cv[1].setPosition(p[0]); + cv[2].setPosition(p[3]); tetrahedron_set_normal(cv); - v[0].load3(cv[0].mPosition.mV); - v[1].load3(cv[1].mPosition.mV); - v[2].load3(cv[2].mPosition.mV); + v[0] = cv[0].getPosition(); + v[1] = cv[1].getPosition(); + v[2] = cv[2].getPosition(); v += 3; - n[0].load3(cv[0].mNormal.mV); - n[1].load3(cv[1].mNormal.mV); - n[2].load3(cv[2].mNormal.mV); + n[0] = cv[0].getNormal(); + n[1] = cv[1].getNormal(); + n[2] = cv[2].getNormal(); n += 3; tc[0] = cv[0].mTexCoord; @@ -3974,9 +3991,9 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, S32 v3 = face.mIndices[j*3+2]; //get current face center - LLVector3 cCenter = (face.mVertices[v1].mPosition + - face.mVertices[v2].mPosition + - face.mVertices[v3].mPosition) / 3.0f; + LLVector3 cCenter = (face.mVertices[v1].getPosition() + + face.mVertices[v2].getPosition() + + face.mVertices[v3].getPosition()) / 3.0f; //for each edge for (S32 k = 0; k < 3; k++) { @@ -3994,9 +4011,9 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, v3 = face.mIndices[nIndex*3+2]; //get neighbor face center - LLVector3 nCenter = (face.mVertices[v1].mPosition + - face.mVertices[v2].mPosition + - face.mVertices[v3].mPosition) / 3.0f; + LLVector3 nCenter = (face.mVertices[v1].getPosition() + + face.mVertices[v2].getPosition() + + face.mVertices[v3].getPosition()) / 3.0f; //draw line vertices.push_back(cCenter); @@ -4020,14 +4037,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, //for each vertex for (U32 j = 0; j < face.mNumVertices; j++) { - vertices.push_back(face.mVertices[j].mPosition); - vertices.push_back(face.mVertices[j].mPosition + face.mVertices[j].mNormal*0.1f); + vertices.push_back(face.mVertices[j].getPosition()); + vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].getNormal()*0.1f); normals.push_back(LLVector3(0,0,1)); normals.push_back(LLVector3(0,0,1)); segments.push_back(vertices.size()); #if DEBUG_SILHOUETTE_BINORMALS - vertices.push_back(face.mVertices[j].mPosition); - vertices.push_back(face.mVertices[j].mPosition + face.mVertices[j].mBinormal*0.1f); + vertices.push_back(face.mVertices[j].getPosition()); + vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mBinormal*0.1f); normals.push_back(LLVector3(0,0,1)); normals.push_back(LLVector3(0,0,1)); segments.push_back(vertices.size()); @@ -5038,9 +5055,15 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) } } +void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv) +{ + cv.setPosition(mPositions[index]); + cv.setNormal(mNormals[index]); + cv.mTexCoord = mTexCoords[index]; +} + void LLVolumeFace::optimize(F32 angle_cutoff) { -#if 0 //disabling until a vectorized version is available LLVolumeFace new_face; VertexMapData::PointMap point_map; @@ -5050,10 +5073,11 @@ void LLVolumeFace::optimize(F32 angle_cutoff) { U16 index = mIndices[i]; - LLVolumeFace::VertexData cv = mVertices[index]; - + LLVolumeFace::VertexData cv; + getVertexData(index, cv); + BOOL found = FALSE; - VertexMapData::PointMap::iterator point_iter = point_map.find(cv.mPosition); + VertexMapData::PointMap::iterator point_iter = point_map.find(cv.getPosition()); if (point_iter != point_map.end()) { //duplicate point might exist for (U32 j = 0; j < point_iter->second.size(); ++j) @@ -5062,7 +5086,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) if (tv.compareNormal(cv, angle_cutoff)) { found = TRUE; - new_face.mIndices.push_back((point_iter->second)[j].mIndex); + new_face.pushIndex((point_iter->second)[j].mIndex); break; } } @@ -5070,14 +5094,14 @@ void LLVolumeFace::optimize(F32 angle_cutoff) if (!found) { - new_face.mVertices.push_back(cv); + new_face.pushVertex(cv); U16 index = (U16) new_face.mNumVertices-1; - new_face.mIndices.push_back(index); + new_face.pushIndex(index); VertexMapData d; - d.mPosition = cv.mPosition; + d.setPosition(cv.getPosition()); d.mTexCoord = cv.mTexCoord; - d.mNormal = cv.mNormal; + d.setNormal(cv.getNormal()); d.mIndex = index; if (point_iter != point_map.end()) { @@ -5085,14 +5109,23 @@ void LLVolumeFace::optimize(F32 angle_cutoff) } else { - point_map[d.mPosition].push_back(d); + point_map[d.getPosition()].push_back(d); } } } - mVertices = new_face.mVertices; - mIndices = new_face.mIndices; -#endif + swapData(new_face); +} + +void LLVolumeFace::swapData(LLVolumeFace& rhs) +{ + llswap(rhs.mPositions, mPositions); + llswap(rhs.mNormals, mNormals); + llswap(rhs.mBinormals, mBinormals); + llswap(rhs.mTexCoords, mTexCoords); + llswap(rhs.mIndices,mIndices); + llswap(rhs.mNumVertices, mNumVertices); + llswap(rhs.mNumIndices, mNumIndices); } void LerpPlanarVertex(LLVolumeFace::VertexData& v0, @@ -5102,10 +5135,21 @@ void LerpPlanarVertex(LLVolumeFace::VertexData& v0, F32 coef01, F32 coef02) { - vout.mPosition = v0.mPosition + ((v1.mPosition-v0.mPosition)*coef01)+((v2.mPosition-v0.mPosition)*coef02); + + LLVector4a lhs; + lhs.setSub(v1.getPosition(), v0.getPosition()); + lhs.mul(coef01); + LLVector4a rhs; + rhs.setSub(v2.getPosition(), v0.getPosition()); + rhs.mul(coef02); + + rhs.add(lhs); + rhs.add(v0.getPosition()); + + vout.setPosition(rhs); + vout.mTexCoord = v0.mTexCoord + ((v1.mTexCoord-v0.mTexCoord)*coef01)+((v2.mTexCoord-v0.mTexCoord)*coef02); - vout.mNormal = v0.mNormal; - vout.mBinormal = v0.mBinormal; + vout.setNormal(v0.getNormal()); } BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) @@ -5137,16 +5181,22 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) VertexData corners[4]; VertexData baseVert; for(int t = 0; t < 4; t++){ - corners[t].mPosition = mesh[offset + (grid_size*t)].mPos; + corners[t].getPosition().load3( mesh[offset + (grid_size*t)].mPos.mV); corners[t].mTexCoord.mV[0] = profile[grid_size*t].mV[0]+0.5f; corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t].mV[1]; } - baseVert.mNormal = - ((corners[1].mPosition-corners[0].mPosition) % - (corners[2].mPosition-corners[1].mPosition)); - baseVert.mNormal.normVec(); + + { + LLVector4a lhs; + lhs.setSub(corners[1].getPosition(), corners[0].getPosition()); + LLVector4a rhs; + rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); + baseVert.getNormal().setCross3(lhs, rhs); + baseVert.getNormal().normalize3fast(); + } + if(!(mTypeMask & TOP_MASK)){ - baseVert.mNormal *= -1.0f; + baseVert.getNormal().mul(-1.0f); }else{ //Swap the UVs on the U(X) axis for top face LLVector2 swap; @@ -5161,9 +5211,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) LLVector4a binormal; calc_binormal_from_triangle( binormal, - corners[0].mPosition, corners[0].mTexCoord, - corners[1].mPosition, corners[1].mTexCoord, - corners[2].mPosition, corners[2].mTexCoord); + corners[0].getPosition(), corners[0].mTexCoord, + corners[1].getPosition(), corners[1].mTexCoord, + corners[2].getPosition(), corners[2].mTexCoord); S32 size = (grid_size+1)*(grid_size+1); resizeVertices(size); @@ -5185,18 +5235,18 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) (F32)gx/(F32)grid_size, (F32)gy/(F32)grid_size); - (*pos++).load3(newVert.mPosition.mV); - (*norm++).load3(baseVert.mNormal.mV); - (*tc++) = newVert.mTexCoord; - (*binorm++).load4a((F32*) &binormal.mQ); + *pos++ = newVert.getPosition(); + *norm++ = baseVert.getNormal(); + *tc++ = newVert.mTexCoord; + *binorm++ = binormal; if (gx == 0 && gy == 0) { - min = max = newVert.mPosition; + min = max = LLVector3(newVert.getPosition().getF32()); } else { - update_min_max(min,max,newVert.mPosition); + update_min_max(min,max,newVert.getPosition().getF32()); } } } @@ -5343,18 +5393,19 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) mCenter = (min+max)*0.5f; cuv = (min_uv + max_uv)*0.5f; + LLVector4a center; + center.load3(mCenter.mV); + LLVector4a binormal; calc_binormal_from_triangle(binormal, - mCenter, cuv, - mesh[0+offset].mPos, tc[0], - mesh[1+offset].mPos, tc[1]); + center, cuv, + pos[0], tc[0], + pos[1], tc[1]); binormal.normalize3fast(); LLVector4a normal; LLVector4a d0, d1; - LLVector4a center; - - center.load3(mCenter.mV); + d0.setSub(center, pos[0]); d1.setSub(center, pos[1]); @@ -5371,7 +5422,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) normal.normalize3fast(); VertexData vd; - vd.mPosition = mCenter; + vd.getPosition().load3(mCenter.mV); vd.mTexCoord = cuv; if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) @@ -5634,10 +5685,7 @@ void LLVolumeFace::createBinormals() allocateBinormals(mNumVertices); //generate binormals - LLStrider pos; - pos = (LLVector3*) mPositions; - pos.setStride(16); - + LLVector4a* pos = mPositions; LLVector2* tc = (LLVector2*) mTexCoords; LLVector4a* binorm = (LLVector4a*) mBinormals; @@ -5690,12 +5738,12 @@ void LLVolumeFace::resizeVertices(S32 num_verts) if (num_verts) { - mPositions = (F32*) _mm_malloc(num_verts*16, 16); - mNormals = (F32*) _mm_malloc(num_verts*16, 16); + mPositions = (LLVector4a*) _mm_malloc(num_verts*16, 16); + mNormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); //pad texture coordinate block end to allow for QWORD reads S32 size = ((num_verts*8) + 0xF) & ~0xF; - mTexCoords = (F32*) _mm_malloc(size, 16); + mTexCoords = (LLVector2*) _mm_malloc(size, 16); } else { @@ -5707,10 +5755,61 @@ void LLVolumeFace::resizeVertices(S32 num_verts) mNumVertices = num_verts; } +void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv) +{ + pushVertex(cv.getPosition(), cv.getNormal(), cv.mTexCoord); +} + +void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc) +{ + S32 new_verts = mNumVertices+1; + S32 new_size = new_verts*16; + + //positions + LLVector4a* dst = (LLVector4a*) _mm_malloc(new_size, 16); + if (mPositions) + { + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mPositions, new_size/4); + _mm_free(mPositions); + } + mPositions = dst; + + //normals + dst = (LLVector4a*) _mm_malloc(new_size, 16); + if (mNormals) + { + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mNormals, new_size/4); + _mm_free(mNormals); + } + mNormals = dst; + + //tex coords + new_size = ((new_verts*8)+0xF) & ~0xF; + + { + LLVector2* dst = (LLVector2*) _mm_malloc(new_size, 16); + if (mTexCoords) + { + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mTexCoords, new_size/4); + _mm_free(mTexCoords); + } + } + + //just clear binormals + _mm_free(mBinormals); + mBinormals = NULL; + + mPositions[mNumVertices] = pos; + mNormals[mNumVertices] = norm; + mTexCoords[mNumVertices] = tc; + + mNumVertices++; +} + void LLVolumeFace::allocateBinormals(S32 num_verts) { _mm_free(mBinormals); - mBinormals = (F32*) _mm_malloc(num_verts*16, 16); + mBinormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); } @@ -5733,6 +5832,23 @@ void LLVolumeFace::resizeIndices(S32 num_indices) mNumIndices = num_indices; } +void LLVolumeFace::pushIndex(const U16& idx) +{ + S32 new_count = mNumIndices + 1; + S32 new_size = ((new_count*2)+0xF) & ~0xF; + + S32 old_size = (mNumIndices+0xF) & ~0xF; + if (new_size != old_size) + { + U16* dst = (U16*) _mm_malloc(new_size, 16); + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mIndices, new_size/4); + _mm_free(mIndices); + mIndices = dst; + } + + mIndices[mNumIndices++] = idx; +} + void LLVolumeFace::fillFromLegacyData(std::vector& v, std::vector& idx) { resizeVertices(v.size()); @@ -5740,14 +5856,9 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v, for (U32 i = 0; i < v.size(); ++i) { - for (U32 j = 0; j < 3; ++j) - { - mPositions[i*4+j] = v[i].mPosition[j]; - mNormals[i*4+j] = v[i].mNormal[j]; - } - - mTexCoords[i*2+0] = v[i].mTexCoord.mV[0]; - mTexCoords[i*2+1] = v[i].mTexCoord.mV[1]; + mPositions[i] = v[i].getPosition(); + mNormals[i] = v[i].getNormal(); + mTexCoords[i] = v[i].mTexCoord; } for (U32 i = 0; i < idx.size(); ++i) @@ -5768,13 +5879,13 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } - F32* new_pos = (F32*) _mm_malloc(new_count*16, 16); - F32* new_norm = (F32*) _mm_malloc(new_count*16, 16); - F32* new_tc = (F32*) _mm_malloc((new_count*8+0xF) & ~0xF, 16); + LLVector4a* new_pos = (LLVector4a*) _mm_malloc(new_count*16, 16); + LLVector4a* new_norm = (LLVector4a*) _mm_malloc(new_count*16, 16); + LLVector2* new_tc = (LLVector2*) _mm_malloc((new_count*8+0xF) & ~0xF, 16); - LLVector4a::memcpyNonAliased16(new_pos, mPositions, new_count*4); - LLVector4a::memcpyNonAliased16(new_norm, mNormals, new_count*4); - LLVector4a::memcpyNonAliased16(new_tc, mTexCoords, new_count*2); + LLVector4a::memcpyNonAliased16((F32*) new_pos, (F32*) mPositions, new_count*4); + LLVector4a::memcpyNonAliased16((F32*) new_norm, (F32*) mNormals, new_count*4); + LLVector4a::memcpyNonAliased16((F32*) new_tc, (F32*) mTexCoords, new_count*2); _mm_free(mPositions); _mm_free(mNormals); @@ -6205,24 +6316,24 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) // Fills in dummy values if the triangle has degenerate texture coordinates. void calc_binormal_from_triangle(LLVector4a& binormal, - const LLVector3& pos0, + const LLVector4a& pos0, const LLVector2& tex0, - const LLVector3& pos1, + const LLVector4a& pos1, const LLVector2& tex1, - const LLVector3& pos2, + const LLVector4a& pos2, const LLVector2& tex2) { - LLVector4a rx0; rx0.set( pos0.mV[VX], tex0.mV[VX], tex0.mV[VY] ); - LLVector4a rx1; rx1.set( pos1.mV[VX], tex1.mV[VX], tex1.mV[VY] ); - LLVector4a rx2; rx2.set( pos2.mV[VX], tex2.mV[VX], tex2.mV[VY] ); + LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] ); - LLVector4a ry0; ry0.set( pos0.mV[VY], tex0.mV[VX], tex0.mV[VY] ); - LLVector4a ry1; ry1.set( pos1.mV[VY], tex1.mV[VX], tex1.mV[VY] ); - LLVector4a ry2; ry2.set( pos2.mV[VY], tex2.mV[VX], tex2.mV[VY] ); + LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] ); - LLVector4a rz0; rz0.set( pos0.mV[VZ], tex0.mV[VX], tex0.mV[VY] ); - LLVector4a rz1; rz1.set( pos1.mV[VZ], tex1.mV[VX], tex1.mV[VY] ); - LLVector4a rz2; rz2.set( pos2.mV[VZ], tex2.mV[VX], tex2.mV[VY] ); + LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] ); LLVector4a lhs, rhs; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 911db6f94b..aa58d6d114 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -40,7 +40,6 @@ class LLPathParams; class LLVolumeParams; class LLProfile; class LLPath; -class LLVector4a; class LLVolumeFace; class LLVolume; @@ -56,6 +55,7 @@ class LLVolume; #include "v4coloru.h" #include "llrefcount.h" #include "llfile.h" +#include "llvector4a.h" //============================================================================ @@ -794,15 +794,74 @@ class LLVolumeFace public: class VertexData { + enum + { + POSITION = 0, + NORMAL = 1 + }; + + private: + void init() + { + mData = (LLVector4a*) _mm_malloc(32, 16); + } public: - LLVector3 mPosition; - LLVector3 mNormal; - LLVector3 mBinormal; + VertexData() + { + init(); + } + + VertexData(const VertexData& rhs) + { + init(); + LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); + mTexCoord = rhs.mTexCoord; + } + + ~VertexData() + { + _mm_free(mData); + } + + LLVector4a& getPosition() + { + return mData[POSITION]; + } + + LLVector4a& getNormal() + { + return mData[NORMAL]; + } + + const LLVector4a& getPosition() const + { + return mData[POSITION]; + } + + const LLVector4a& getNormal() const + { + return mData[NORMAL]; + } + + + void setPosition(const LLVector4a& pos) + { + mData[POSITION] = pos; + } + + void setNormal(const LLVector4a& norm) + { + mData[NORMAL] = 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() : @@ -834,6 +893,13 @@ public: void resizeIndices(S32 num_indices); void fillFromLegacyData(std::vector& v, std::vector& 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 { @@ -842,28 +908,20 @@ public: bool operator==(const LLVolumeFace::VertexData& rhs) const { - return mPosition == rhs.mPosition && + return getPosition().equal3(rhs.getPosition()) && mTexCoord == rhs.mTexCoord && - mNormal == rhs.mNormal; + getNormal().equal3(rhs.getNormal()); } struct ComparePosition { - bool operator()(const LLVector3& a, const LLVector3& b) const + bool operator()(const LLVector4a& a, const LLVector4a& b) const { - if (a.mV[0] != b.mV[0]) - { - return a.mV[0] < b.mV[0]; - } - if (a.mV[1] != b.mV[1]) - { - return a.mV[1] < b.mV[1]; - } - return a.mV[2] < b.mV[2]; + return a.less3(b); } }; - typedef std::map, VertexMapData::ComparePosition > PointMap; + typedef std::map, VertexMapData::ComparePosition > PointMap; }; void optimize(F32 angle_cutoff = 2.f); @@ -899,10 +957,10 @@ public: S32 mNumVertices; S32 mNumIndices; - F32* mPositions; - F32* mNormals; - F32* mBinormals; - F32* mTexCoords; + LLVector4a* mPositions; + LLVector4a* mNormals; + LLVector4a* mBinormals; + LLVector2* mTexCoords; U16* mIndices; std::vector mEdge; @@ -1059,14 +1117,18 @@ std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); void calc_binormal_from_triangle( LLVector4a& binormal, - const LLVector3& pos0, + 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 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 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 two_sided); -- cgit v1.2.3 From c98b1b3fd9341834978aff0e841714e206d28c0a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 26 May 2010 03:29:19 -0500 Subject: Fully aligned llvolume --- indra/llmath/llvolume.cpp | 353 +++++++++++++++++++++++++++++++++++----------- indra/llmath/llvolume.h | 99 ++++--------- indra/llmath/v3math.h | 1 - 3 files changed, 302 insertions(+), 151 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d8fbc081fa..9b6e2488e6 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -107,22 +107,27 @@ BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLV BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size) { - float fAWdU[3]; - LLVector3 dir; - LLVector3 diff; + return LLLineSegmentBoxIntersect(start.mV, end.mV, center.mV, size.mV); +} + +BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size) +{ + F32 fAWdU[3]; + F32 dir[3]; + F32 diff[3]; for (U32 i = 0; i < 3; i++) { - dir.mV[i] = 0.5f * (end.mV[i] - start.mV[i]); - diff.mV[i] = (0.5f * (end.mV[i] + start.mV[i])) - center.mV[i]; - fAWdU[i] = fabsf(dir.mV[i]); - if(fabsf(diff.mV[i])>size.mV[i] + fAWdU[i]) return false; + dir[i] = 0.5f * (end[i] - start[i]); + diff[i] = (0.5f * (end[i] + start[i])) - center[i]; + fAWdU[i] = fabsf(dir[i]); + if(fabsf(diff[i])>size[i] + fAWdU[i]) return false; } float f; - f = dir.mV[1] * diff.mV[2] - dir.mV[2] * diff.mV[1]; if(fabsf(f)>size.mV[1]*fAWdU[2] + size.mV[2]*fAWdU[1]) return false; - f = dir.mV[2] * diff.mV[0] - dir.mV[0] * diff.mV[2]; if(fabsf(f)>size.mV[0]*fAWdU[2] + size.mV[2]*fAWdU[0]) return false; - f = dir.mV[0] * diff.mV[1] - dir.mV[1] * diff.mV[0]; if(fabsf(f)>size.mV[0]*fAWdU[1] + size.mV[1]*fAWdU[0]) return false; + f = dir[1] * diff[2] - dir[2] * diff[1]; if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1]) return false; + f = dir[2] * diff[0] - dir[0] * diff[2]; if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0]) return false; + f = dir[0] * diff[1] - dir[1] * diff[0]; if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0]) return false; return true; } @@ -1869,6 +1874,59 @@ BOOL LLVolume::generate() return FALSE; } +void LLVolumeFace::VertexData::init() +{ + mData = (LLVector4a*) _mm_malloc(32, 16); +} + +LLVolumeFace::VertexData::VertexData() +{ + init(); +} + +LLVolumeFace::VertexData::VertexData(const VertexData& rhs) +{ + init(); + LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); + mTexCoord = rhs.mTexCoord; +} + +LLVolumeFace::VertexData::~VertexData() +{ + _mm_free(mData); +} + +LLVector4a& LLVolumeFace::VertexData::getPosition() +{ + return mData[POSITION]; +} + +LLVector4a& LLVolumeFace::VertexData::getNormal() +{ + return mData[NORMAL]; +} + +const LLVector4a& LLVolumeFace::VertexData::getPosition() const +{ + return mData[POSITION]; +} + +const LLVector4a& LLVolumeFace::VertexData::getNormal() const +{ + return mData[NORMAL]; +} + + +void LLVolumeFace::VertexData::setPosition(const LLVector4a& pos) +{ + mData[POSITION] = pos; +} + +void LLVolumeFace::VertexData::setNormal(const LLVector4a& norm) +{ + mData[NORMAL] = norm; +} + bool LLVolumeFace::VertexData::operator<(const LLVolumeFace::VertexData& rhs)const { const U8* l = (const U8*) this; @@ -2037,7 +2095,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) if (mdl[i].has("Weights")) { - face.mWeights.resize(num_verts); + face.allocateWeights(num_verts); LLSD::Binary weights = mdl[i]["Weights"]; @@ -2050,13 +2108,15 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) U8 joint = weights[idx++]; U32 cur_influence = 0; + LLVector4 wght(0,0,0,0); + while (joint != END_INFLUENCES) { U16 influence = weights[idx++]; influence |= ((U16) weights[idx++] << 8); F32 w = llmin((F32) influence / 65535.f, 0.99999f); - face.mWeights[cur_vertex].mV[cur_influence++] = (F32) joint + w; + wght.mV[cur_influence++] = (F32) joint + w; if (cur_influence >= 4) { @@ -2068,6 +2128,8 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } + face.mWeights[cur_vertex].loadua(wght.mV); + cur_vertex++; } @@ -2078,62 +2140,70 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } - LLVector3 min_pos; - LLVector3 max_pos; + LLVector3 minp; + LLVector3 maxp; LLVector2 min_tc; LLVector2 max_tc; - min_pos.setValue(mdl[i]["PositionDomain"]["Min"]); - max_pos.setValue(mdl[i]["PositionDomain"]["Max"]); + minp.setValue(mdl[i]["PositionDomain"]["Min"]); + maxp.setValue(mdl[i]["PositionDomain"]["Max"]); + LLVector4a min_pos, max_pos; + min_pos.load3(minp.mV); + max_pos.load3(maxp.mV); + min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); - LLVector3 pos_range = max_pos - min_pos; + LLVector4a pos_range; + pos_range.setSub(max_pos, min_pos); LLVector2 tc_range = max_tc - min_tc; - LLVector3& min = face.mExtents[0]; - LLVector3& max = face.mExtents[1]; - - min = max = LLVector3(0,0,0); + LLVector4a& min = face.mExtents[0]; + LLVector4a& max = face.mExtents[1]; - F32* pos_out = (F32*) face.mPositions; - F32* norm_out = (F32*) face.mNormals; - F32* tc_out = (F32*) face.mTexCoords; + min.clear(); + max.clear(); + + LLVector4a* pos_out = face.mPositions; + LLVector4a* norm_out = face.mNormals; + LLVector2* tc_out = face.mTexCoords; for (U32 j = 0; j < num_verts; ++j) { U16* v = (U16*) &(pos[j*3*2]); - pos_out[0] = (F32) v[0] / 65535.f * pos_range.mV[0] + min_pos.mV[0]; - pos_out[1] = (F32) v[1] / 65535.f * pos_range.mV[1] + min_pos.mV[1]; - pos_out[2] = (F32) v[2] / 65535.f * pos_range.mV[2] + min_pos.mV[2]; - + pos_out->set((F32) v[0], (F32) v[1], (F32) v[2]); + pos_out->div(65535.f); + pos_out->mul(pos_range); + pos_out->add(min_pos); if (j == 0) { - min = max = LLVector3(pos_out); + min = *pos_out; + max = min; } else { - update_min_max(min,max,pos_out); + min.setMin(*pos_out); + max.setMax(*pos_out); } - pos_out += 4; + pos_out++; U16* n = (U16*) &(norm[j*3*2]); - - norm_out[0] = (F32) n[0] / 65535.f * 2.f - 1.f; - norm_out[1] = (F32) n[1] / 65535.f * 2.f - 1.f; - norm_out[2] = (F32) n[2] / 65535.f * 2.f - 1.f; - norm_out += 4; + norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); + norm_out->div(65535.f); + norm_out->mul(2.f); + norm_out->sub(1.f); + norm_out++; U16* t = (U16*) &(tc[j*2*2]); - tc_out[0] = (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0]; - tc_out[1] = (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]; + tc_out->mV[0] = (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0]; + tc_out->mV[1] = (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]; - tc_out += 8; + tc_out++; } @@ -2234,8 +2304,8 @@ void LLVolume::makeTetrahedron() LLVector4a(x,-x,-x) }; - face.mExtents[0].setVec(-x,-x,-x); - face.mExtents[1].setVec(x,x,x); + face.mExtents[0].splat(-x); + face.mExtents[1].splat(x); LLVolumeFace::VertexData cv[3]; @@ -4165,6 +4235,18 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +{ + LLVector4a starta, enda; + starta.load3(start.mV); + enda.load3(end.mV); + + return lineSegmentIntersect(starta, enda, face, intersection, tex_coord, normal, bi_normal); + +} + +S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, + S32 face, + LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) { S32 hit_face = -1; @@ -4182,7 +4264,8 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, end_face = face; } - LLVector3 dir = end - start; + LLVector4a dir; + dir.setSub(end, start); F32 closest_t = 2.f; // must be larger than 1 @@ -4192,21 +4275,20 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, { LLVolumeFace &face = mVolumeFaces[i]; - LLVector3 box_center = (face.mExtents[0] + face.mExtents[1]) / 2.f; - LLVector3 box_size = face.mExtents[1] - face.mExtents[0]; + LLVector4a box_center; + box_center.setAdd(face.mExtents[0], face.mExtents[1]); + box_center.mul(0.5f); + + LLVector4a box_size; + box_size.setSub(face.mExtents[1], face.mExtents[0]); - if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) + if (LLLineSegmentBoxIntersect(start.getF32(), end.getF32(), box_center.getF32(), box_size.getF32())) { if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them { genBinormals(i); } - LLVector4a starta, dira; - - starta.load3(start.mV); - dira.load3(dir.mV); - LLVector4a* p = (LLVector4a*) face.mPositions; for (U32 tri = 0; tri < face.mNumIndices/3; tri++) @@ -4220,7 +4302,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, if (LLTriangleRayIntersect(p[index1], p[index2], p[index3], - starta, dira, &a, &b, &t, FALSE)) + start, dir, &a, &b, &t, FALSE)) { if ((t >= 0.f) && // if hit is after start (t <= 1.f) && // and before end @@ -4231,7 +4313,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, if (intersection != NULL) { - *intersection = start + dir * closest_t; + LLVector4a intersect = dir; + intersect.mul(closest_t); + intersect.add(start); + intersection->set(intersect.getF32()); } @@ -5029,6 +5114,107 @@ std::ostream& operator<<(std::ostream &s, const LLVolume *volumep) return s; } +LLVolumeFace::LLVolumeFace() : + mID(0), + mTypeMask(0), + mBeginS(0), + mBeginT(0), + mNumS(0), + mNumT(0), + mNumVertices(0), + mNumIndices(0), + mPositions(NULL), + mNormals(NULL), + mBinormals(NULL), + mTexCoords(NULL), + mIndices(NULL), + mWeights(NULL) +{ + mExtents = (LLVector4a*) _mm_malloc(48, 16); + mCenter = mExtents+2; +} + +LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) +{ + mExtents = (LLVector4a*) _mm_malloc(48, 16); + mCenter = mExtents+2; + *this = src; +} + +LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) +{ + if (&src == this) + { //self assignment, do nothing + return *this; + } + + mID = src.mID; + mTypeMask = src.mTypeMask; + mBeginS = src.mBeginS; + mBeginT = src.mBeginT; + mNumS = src.mNumS; + mNumT = src.mNumT; + + mNumVertices = 0; + mNumIndices = 0; + mPositions = NULL; + mNormals = NULL; + mBinormals = NULL; + mTexCoords = NULL; + mWeights = NULL; + mIndices = NULL; + + LLVector4a::memcpyNonAliased16((F32*) mExtents, (F32*) src.mExtents, 12); + + resizeVertices(src.mNumVertices); + resizeIndices(src.mNumIndices); + + if (mNumVertices) + { + S32 vert_size = mNumVertices*4; + S32 tc_size = (mNumVertices*8+0xF) & ~0xF; + tc_size /= 4; + + LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); + LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); + LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, vert_size); + + if (src.mBinormals) + { + allocateBinormals(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) src.mBinormals, vert_size); + } + else + { + _mm_free(mBinormals); + mBinormals = NULL; + } + + if (src.mWeights) + { + allocateWeights(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size); + } + else + { + _mm_free(mWeights); + mWeights = NULL; + } + } + + if (mNumIndices) + { + S32 idx_size = (mNumIndices*2+0xF) & ~0xF; + idx_size /= 4; + + LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size); + } + + + //delete + return *this; +} + LLVolumeFace::~LLVolumeFace() { _mm_free(mPositions); @@ -5036,6 +5222,8 @@ LLVolumeFace::~LLVolumeFace() _mm_free(mTexCoords); _mm_free(mIndices); _mm_free(mBinormals); + _mm_free(mWeights); + _mm_free(mExtents); } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) @@ -5169,8 +5357,8 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) num_vertices = (grid_size+1)*(grid_size+1); num_indices = quad_count * 4; - LLVector3& min = mExtents[0]; - LLVector3& max = mExtents[1]; + LLVector4a& min = mExtents[0]; + LLVector4a& max = mExtents[1]; S32 offset = 0; if (mTypeMask & TOP_MASK) @@ -5242,16 +5430,18 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) if (gx == 0 && gy == 0) { - min = max = LLVector3(newVert.getPosition().getF32()); + min = max = newVert.getPosition(); } else { - update_min_max(min,max,newVert.getPosition().getF32()); + min.setMin(newVert.getPosition()); + max.setMax(newVert.getPosition()); } } } - mCenter = (min + max) * 0.5f; + mCenter->setAdd(min, max); + mCenter->mul(0.5f); if (!partial_build) { @@ -5335,7 +5525,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) S32 max_s = volume->getProfile().getTotal(); S32 max_t = volume->getPath().mPath.size(); - mCenter.clearVec(); + mCenter->clear(); S32 offset = 0; if (mTypeMask & TOP_MASK) @@ -5353,8 +5543,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) LLVector2 cuv; LLVector2 min_uv, max_uv; - LLVector3& min = mExtents[0]; - LLVector3& max = mExtents[1]; + LLVector4a& min = mExtents[0]; + LLVector4a& max = mExtents[1]; LLVector2* tc = (LLVector2*) mTexCoords; LLVector4a* pos = (LLVector4a*) mPositions; @@ -5380,25 +5570,24 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) if (i == 0) { - min = max = mesh[i+offset].mPos; + min = max = pos[i]; min_uv = max_uv = tc[i]; } else { - update_min_max(min,max, mesh[i+offset].mPos); + update_min_max(min,max,pos[i]); update_min_max(min_uv, max_uv, tc[i]); } } - mCenter = (min+max)*0.5f; - cuv = (min_uv + max_uv)*0.5f; + mCenter->setAdd(min, max); + mCenter->mul(0.5f); - LLVector4a center; - center.load3(mCenter.mV); + cuv = (min_uv + max_uv)*0.5f; LLVector4a binormal; calc_binormal_from_triangle(binormal, - center, cuv, + *mCenter, cuv, pos[0], tc[0], pos[1], tc[1]); binormal.normalize3fast(); @@ -5407,8 +5596,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) LLVector4a d0, d1; - d0.setSub(center, pos[0]); - d1.setSub(center, pos[1]); + d0.setSub(*mCenter, pos[0]); + d1.setSub(*mCenter, pos[1]); if (mTypeMask & TOP_MASK) { @@ -5422,12 +5611,12 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) normal.normalize3fast(); VertexData vd; - vd.getPosition().load3(mCenter.mV); + vd.setPosition(*mCenter); vd.mTexCoord = cuv; if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) { - pos[num_vertices].load4a((F32*) ¢er.mQ); + pos[num_vertices] = *mCenter; tc[num_vertices] = cuv; num_vertices++; } @@ -5812,6 +6001,11 @@ void LLVolumeFace::allocateBinormals(S32 num_verts) mBinormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); } +void LLVolumeFace::allocateWeights(S32 num_verts) +{ + _mm_free(mWeights); + mWeights = (LLVector4a*) _mm_malloc(num_verts*16, 16); +} void LLVolumeFace::resizeIndices(S32 num_indices) { @@ -5919,11 +6113,11 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat if (offset == 0 && i == 0) { - mExtents[0] = mExtents[1] = LLVector3((F32*) &(dst_pos[i].mQ)); + mExtents[0] = mExtents[1] = dst_pos[i]; } else { - update_min_max(mExtents[0], mExtents[1], (F32*) &(dst_pos[i].mQ)); + update_min_max(mExtents[0], mExtents[1], dst_pos[i]); } } @@ -6076,18 +6270,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) //get bounding box for this side - LLVector3& face_min = mExtents[0]; - LLVector3& face_max = mExtents[1]; - mCenter.clearVec(); + LLVector4a& face_min = mExtents[0]; + LLVector4a& face_max = mExtents[1]; + mCenter->clear(); - face_min = face_max = LLVector3((F32*) &(pos[0].mQ)); + face_min = face_max = pos[0]; for (U32 i = 1; i < mNumVertices; ++i) { - update_min_max(face_min, face_max, (F32*) &(pos[i].mQ)); + update_min_max(face_min, face_max, pos[i]); } - mCenter = (face_min + face_max) * 0.5f; + mCenter->setAdd(face_min, face_max); + mCenter->mul(0.5f); S32 cur_index = 0; S32 cur_edge = 0; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index aa58d6d114..7c63266aab 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -50,12 +50,13 @@ class LLVolume; #include "v2math.h" #include "v3math.h" #include "v4math.h" +#include "llvector4a.h" #include "llquaternion.h" #include "llstrider.h" #include "v4coloru.h" #include "llrefcount.h" #include "llfile.h" -#include "llvector4a.h" + //============================================================================ @@ -801,59 +802,19 @@ public: }; private: - void init() - { - mData = (LLVector4a*) _mm_malloc(32, 16); - } + void init(); public: - VertexData() - { - init(); - } - - VertexData(const VertexData& rhs) - { - init(); - LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); - mTexCoord = rhs.mTexCoord; - } - - ~VertexData() - { - _mm_free(mData); - } - - LLVector4a& getPosition() - { - return mData[POSITION]; - } - - LLVector4a& getNormal() - { - return mData[NORMAL]; - } - - const LLVector4a& getPosition() const - { - return mData[POSITION]; - } - - const LLVector4a& getNormal() const - { - return mData[NORMAL]; - } + VertexData(); + VertexData(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); - void setPosition(const LLVector4a& pos) - { - mData[POSITION] = pos; - } - - void setNormal(const LLVector4a& norm) - { - mData[NORMAL] = norm; - } - LLVector2 mTexCoord; bool operator<(const VertexData& rhs) const; @@ -864,22 +825,9 @@ public: LLVector4a* mData; }; - LLVolumeFace() : - mID(0), - mTypeMask(0), - mBeginS(0), - mBeginT(0), - mNumS(0), - mNumT(0), - mNumVertices(0), - mNumIndices(0), - mPositions(NULL), - mNormals(NULL), - mBinormals(NULL), - mTexCoords(NULL), - mIndices(NULL) - { - } + LLVolumeFace(); + LLVolumeFace(const LLVolumeFace& src); + LLVolumeFace& operator=(const LLVolumeFace& rhs); ~LLVolumeFace(); @@ -890,6 +838,7 @@ public: void resizeVertices(S32 num_verts); void allocateBinormals(S32 num_verts); + void allocateWeights(S32 num_verts); void resizeIndices(S32 num_indices); void fillFromLegacyData(std::vector& v, std::vector& idx); @@ -944,15 +893,15 @@ public: public: S32 mID; U32 mTypeMask; - LLVector3 mCenter; - + // 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; S32 mNumVertices; S32 mNumIndices; @@ -968,7 +917,7 @@ public: //list of skin weights for rigged volumes // format is mWeights[vertex_index].mV[influence] = . // mWeights.size() should be empty or match mVertices.size() - std::vector mWeights; + LLVector4a* mWeights; private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); @@ -1051,6 +1000,13 @@ public: LLVector3* normal = NULL, // return the surface normal at the intersection point LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point ); + + S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, + S32 face = 1, + LLVector3* intersection = NULL, + LLVector2* tex_coord = NULL, + LLVector3* normal = NULL, + LLVector3* bi_normal = NULL); // The following cleans up vertices and triangles, // getting rid of degenerate triangles and duplicate vertices, @@ -1124,6 +1080,7 @@ void calc_binormal_from_triangle( const LLVector4a& 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, diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 0e7d72e958..75c860a91e 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -36,7 +36,6 @@ #include "llerror.h" #include "llmath.h" - #include "llsd.h" class LLVector2; class LLVector4; -- cgit v1.2.3 From 0e7f4dc5cef8a97cb1dd08aa2f79538ced267888 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 29 May 2010 05:37:38 -0500 Subject: Octree per LLVolumeFace WIP --- indra/llmath/lloctree.h | 18 ++ indra/llmath/llvolume.cpp | 625 ++++++++++++++++++++++++++++++++++++---------- indra/llmath/llvolume.h | 45 ++-- 3 files changed, 539 insertions(+), 149 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 2f34fb1bb0..8bba12783f 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -72,6 +72,13 @@ public: virtual void visit(const LLOctreeNode* branch) = 0; }; +template +class LLOctreeTravelerDepthFirst : public LLOctreeTraveler +{ +public: + virtual void traverse(const LLOctreeNode* node); +}; + template class LLOctreeNode : public LLTreeNode { @@ -710,4 +717,15 @@ void LLOctreeTraveler::traverse(const LLOctreeNode* node) traverse(node->getChild(i)); } } + +template +void LLOctreeTravelerDepthFirst::traverse(const LLOctreeNode* node) +{ + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + } + node->accept(this); +} + #endif diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 9b6e2488e6..d261811aa2 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -45,6 +45,7 @@ #include "m4math.h" #include "m3math.h" #include "llmatrix4a.h" +#include "lloctree.h" #include "lldarray.h" #include "llvolume.h" #include "llstl.h" @@ -132,6 +133,51 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent return true; } +BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size) +{ + LLVector4a fAWdU; + LLVector4a dir; + LLVector4a diff; + + dir.setSub(end, start); + dir.mul(0.5f); + + diff.setAdd(end,start); + diff.mul(0.5f); + diff.sub(center); + fAWdU.setAbs(dir); + + LLVector4a rhs; + rhs.setAdd(size, fAWdU); + + LLVector4a lhs; + lhs.setAbs(diff); + + S32 grt = lhs.greaterThan4(rhs).getComparisonMask(); + + if (grt & 0x7) + { + return false; + } + + LLVector4a f; + f.setCross3(dir, diff); + f.setAbs(f); + + LLVector4a v0; v0.mQ = _mm_shuffle_ps(size.mQ, size.mQ, _MM_SHUFFLE(3,1,0,0)); + LLVector4a v1; v1.mQ = _mm_shuffle_ps(fAWdU.mQ, fAWdU.mQ, _MM_SHUFFLE(3,2,2,1)); + lhs.setMul(v0, v1); + + v0.mQ = _mm_shuffle_ps(size.mQ, size.mQ, _MM_SHUFFLE(3,2,2,1)); + v1.mQ = _mm_shuffle_ps(fAWdU.mQ, fAWdU.mQ, _MM_SHUFFLE(3,1,0,0)); + rhs.setMul(v0, v1); + rhs.add(lhs); + + grt = f.greaterThan4(rhs).getComparisonMask(); + + return (grt & 0x7) ? false : true; +} + // intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. // returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b, @@ -139,15 +185,13 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent // Moller-Trumbore algorithm 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 two_sided) + F32& intersection_a, F32& intersection_b, F32& intersection_t) { - F32 u, v, t; /* find vectors for two edges sharing vert0 */ LLVector4a edge1; edge1.setSub(vert1, vert0); - LLVector4a edge2; edge2.setSub(vert2, vert0); @@ -156,87 +200,116 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co pvec.setCross3(dir, edge2); /* if determinant is near zero, ray lies in plane of triangle */ - F32 det = edge1.dot3(pvec); - - if (!two_sided) + LLVector4a det; + det.setAllDot3(edge1, pvec); + + if (det.greaterEqual4(LLVector4a::getApproximatelyZero()).getComparisonMask()) { - if (det < F_APPROXIMATELY_ZERO) - { - return FALSE; - } - /* calculate distance from vert0 to ray origin */ LLVector4a tvec; tvec.setSub(orig, vert0); /* calculate U parameter and test bounds */ - u = tvec.dot3(pvec); + LLVector4a u; + u.setAllDot3(tvec,pvec); - if (u < 0.f || u > det) + if (u.greaterEqual4(LLVector4a::getZero()).getComparisonMask() && + u.lessEqual4(det).getComparisonMask()) { - return FALSE; + /* prepare to test V parameter */ + LLVector4a qvec; + qvec.setCross3(tvec, edge1); + + /* calculate V parameter and test bounds */ + LLVector4a v; + v.setAllDot3(dir, qvec); + + + //if (!(v < 0.f || u + v > det)) + + LLVector4a sum_uv; + sum_uv.setAdd(u, v); + + S32 v_gequal = v.greaterEqual4(LLVector4a::getZero()).getComparisonMask(); + S32 sum_lequal = sum_uv.lessEqual4(det).getComparisonMask(); + + if (v_gequal && sum_lequal) + { + /* calculate t, scale parameters, ray intersects triangle */ + LLVector4a t; + t.setAllDot3(edge2,qvec); + + t.div(det); + u.div(det); + v.div(det); + + intersection_a = u[0]; + intersection_b = v[0]; + intersection_t = t[0]; + return TRUE; + } } - - /* prepare to test V parameter */ - LLVector4a qvec; - qvec.setCross3(tvec, edge1); + } - /* calculate V parameter and test bounds */ - v = dir.dot3(qvec); - if (v < 0.f || u + v > det) - { - return FALSE; - } + return FALSE; +} - /* calculate t, scale parameters, ray intersects triangle */ - t = edge2.dot3(qvec); - F32 inv_det = 1.0 / det; - t *= inv_det; - u *= inv_det; - v *= inv_det; - } +BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, + F32& intersection_a, F32& intersection_b, F32& intersection_t) +{ + F32 u, v, t; - else // two sided - { - if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO) - { - return FALSE; - } - F32 inv_det = 1.0 / det; + /* find vectors for two edges sharing vert0 */ + LLVector4a edge1; + edge1.setSub(vert1, vert0); + + + LLVector4a edge2; + edge2.setSub(vert2, vert0); - /* calculate distance from vert0 to ray origin */ - LLVector4a tvec; - tvec.setSub(orig, vert0); - - /* calculate U parameter and test bounds */ - u = (tvec.dot3(pvec)) * inv_det; - if (u < 0.f || u > 1.f) - { - return FALSE; - } + /* begin calculating determinant - also used to calculate U parameter */ + LLVector4a pvec; + pvec.setCross3(dir, edge2); - /* prepare to test V parameter */ - LLVector4a qvec; - qvec.setSub(tvec, edge1); - - /* calculate V parameter and test bounds */ - v = (dir.dot3(qvec)) * inv_det; - - if (v < 0.f || u + v > 1.f) - { - return FALSE; - } + /* if determinant is near zero, ray lies in plane of triangle */ + F32 det = edge1.dot3(pvec); + + + if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO) + { + return FALSE; + } + + F32 inv_det = 1.f / det; + + /* calculate distance from vert0 to ray origin */ + LLVector4a tvec; + tvec.setSub(orig, vert0); + + /* calculate U parameter and test bounds */ + u = (tvec.dot3(pvec)) * inv_det; + if (u < 0.f || u > 1.f) + { + return FALSE; + } - /* calculate t, ray intersects triangle */ - t = (edge2.dot3(qvec)) * inv_det; + /* prepare to test V parameter */ + tvec.sub(edge1); + + /* calculate V parameter and test bounds */ + v = (dir.dot3(tvec)) * inv_det; + + if (v < 0.f || u + v > 1.f) + { + return FALSE; } + + /* calculate t, ray intersects triangle */ + t = (edge2.dot3(tvec)) * inv_det; - if (intersection_a != NULL) - *intersection_a = u; - if (intersection_b != NULL) - *intersection_b = v; - if (intersection_t != NULL) - *intersection_t = t; + intersection_a = u; + intersection_b = v; + intersection_t = t; return TRUE; @@ -244,7 +317,7 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co //helper for non-aligned vectors BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, - F32* intersection_a, F32* intersection_b, F32* intersection_t, BOOL two_sided) + F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided) { LLVector4a vert0a, vert1a, vert2a, origa, dira; vert0a.load3(vert0.mV); @@ -253,11 +326,130 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons origa.load3(orig.mV); dira.load3(dir.mV); - return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira, - intersection_a, intersection_b, intersection_t, two_sided); + if (two_sided) + { + return LLTriangleRayIntersectTwoSided(vert0a, vert1a, vert2a, origa, dira, + intersection_a, intersection_b, intersection_t); + } + else + { + return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira, + intersection_a, intersection_b, intersection_t); + } } +class LLVolumeOctreeListener : public LLOctreeListener +{ +public: + + LLVolumeOctreeListener(LLOctreeNode* node) + { + node->addListener(this); + + mBounds = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*4, 16); + mExtents = mBounds+2; + } + + ~LLVolumeOctreeListener() + { + _mm_free(mBounds); + } + + //LISTENER FUNCTIONS + virtual void handleChildAddition(const LLOctreeNode* parent, + LLOctreeNode* child) + { + new LLVolumeOctreeListener(child); + } + + virtual void handleStateChange(const LLTreeNode* node) { } + virtual void handleChildRemoval(const LLOctreeNode* parent, + const LLOctreeNode* child) { } + virtual void handleInsertion(const LLTreeNode* node, LLVolumeFace::Triangle* tri) { } + virtual void handleRemoval(const LLTreeNode* node, LLVolumeFace::Triangle* tri) { } + virtual void handleDestruction(const LLTreeNode* node) { } + + +public: + LLVector4a* mBounds; // bounding box (center, size) of this node and all its children (tight fit to objects) + LLVector4a* mExtents; // extents (min, max) of this node and all its children +}; + +class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst +{ +public: + const LLVolumeFace* mFace; + + LLVolumeOctreeRebound(const LLVolumeFace* face) + { + mFace = face; + } + + virtual void visit(const LLOctreeNode* branch) + { + LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); + + LLVector4a& min = node->mExtents[0]; + LLVector4a& max = node->mExtents[1]; + + if (branch->getElementCount() != 0) + { + const LLVolumeFace::Triangle* tri = *(branch->getData().begin()); + + min = *(tri->mV[0]); + max = *(tri->mV[0]); + + for (LLOctreeNode::const_element_iter iter = + branch->getData().begin(); iter != branch->getData().end(); ++iter) + { + //stretch by triangles in node + tri = *iter; + + min.setMin(*tri->mV[0]); + min.setMin(*tri->mV[1]); + min.setMin(*tri->mV[2]); + + max.setMax(*tri->mV[0]); + max.setMax(*tri->mV[1]); + max.setMax(*tri->mV[2]); + } + + for (S32 i = 0; i < branch->getChildCount(); ++i) + { //stretch by child extents + LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); + min.setMin(child->mExtents[0]); + max.setMax(child->mExtents[1]); + } + } + else if (branch->getChildCount() != 0) + { + LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0); + + min = child->mExtents[0]; + max = child->mExtents[1]; + + for (S32 i = 1; i < branch->getChildCount(); ++i) + { //stretch by child extents + child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); + min.setMin(child->mExtents[0]); + max.setMax(child->mExtents[1]); + } + } + else + { + llerrs << "WTF? Empty leaf" << llendl; + } + + node->mBounds[0].setAdd(min, max); + node->mBounds[0].mul(0.5f); + + node->mBounds[1].setSub(max,min); + node->mBounds[1].mul(0.5f); + } +}; + + //------------------------------------------------------------------- // statics //------------------------------------------------------------------- @@ -4244,6 +4436,114 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, } +class LLOctreeTriangleRayIntersect : public LLOctreeTraveler +{ +public: + const LLVolumeFace* mFace; + LLVector4a mStart; + LLVector4a mDir; + LLVector4a mEnd; + LLVector3* mIntersection; + LLVector2* mTexCoord; + LLVector3* mNormal; + LLVector3* mBinormal; + F32* mClosestT; + bool mHitFace; + + LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, + const LLVolumeFace* face, F32* closest_t, + LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) + : mFace(face), + mStart(start), + mDir(dir), + mIntersection(intersection), + mTexCoord(tex_coord), + mNormal(normal), + mBinormal(bi_normal), + mClosestT(closest_t), + mHitFace(false) + { + mEnd.setAdd(mStart, mDir); + } + + void traverse(const LLOctreeNode* node) + { + LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); + + /*const F32* start = mStart.getF32(); + const F32* end = mEnd.getF32(); + const F32* center = vl->mBounds[0].getF32(); + const F32* size = vl->mBounds[1].getF32();*/ + + if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) + { + node->accept(this); + for (S32 i = 0; i < node->getChildCount(); ++i) + { + traverse(node->getChild(i)); + } + } + } + + void visit(const LLOctreeNode* node) + { + for (LLOctreeNode::const_element_iter iter = + node->getData().begin(); iter != node->getData().end(); ++iter) + { + const LLVolumeFace::Triangle* tri = *iter; + + F32 a, b, t; + + if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2], + mStart, mDir, a, b, t)) + { + if ((t >= 0.f) && // if hit is after start + (t <= 1.f) && // and before end + (t < *mClosestT)) // and this hit is closer + { + *mClosestT = t; + mHitFace = true; + + if (mIntersection != NULL) + { + LLVector4a intersect = mDir; + intersect.mul(*mClosestT); + intersect.add(mStart); + mIntersection->set(intersect.getF32()); + } + + + if (mTexCoord != NULL) + { + LLVector2* tc = (LLVector2*) mFace->mTexCoords; + *mTexCoord = ((1.f - a - b) * tc[tri->mIndex[0]] + + a * tc[tri->mIndex[1]] + + b * tc[tri->mIndex[2]]); + + } + + if (mNormal != NULL) + { + LLVector4* norm = (LLVector4*) mFace->mNormals; + + *mNormal = ((1.f - a - b) * LLVector3(norm[tri->mIndex[0]]) + + a * LLVector3(norm[tri->mIndex[1]]) + + b * LLVector3(norm[tri->mIndex[2]])); + } + + if (mBinormal != NULL) + { + LLVector4* binormal = (LLVector4*) mFace->mBinormals; + *mBinormal = ((1.f - a - b) * LLVector3(binormal[tri->mIndex[0]]) + + a * LLVector3(binormal[tri->mIndex[1]]) + + b * LLVector3(binormal[tri->mIndex[2]])); + } + } + } + } + } +}; + S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) @@ -4288,66 +4588,19 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en { genBinormals(i); } - - LLVector4a* p = (LLVector4a*) face.mPositions; - for (U32 tri = 0; tri < face.mNumIndices/3; tri++) + if (!face.mOctree) { - S32 index1 = face.mIndices[tri*3+0]; - S32 index2 = face.mIndices[tri*3+1]; - S32 index3 = face.mIndices[tri*3+2]; - - F32 a, b, t; + face.createOctree(); + } - if (LLTriangleRayIntersect(p[index1], - p[index2], - p[index3], - start, dir, &a, &b, &t, FALSE)) - { - if ((t >= 0.f) && // if hit is after start - (t <= 1.f) && // and before end - (t < closest_t)) // and this hit is closer - { - closest_t = t; - hit_face = i; - - if (intersection != NULL) - { - LLVector4a intersect = dir; - intersect.mul(closest_t); - intersect.add(start); - intersection->set(intersect.getF32()); - } - - - if (tex_coord != NULL) - { - LLVector2* tc = (LLVector2*) face.mTexCoords; - *tex_coord = ((1.f - a - b) * tc[index1] + - a * tc[index2] + - b * tc[index3]); - - } - - if (normal != NULL) - { - LLVector4* norm = (LLVector4*) face.mNormals; - - *normal = ((1.f - a - b) * LLVector3(norm[index1]) + - a * LLVector3(norm[index2]) + - b * LLVector3(norm[index3])); - } - - if (bi_normal != NULL) - { - LLVector4* binormal = (LLVector4*) face.mBinormals; - *bi_normal = ((1.f - a - b) * LLVector3(binormal[index1]) + - a * LLVector3(binormal[index2]) + - b * LLVector3(binormal[index3])); - } + LLVector4a* p = (LLVector4a*) face.mPositions; - } - } + LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); + intersect.traverse(face.mOctree); + if (intersect.mHitFace) + { + hit_face = i; } } } @@ -5128,13 +5381,29 @@ LLVolumeFace::LLVolumeFace() : mBinormals(NULL), mTexCoords(NULL), mIndices(NULL), - mWeights(NULL) + mWeights(NULL), + mOctree(NULL) { mExtents = (LLVector4a*) _mm_malloc(48, 16); mCenter = mExtents+2; } LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) +: mID(0), + mTypeMask(0), + mBeginS(0), + mBeginT(0), + mNumS(0), + mNumT(0), + mNumVertices(0), + mNumIndices(0), + mPositions(NULL), + mNormals(NULL), + mBinormals(NULL), + mTexCoords(NULL), + mIndices(NULL), + mWeights(NULL), + mOctree(NULL) { mExtents = (LLVector4a*) _mm_malloc(48, 16); mCenter = mExtents+2; @@ -5157,13 +5426,9 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) mNumVertices = 0; mNumIndices = 0; - mPositions = NULL; - mNormals = NULL; - mBinormals = NULL; - mTexCoords = NULL; - mWeights = NULL; - mIndices = NULL; + freeData(); + LLVector4a::memcpyNonAliased16((F32*) mExtents, (F32*) src.mExtents, 12); resizeVertices(src.mNumVertices); @@ -5179,6 +5444,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, vert_size); + if (src.mBinormals) { allocateBinormals(src.mNumVertices); @@ -5216,18 +5482,38 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } LLVolumeFace::~LLVolumeFace() +{ + _mm_free(mExtents); + mExtents = NULL; + + freeData(); +} + +void LLVolumeFace::freeData() { _mm_free(mPositions); + mPositions = NULL; _mm_free(mNormals); + mNormals = NULL; _mm_free(mTexCoords); + mTexCoords = NULL; _mm_free(mIndices); + mIndices = NULL; _mm_free(mBinormals); + mBinormals = NULL; _mm_free(mWeights); - _mm_free(mExtents); + mWeights = NULL; + + delete mOctree; + mOctree = NULL; } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { + //tree for this face is no longer valid + delete mOctree; + mOctree = NULL; + if (mTypeMask & CAP_MASK) { return createCap(volume, partial_build); @@ -5250,6 +5536,18 @@ void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv) cv.mTexCoord = mTexCoords[index]; } +bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const +{ + return getPosition().equal3(rhs.getPosition()) && + mTexCoord == rhs.mTexCoord && + getNormal().equal3(rhs.getNormal()); +} + +bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector4a& a, const LLVector4a& b) const +{ + return a.less3(b); +} + void LLVolumeFace::optimize(F32 angle_cutoff) { LLVolumeFace new_face; @@ -5305,6 +5603,65 @@ void LLVolumeFace::optimize(F32 angle_cutoff) swapData(new_face); } + +void LLVolumeFace::createOctree() +{ + mOctree = new LLOctreeRoot(LLVector3d(0,0,0), LLVector3d(1,1,1), NULL); + new LLVolumeOctreeListener(mOctree); + + for (U32 i = 0; i < mNumIndices; i+= 3) + { + Triangle* tri = new Triangle(); + + const LLVector4a& v0 = mPositions[mIndices[i]]; + const LLVector4a& v1 = mPositions[mIndices[i+1]]; + const LLVector4a& v2 = mPositions[mIndices[i+2]]; + + tri->mV[0] = &v0; + tri->mV[1] = &v1; + tri->mV[2] = &v2; + + tri->mIndex[0] = mIndices[i]; + tri->mIndex[1] = mIndices[i+1]; + tri->mIndex[2] = mIndices[i+2]; + + LLVector4a min = v0; + min.setMin(v1); + min.setMin(v2); + + LLVector4a max = v0; + max.setMax(v1); + max.setMax(v2); + + LLVector4a center; + center.setAdd(min, max); + center.mul(0.5f); + + + tri->mPositionGroup.setVec(center[0], center[1], center[2]); + + LLVector4a size; + size.setSub(max,min); + + tri->mRadius = size.length3() * 0.5f; + + mOctree->insert(tri); + } + + LLVolumeOctreeRebound rebound(this); + rebound.traverse(mOctree); +} + +const LLVector3d& LLVolumeFace::Triangle::getPositionGroup() const +{ + return mPositionGroup; +} + +const F64& LLVolumeFace::Triangle::getBinRadius() const +{ + return mRadius; +} + void LLVolumeFace::swapData(LLVolumeFace& rhs) { llswap(rhs.mPositions, mPositions); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 7c63266aab..a40a21b405 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -40,6 +40,9 @@ class LLPathParams; class LLVolumeParams; class LLProfile; class LLPath; + +template class LLOctreeNode; +class LLVector4a; class LLVolumeFace; class LLVolume; @@ -49,15 +52,14 @@ class LLVolume; //#include "vmath.h" #include "v2math.h" #include "v3math.h" +#include "v3dmath.h" #include "v4math.h" -#include "llvector4a.h" #include "llquaternion.h" #include "llstrider.h" #include "v4coloru.h" #include "llrefcount.h" #include "llfile.h" - //============================================================================ const S32 MIN_DETAIL_FACES = 6; @@ -830,6 +832,9 @@ public: LLVolumeFace& operator=(const LLVolumeFace& rhs); ~LLVolumeFace(); +private: + void freeData(); +public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); void createBinormals(); @@ -855,26 +860,19 @@ public: public: U16 mIndex; - bool operator==(const LLVolumeFace::VertexData& rhs) const - { - return getPosition().equal3(rhs.getPosition()) && - mTexCoord == rhs.mTexCoord && - getNormal().equal3(rhs.getNormal()); - } + bool operator==(const LLVolumeFace::VertexData& rhs) const; struct ComparePosition { - bool operator()(const LLVector4a& a, const LLVector4a& b) const - { - return a.less3(b); - } + bool operator()(const LLVector4a& a, const LLVector4a& b) const; }; typedef std::map, VertexMapData::ComparePosition > PointMap; }; void optimize(F32 angle_cutoff = 2.f); - + void createOctree(); + enum { SINGLE_MASK = 0x0001, @@ -919,6 +917,21 @@ public: // mWeights.size() should be empty or match mVertices.size() LLVector4a* mWeights; + class Triangle : public LLRefCount + { + public: + const LLVector4a* mV[3]; + U16 mIndex[3]; + + LLVector3d mPositionGroup; + F64 mRadius; + + virtual const LLVector3d& getPositionGroup() const; + virtual const F64& getBinRadius() const; + }; + + LLOctreeNode* mOctree; + private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); @@ -1084,10 +1097,12 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent 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); + 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 two_sided); + 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); -- cgit v1.2.3 From 9a869d630162292864e01fdd1707efc609fbd6b4 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 29 May 2010 19:55:13 -0500 Subject: Octree triven raycast works, time to profile. --- indra/llmath/CMakeLists.txt | 2 + indra/llmath/lltreenode.h | 3 + indra/llmath/llvolume.cpp | 202 ++------------------------------------------ indra/llmath/llvolume.h | 2 + 4 files changed, 14 insertions(+), 195 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 367486eee7..dda07133d5 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -22,6 +22,7 @@ set(llmath_SOURCE_FILES llsphere.cpp llvolume.cpp llvolumemgr.cpp + llvolumeoctree.cpp llsdutil_math.cpp m3math.cpp m4math.cpp @@ -66,6 +67,7 @@ set(llmath_HEADER_FILES llmatrix4a.h llvolume.h llvolumemgr.h + llvolumeoctree.h llsdutil_math.h m3math.h m4math.h diff --git a/indra/llmath/lltreenode.h b/indra/llmath/lltreenode.h index ee9836241a..e6d2521b2a 100644 --- a/indra/llmath/lltreenode.h +++ b/indra/llmath/lltreenode.h @@ -34,6 +34,9 @@ #include "stdtypes.h" #include "xform.h" +#include "llpointer.h" +#include "llrefcount.h" + #include template class LLTreeNode; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d261811aa2..c4172de651 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -48,6 +48,7 @@ #include "lloctree.h" #include "lldarray.h" #include "llvolume.h" +#include "llvolumeoctree.h" #include "llstl.h" #include "llsdserialize.h" #include "llvector4a.h" @@ -133,50 +134,6 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent return true; } -BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size) -{ - LLVector4a fAWdU; - LLVector4a dir; - LLVector4a diff; - - dir.setSub(end, start); - dir.mul(0.5f); - - diff.setAdd(end,start); - diff.mul(0.5f); - diff.sub(center); - fAWdU.setAbs(dir); - - LLVector4a rhs; - rhs.setAdd(size, fAWdU); - - LLVector4a lhs; - lhs.setAbs(diff); - - S32 grt = lhs.greaterThan4(rhs).getComparisonMask(); - - if (grt & 0x7) - { - return false; - } - - LLVector4a f; - f.setCross3(dir, diff); - f.setAbs(f); - - LLVector4a v0; v0.mQ = _mm_shuffle_ps(size.mQ, size.mQ, _MM_SHUFFLE(3,1,0,0)); - LLVector4a v1; v1.mQ = _mm_shuffle_ps(fAWdU.mQ, fAWdU.mQ, _MM_SHUFFLE(3,2,2,1)); - lhs.setMul(v0, v1); - - v0.mQ = _mm_shuffle_ps(size.mQ, size.mQ, _MM_SHUFFLE(3,2,2,1)); - v1.mQ = _mm_shuffle_ps(fAWdU.mQ, fAWdU.mQ, _MM_SHUFFLE(3,1,0,0)); - rhs.setMul(v0, v1); - rhs.add(lhs); - - grt = f.greaterThan4(rhs).getComparisonMask(); - - return (grt & 0x7) ? false : true; -} // intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. @@ -203,7 +160,7 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co LLVector4a det; det.setAllDot3(edge1, pvec); - if (det.greaterEqual4(LLVector4a::getApproximatelyZero()).getComparisonMask()) + if (det.greaterEqual4(LLVector4a::getApproximatelyZero()).getComparisonMask() & 0x7) { /* calculate distance from vert0 to ray origin */ LLVector4a tvec; @@ -213,8 +170,8 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co LLVector4a u; u.setAllDot3(tvec,pvec); - if (u.greaterEqual4(LLVector4a::getZero()).getComparisonMask() && - u.lessEqual4(det).getComparisonMask()) + if ((u.greaterEqual4(LLVector4a::getZero()).getComparisonMask() & 0x7) && + (u.lessEqual4(det).getComparisonMask() & 0x7)) { /* prepare to test V parameter */ LLVector4a qvec; @@ -230,10 +187,10 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co LLVector4a sum_uv; sum_uv.setAdd(u, v); - S32 v_gequal = v.greaterEqual4(LLVector4a::getZero()).getComparisonMask(); - S32 sum_lequal = sum_uv.lessEqual4(det).getComparisonMask(); + S32 v_gequal = v.greaterEqual4(LLVector4a::getZero()).getComparisonMask() & 0x7; + S32 sum_lequal = sum_uv.lessEqual4(det).getComparisonMask() & 0x7; - if (v_gequal && sum_lequal) + if (v_gequal && sum_lequal) { /* calculate t, scale parameters, ray intersects triangle */ LLVector4a t; @@ -338,44 +295,6 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } } - -class LLVolumeOctreeListener : public LLOctreeListener -{ -public: - - LLVolumeOctreeListener(LLOctreeNode* node) - { - node->addListener(this); - - mBounds = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*4, 16); - mExtents = mBounds+2; - } - - ~LLVolumeOctreeListener() - { - _mm_free(mBounds); - } - - //LISTENER FUNCTIONS - virtual void handleChildAddition(const LLOctreeNode* parent, - LLOctreeNode* child) - { - new LLVolumeOctreeListener(child); - } - - virtual void handleStateChange(const LLTreeNode* node) { } - virtual void handleChildRemoval(const LLOctreeNode* parent, - const LLOctreeNode* child) { } - virtual void handleInsertion(const LLTreeNode* node, LLVolumeFace::Triangle* tri) { } - virtual void handleRemoval(const LLTreeNode* node, LLVolumeFace::Triangle* tri) { } - virtual void handleDestruction(const LLTreeNode* node) { } - - -public: - LLVector4a* mBounds; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a* mExtents; // extents (min, max) of this node and all its children -}; - class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst { public: @@ -4436,113 +4355,6 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, } -class LLOctreeTriangleRayIntersect : public LLOctreeTraveler -{ -public: - const LLVolumeFace* mFace; - LLVector4a mStart; - LLVector4a mDir; - LLVector4a mEnd; - LLVector3* mIntersection; - LLVector2* mTexCoord; - LLVector3* mNormal; - LLVector3* mBinormal; - F32* mClosestT; - bool mHitFace; - - LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, - const LLVolumeFace* face, F32* closest_t, - LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) - : mFace(face), - mStart(start), - mDir(dir), - mIntersection(intersection), - mTexCoord(tex_coord), - mNormal(normal), - mBinormal(bi_normal), - mClosestT(closest_t), - mHitFace(false) - { - mEnd.setAdd(mStart, mDir); - } - - void traverse(const LLOctreeNode* node) - { - LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); - - /*const F32* start = mStart.getF32(); - const F32* end = mEnd.getF32(); - const F32* center = vl->mBounds[0].getF32(); - const F32* size = vl->mBounds[1].getF32();*/ - - if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) - { - node->accept(this); - for (S32 i = 0; i < node->getChildCount(); ++i) - { - traverse(node->getChild(i)); - } - } - } - - void visit(const LLOctreeNode* node) - { - for (LLOctreeNode::const_element_iter iter = - node->getData().begin(); iter != node->getData().end(); ++iter) - { - const LLVolumeFace::Triangle* tri = *iter; - - F32 a, b, t; - - if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2], - mStart, mDir, a, b, t)) - { - if ((t >= 0.f) && // if hit is after start - (t <= 1.f) && // and before end - (t < *mClosestT)) // and this hit is closer - { - *mClosestT = t; - mHitFace = true; - - if (mIntersection != NULL) - { - LLVector4a intersect = mDir; - intersect.mul(*mClosestT); - intersect.add(mStart); - mIntersection->set(intersect.getF32()); - } - - - if (mTexCoord != NULL) - { - LLVector2* tc = (LLVector2*) mFace->mTexCoords; - *mTexCoord = ((1.f - a - b) * tc[tri->mIndex[0]] + - a * tc[tri->mIndex[1]] + - b * tc[tri->mIndex[2]]); - - } - - if (mNormal != NULL) - { - LLVector4* norm = (LLVector4*) mFace->mNormals; - - *mNormal = ((1.f - a - b) * LLVector3(norm[tri->mIndex[0]]) + - a * LLVector3(norm[tri->mIndex[1]]) + - b * LLVector3(norm[tri->mIndex[2]])); - } - - if (mBinormal != NULL) - { - LLVector4* binormal = (LLVector4*) mFace->mBinormals; - *mBinormal = ((1.f - a - b) * LLVector3(binormal[tri->mIndex[0]]) + - a * LLVector3(binormal[tri->mIndex[1]]) + - b * LLVector3(binormal[tri->mIndex[2]])); - } - } - } - } - } -}; S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index a40a21b405..0ae8aa19ca 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -42,6 +42,7 @@ class LLProfile; class LLPath; template class LLOctreeNode; + class LLVector4a; class LLVolumeFace; class LLVolume; @@ -1095,6 +1096,7 @@ void calc_binormal_from_triangle( BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size); BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size); +BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size); BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided); -- cgit v1.2.3 From 26ba00b5554d20ee958693ced87b36fa7f6e3d99 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 3 Jun 2010 12:52:28 -0500 Subject: Vectorized octree and much of llspatialpartition and lldrawable. Octree driven raycast. --- indra/llmath/llcamera.cpp | 216 +++++++++++++++++------------------------ indra/llmath/llcamera.h | 29 +++--- indra/llmath/lloctree.h | 239 ++++++++++++++++++++++++---------------------- indra/llmath/llvolume.cpp | 31 +++--- indra/llmath/llvolume.h | 16 +--- 5 files changed, 247 insertions(+), 284 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index 487ed6451f..6b56e4870e 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -48,10 +48,10 @@ LLCamera::LLCamera() : mPlaneCount(6), mFrustumCornerDist(0.f) { + alignPlanes(); calculateFrustumPlanes(); } - LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane) : LLCoordFrame(), mViewHeightInPixels(view_height_in_pixels), @@ -59,6 +59,7 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p mPlaneCount(6), mFrustumCornerDist(0.f) { + alignPlanes(); mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO); mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE); if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE; @@ -67,6 +68,23 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p setView(vertical_fov_rads); } +LLCamera::~LLCamera() +{ + +} + +const LLCamera& LLCamera::operator=(const LLCamera& rhs) +{ + memcpy(this, &rhs, sizeof(LLCamera)); + alignPlanes(); + LLVector4a::memcpyNonAliased16((F32*) mAgentPlanes, (F32*) rhs.mAgentPlanes, 4*7); + return *this; +} + +void LLCamera::alignPlanes() +{ + mAgentPlanes = (LLPlane*) LL_NEXT_ALIGNED_ADDRESS(mAgentPlaneBuffer); +} // ---------------- LLCamera::getFoo() member functions ---------------- @@ -91,8 +109,8 @@ F32 LLCamera::getMaxView() const void LLCamera::setUserClipPlane(LLPlane plane) { mPlaneCount = 7; - mAgentPlanes[6].p = plane; - mAgentPlanes[6].mask = calcPlaneMask(plane); + mAgentPlanes[6] = plane; + mPlaneMask[6] = calcPlaneMask(plane); } void LLCamera::disableUserClipPlane() @@ -164,129 +182,66 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer) // ---------------- test methods ---------------- -S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) -{ - static const LLVector3 scaler[] = { - LLVector3(-1,-1,-1), - LLVector3( 1,-1,-1), - LLVector3(-1, 1,-1), - LLVector3( 1, 1,-1), - LLVector3(-1,-1, 1), - LLVector3( 1,-1, 1), - LLVector3(-1, 1, 1), - LLVector3( 1, 1, 1) +S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) +{ + static const LLVector4a scaler[] = { + LLVector4a(-1,-1,-1), + LLVector4a( 1,-1,-1), + LLVector4a(-1, 1,-1), + LLVector4a( 1, 1,-1), + LLVector4a(-1,-1, 1), + LLVector4a( 1,-1, 1), + LLVector4a(-1, 1, 1), + LLVector4a( 1, 1, 1) }; U8 mask = 0; S32 result = 2; - /*if (mFrustumCornerDist > 0.f && radius.magVecSquared() > mFrustumCornerDist * mFrustumCornerDist) - { //box is larger than frustum, check frustum quads against box planes - - static const LLVector3 dir[] = - { - LLVector3(1, 0, 0), - LLVector3(-1, 0, 0), - LLVector3(0, 1, 0), - LLVector3(0, -1, 0), - LLVector3(0, 0, 1), - LLVector3(0, 0, -1) - }; - - U32 quads[] = + for (U32 i = 0; i < mPlaneCount; i++) + { + mask = mPlaneMask[i]; + if (mask == 0xff) { - 0, 1, 2, 3, - 0, 1, 5, 4, - 2, 3, 7, 6, - 3, 0, 7, 4, - 1, 2, 6, 4, - 4, 5, 6, 7 - }; - - result = 0; - - BOOL total_inside = TRUE; - for (U32 i = 0; i < 6; i++) - { - LLVector3 p = center + radius.scaledVec(dir[i]); - F32 d = -p*dir[i]; - - for (U32 j = 0; j < 6; j++) - { //for each quad - F32 dist = mAgentFrustum[quads[j*4+0]]*dir[i] + d; - if (dist > 0) - { //at least one frustum point is outside the AABB - total_inside = FALSE; - for (U32 k = 1; k < 4; k++) - { //for each other point on quad - if ( mAgentFrustum[quads[j*4+k]]*dir[i]+d <= 0.f) - { //quad is straddling some plane of AABB - return 1; - } - } - } - else - { - for (U32 k = 1; k < 4; k++) - { - if (mAgentFrustum[quads[j*4+k]]*dir[i]+d > 0.f) - { - return 1; - } - } - } - } + continue; } - if (total_inside) + const LLPlane& p = mAgentPlanes[i]; + const LLVector4a& n = reinterpret_cast(p); + float d = p.mV[3]; + LLVector4a rscale; + rscale.setMul(radius, scaler[mask]); + + LLVector4a minp, maxp; + minp.setSub(center, rscale); + maxp.setAdd(center, rscale); + + if (n.dot3(minp) > -d) { - result = 1; + return 0; } - } - else*/ - { - for (U32 i = 0; i < mPlaneCount; i++) + + if (n.dot3(maxp) > -d) { - mask = mAgentPlanes[i].mask; - if (mask == 0xff) - { - continue; - } - LLPlane p = mAgentPlanes[i].p; - LLVector3 n = LLVector3(p); - float d = p.mV[3]; - LLVector3 rscale = radius.scaledVec(scaler[mask]); - - LLVector3 minp = center - rscale; - LLVector3 maxp = center + rscale; - - if (n * minp > -d) - { - return 0; - } - - if (n * maxp > -d) - { - result = 1; - } + result = 1; } } - return result; } -S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& radius) -{ - static const LLVector3 scaler[] = { - LLVector3(-1,-1,-1), - LLVector3( 1,-1,-1), - LLVector3(-1, 1,-1), - LLVector3( 1, 1,-1), - LLVector3(-1,-1, 1), - LLVector3( 1,-1, 1), - LLVector3(-1, 1, 1), - LLVector3( 1, 1, 1) + +S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius) +{ + static const LLVector4a scaler[] = { + LLVector4a(-1,-1,-1), + LLVector4a( 1,-1,-1), + LLVector4a(-1, 1,-1), + LLVector4a( 1, 1,-1), + LLVector4a(-1,-1, 1), + LLVector4a( 1,-1, 1), + LLVector4a(-1, 1, 1), + LLVector4a( 1, 1, 1) }; U8 mask = 0; @@ -299,25 +254,28 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& r continue; } - mask = mAgentPlanes[i].mask; + mask = mPlaneMask[i]; if (mask == 0xff) { continue; } - LLPlane p = mAgentPlanes[i].p; - LLVector3 n = LLVector3(p); + + const LLPlane& p = mAgentPlanes[i]; + const LLVector4a& n = reinterpret_cast(p); float d = p.mV[3]; - LLVector3 rscale = radius.scaledVec(scaler[mask]); + LLVector4a rscale; + rscale.setMul(radius, scaler[mask]); - LLVector3 minp = center - rscale; - LLVector3 maxp = center + rscale; + LLVector4a minp, maxp; + minp.setSub(center, rscale); + maxp.setAdd(center, rscale); - if (n * minp > -d) + if (n.dot3(minp) > -d) { return 0; } - if (n * maxp > -d) + if (n.dot3(maxp) > -d) { result = 1; } @@ -447,12 +405,12 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) int res = 2; for (int i = 0; i < 6; i++) { - if (mAgentPlanes[i].mask == 0xff) + if (mPlaneMask[i] == 0xff) { continue; } - float d = mAgentPlanes[i].p.dist(sphere_center); + float d = mAgentPlanes[i].dist(sphere_center); if (d > radius) { @@ -644,12 +602,14 @@ void LLCamera::ignoreAgentFrustumPlane(S32 idx) return; } - mAgentPlanes[idx].mask = 0xff; - mAgentPlanes[idx].p.clearVec(); + mPlaneMask[idx] = 0xff; + mAgentPlanes[idx].clearVec(); } void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) { + alignPlanes(); + for (int i = 0; i < 8; i++) { mAgentFrustum[i] = frust[i]; @@ -662,27 +622,27 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) //order of planes is important, keep most likely to fail in the front of the list //near - frust[0], frust[1], frust[2] - mAgentPlanes[2].p = planeFromPoints(frust[0], frust[1], frust[2]); + mAgentPlanes[2] = planeFromPoints(frust[0], frust[1], frust[2]); //far - mAgentPlanes[5].p = planeFromPoints(frust[5], frust[4], frust[6]); + mAgentPlanes[5] = planeFromPoints(frust[5], frust[4], frust[6]); //left - mAgentPlanes[0].p = planeFromPoints(frust[4], frust[0], frust[7]); + mAgentPlanes[0] = planeFromPoints(frust[4], frust[0], frust[7]); //right - mAgentPlanes[1].p = planeFromPoints(frust[1], frust[5], frust[6]); + mAgentPlanes[1] = planeFromPoints(frust[1], frust[5], frust[6]); //top - mAgentPlanes[4].p = planeFromPoints(frust[3], frust[2], frust[6]); + mAgentPlanes[4] = planeFromPoints(frust[3], frust[2], frust[6]); //bottom - mAgentPlanes[3].p = planeFromPoints(frust[1], frust[0], frust[4]); + mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]); //cache plane octant facing mask for use in AABBInFrustum for (U32 i = 0; i < mPlaneCount; i++) { - mAgentPlanes[i].mask = calcPlaneMask(mAgentPlanes[i].p); + mPlaneMask[i] = calcPlaneMask(mAgentPlanes[i]); } } diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index d6c5f7bbb1..c40e819dcf 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -37,6 +37,7 @@ #include "llmath.h" #include "llcoordframe.h" #include "llplane.h" +#include "llvector4a.h" const F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD; const F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f; @@ -79,6 +80,14 @@ class LLCamera : public LLCoordFrame { public: + + LLCamera(const LLCamera& rhs) + { + *this = rhs; + } + + const LLCamera& operator=(const LLCamera& rhs); + enum { PLANE_LEFT = 0, PLANE_RIGHT = 1, @@ -129,13 +138,9 @@ private: LLPlane mWorldPlanes[PLANE_NUM]; LLPlane mHorizPlanes[HORIZ_PLANE_NUM]; - struct frustum_plane - { - frustum_plane() : mask(0) {} - LLPlane p; - U8 mask; - }; - frustum_plane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + LLPlane* mAgentPlanes; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + U8 mAgentPlaneBuffer[sizeof(LLPlane)*8]; + U8 mPlaneMask[7]; U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in @@ -143,12 +148,14 @@ private: public: LLVector3 mAgentFrustum[8]; //8 corners of 6-plane frustum F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane - LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx].p; } + LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx]; } public: LLCamera(); LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane); - virtual ~LLCamera(){} // no-op virtual destructor + virtual ~LLCamera(); + + void alignPlanes(); void setUserClipPlane(LLPlane plane); void disableUserClipPlane(); @@ -199,8 +206,8 @@ public: S32 sphereInFrustum(const LLVector3 ¢er, const F32 radius) const; S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); } S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); } - S32 AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius); - S32 AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& radius); + S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius); + S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius); //does a quick 'n dirty sphere-sphere check S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius); diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 8bba12783f..ae2259dba0 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -35,6 +35,7 @@ #include "lltreenode.h" #include "v3math.h" +#include "llvector4a.h" #include #include @@ -44,7 +45,7 @@ #define OCT_ERRS LL_WARNS("OctreeErrors") #endif -#define LL_OCTREE_PARANOIA_CHECK 0 +#define LL_OCTREE_PARANOIA_CHECK 1 #if LL_DARWIN #define LL_OCTREE_MAX_CAPACITY 32 #else @@ -94,23 +95,22 @@ public: typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; - static const U8 OCTANT_POSITIVE_X = 0x01; - static const U8 OCTANT_POSITIVE_Y = 0x02; - static const U8 OCTANT_POSITIVE_Z = 0x04; - - LLOctreeNode( LLVector3d center, - LLVector3d size, + LLOctreeNode( const LLVector4a& center, + const LLVector4a& size, BaseType* parent, - U8 octant = 255) + S32 octant = -1) : mParent((oct_node*)parent), - mCenter(center), - mSize(size), mOctant(octant) { + mD = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*4, 16); + + mD[CENTER] = center; + mD[SIZE] = size; + updateMinMax(); - if ((mOctant == 255) && mParent) + if ((mOctant == -1) && mParent) { - mOctant = ((oct_node*) mParent)->getOctant(mCenter.mdV); + mOctant = ((oct_node*) mParent)->getOctant(mD[CENTER]); } clearChildren(); @@ -124,43 +124,30 @@ public: { delete getChild(i); } + + _mm_free(mD); } inline const BaseType* getParent() const { return mParent; } - inline void setParent(BaseType* parent) { mParent = (oct_node*) parent; } - inline const LLVector3d& getCenter() const { return mCenter; } - inline const LLVector3d& getSize() const { return mSize; } - inline void setCenter(LLVector3d center) { mCenter = center; } - inline void setSize(LLVector3d size) { mSize = size; } - inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } - inline U8 getOctant() const { return mOctant; } - inline void setOctant(U8 octant) { mOctant = octant; } + inline void setParent(BaseType* parent) { mParent = (oct_node*) parent; } + inline const LLVector4a& getCenter() const { return mD[CENTER]; } + inline const LLVector4a& getSize() const { return mD[SIZE]; } + inline void setCenter(const LLVector4a& center) { mD[CENTER] = center; } + inline void setSize(const LLVector4a& size) { mD[SIZE] = size; } + inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } + inline S32 getOctant() const { return mOctant; } + inline void setOctant(S32 octant) { mOctant = octant; } inline const oct_node* getOctParent() const { return (const oct_node*) getParent(); } inline oct_node* getOctParent() { return (oct_node*) getParent(); } - U8 getOctant(const F64 pos[]) const //get the octant pos is in + S32 getOctant(const LLVector4a& pos) const //get the octant pos is in { - U8 ret = 0; - - if (pos[0] > mCenter.mdV[0]) - { - ret |= OCTANT_POSITIVE_X; - } - if (pos[1] > mCenter.mdV[1]) - { - ret |= OCTANT_POSITIVE_Y; - } - if (pos[2] > mCenter.mdV[2]) - { - ret |= OCTANT_POSITIVE_Z; - } - - return ret; + return pos.greaterThan4(mD[CENTER]).getComparisonMask() & 0x7; } - inline bool isInside(const LLVector3d& pos, const F64& rad) const + inline bool isInside(const LLVector4a& pos, const F32& rad) const { - return rad <= mSize.mdV[0]*2.0 && isInside(pos); + return rad <= mD[SIZE][0]*2.f && isInside(pos); } inline bool isInside(T* data) const @@ -168,29 +155,27 @@ public: return isInside(data->getPositionGroup(), data->getBinRadius()); } - bool isInside(const LLVector3d& pos) const + bool isInside(const LLVector4a& pos) const { - const F64& x = pos.mdV[0]; - const F64& y = pos.mdV[1]; - const F64& z = pos.mdV[2]; - - if (x > mMax.mdV[0] || x <= mMin.mdV[0] || - y > mMax.mdV[1] || y <= mMin.mdV[1] || - z > mMax.mdV[2] || z <= mMin.mdV[2]) + S32 gt = pos.greaterThan4(mD[MAX]).getComparisonMask() & 0x7; + if (gt) { return false; } - + + S32 lt = pos.lessEqual4(mD[MIN]).getComparisonMask() & 0x7; + if (lt) + { + return false; + } + return true; } void updateMinMax() { - for (U32 i = 0; i < 3; i++) - { - mMax.mdV[i] = mCenter.mdV[i] + mSize.mdV[i]; - mMin.mdV[i] = mCenter.mdV[i] - mSize.mdV[i]; - } + mD[MAX].setAdd(mD[CENTER], mD[SIZE]); + mD[MIN].setSub(mD[CENTER], mD[SIZE]); } inline oct_listener* getOctListener(U32 index) @@ -203,34 +188,34 @@ public: return contains(xform->getBinRadius()); } - bool contains(F64 radius) + bool contains(F32 radius) { if (mParent == NULL) { //root node contains nothing return false; } - F64 size = mSize.mdV[0]; - F64 p_size = size * 2.0; + F32 size = mD[SIZE][0]; + F32 p_size = size * 2.f; - return (radius <= 0.001 && size <= 0.001) || + return (radius <= 0.001f && size <= 0.001f) || (radius <= p_size && radius > size); } - static void pushCenter(LLVector3d ¢er, const LLVector3d &size, const T* data) + static void pushCenter(LLVector4a ¢er, const LLVector4a &size, const T* data) { - const LLVector3d& pos = data->getPositionGroup(); - for (U32 i = 0; i < 3; i++) - { - if (pos.mdV[i] > center.mdV[i]) - { - center.mdV[i] += size.mdV[i]; - } - else - { - center.mdV[i] -= size.mdV[i]; - } - } + const LLVector4a& pos = data->getPositionGroup(); + + LLVector4a gt = pos.greaterThan4(center); + + LLVector4a up; + up.mQ = _mm_and_ps(size.mQ, gt.mQ); + + LLVector4a down; + down.mQ = _mm_andnot_ps(gt.mQ, size.mQ); + + center.add(up); + center.sub(down); } void accept(oct_traveler* visitor) { visitor->visit(this); } @@ -249,21 +234,21 @@ public: void accept(tree_traveler* visitor) const { visitor->visit(this); } void accept(oct_traveler* visitor) const { visitor->visit(this); } - oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) + oct_node* getNodeAt(const LLVector4a& pos, const F32& rad) { LLOctreeNode* node = this; if (node->isInside(pos, rad)) { //do a quick search by octant - U8 octant = node->getOctant(pos.mdV); + S32 octant = node->getOctant(pos); BOOL keep_going = TRUE; //traverse the tree until we find a node that has no node //at the appropriate octant or is smaller than the object. //by definition, that node is the smallest node that contains // the data - while (keep_going && node->getSize().mdV[0] >= rad) + while (keep_going && node->getSize()[0] >= rad) { keep_going = FALSE; for (U32 i = 0; i < node->getChildCount() && !keep_going; i++) @@ -271,7 +256,7 @@ public: if (node->getChild(i)->getOctant() == octant) { node = node->getChild(i); - octant = node->getOctant(pos.mdV); + octant = node->getOctant(pos); keep_going = TRUE; } } @@ -289,7 +274,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* parent = getOctParent(); @@ -299,7 +284,7 @@ public: { if (getElementCount() < LL_OCTREE_MAX_CAPACITY && (contains(data->getBinRadius()) || - (data->getBinRadius() > getSize().mdV[0] && + (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) { //it belongs here #if LL_OCTREE_PARANOIA_CHECK @@ -330,16 +315,22 @@ public: } //it's here, but no kids are in the right place, make a new kid - LLVector3d center(getCenter()); - LLVector3d size(getSize()*0.5); + LLVector4a center = getCenter(); + LLVector4a size = getSize(); + size.mul(0.5f); //push center in direction of data LLOctreeNode::pushCenter(center, size, data); // handle case where floating point number gets too small - if( llabs(center.mdV[0] - getCenter().mdV[0]) < F_APPROXIMATELY_ZERO && - llabs(center.mdV[1] - getCenter().mdV[1]) < F_APPROXIMATELY_ZERO && - llabs(center.mdV[2] - getCenter().mdV[2]) < F_APPROXIMATELY_ZERO) + LLVector4a val; + val.setSub(center, getCenter()); + val.setAbs(val); + LLVector4a app_zero; + app_zero.mQ = F_APPROXIMATELY_ZERO_4A; + S32 lt = val.lessThan4(app_zero).getComparisonMask() & 0x7; + + if( lt == 0x7 ) { mData.insert(data); BaseType::insert(data); @@ -357,7 +348,7 @@ public: //make sure no existing node matches this position for (U32 i = 0; i < getChildCount(); i++) { - if (mChild[i]->getCenter() == center) + if (mChild[i]->getCenter().equal3(center)) { OCT_ERRS << "Octree detected duplicate child center and gave up." << llendl; return false; @@ -375,7 +366,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; @@ -482,13 +473,19 @@ public: void addChild(oct_node* child, BOOL silent = FALSE) { #if LL_OCTREE_PARANOIA_CHECK + + if (child->getSize().equal3(getSize())) + { + OCT_ERRS << "Child size is same as parent size!" << llendl; + } + for (U32 i = 0; i < getChildCount(); i++) { - if(mChild[i]->getSize() != child->getSize()) + if(!mChild[i]->getSize().equal3(child->getSize())) { OCT_ERRS <<"Invalid octree child size." << llendl; } - if (mChild[i]->getCenter() == child->getCenter()) + if (mChild[i]->getCenter().equal3(child->getCenter())) { OCT_ERRS <<"Duplicate octree child position." << llendl; } @@ -513,7 +510,7 @@ public: } } - void removeChild(U8 index, BOOL destroy = FALSE) + void removeChild(S32 index, BOOL destroy = FALSE) { for (U32 i = 0; i < this->getListenerCount(); i++) { @@ -554,18 +551,26 @@ public: } } - //OCT_ERRS << "Octree failed to delete requested child." << llendl; + OCT_ERRS << "Octree failed to delete requested child." << llendl; } protected: + typedef enum + { + CENTER = 0, + SIZE = 1, + MAX = 2, + MIN = 3 + } eDName; + + LLVector4a* mD; + + oct_node* mParent; + S32 mOctant; + child_list mChild; element_list mData; - oct_node* mParent; - LLVector3d mCenter; - LLVector3d mSize; - LLVector3d mMax; - LLVector3d mMin; - U8 mOctant; + }; //just like a regular node, except it might expand on insert and compress on balance @@ -576,9 +581,9 @@ public: typedef LLOctreeNode BaseType; typedef LLOctreeNode oct_node; - LLOctreeRoot( LLVector3d center, - LLVector3d size, - BaseType* parent) + LLOctreeRoot(const LLVector4a& center, + const LLVector4a& size, + BaseType* parent) : BaseType(center, size, parent) { } @@ -619,28 +624,33 @@ 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; } - const F64 MAX_MAG = 1024.0*1024.0; + LLVector4a MAX_MAG; + MAX_MAG.splat(1024.f*1024.f); + + const LLVector4a& v = data->getPositionGroup(); + + LLVector4a val; + val.setSub(v, mD[CENTER]); + val.setAbs(val); + S32 lt = val.lessThan4(MAX_MAG).getComparisonMask() & 0x7; - const LLVector3d& v = data->getPositionGroup(); - if (!(fabs(v.mdV[0]-this->mCenter.mdV[0]) < MAX_MAG && - fabs(v.mdV[1]-this->mCenter.mdV[1]) < MAX_MAG && - fabs(v.mdV[2]-this->mCenter.mdV[2]) < MAX_MAG)) + if (lt != 0x7) { - //OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl; + OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl; return false; } - if (this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup())) + if (this->getSize()[0] > data->getBinRadius() && isInside(data->getPositionGroup())) { //we got it, just act like a branch oct_node* node = getNodeAt(data); @@ -656,31 +666,34 @@ public: else if (this->getChildCount() == 0) { //first object being added, just wrap it up - while (!(this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) + while (!(this->getSize()[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) { - LLVector3d center, size; + LLVector4a center, size; center = this->getCenter(); size = this->getSize(); LLOctreeNode::pushCenter(center, size, data); this->setCenter(center); - this->setSize(size*2); + size.mul(2.f); + this->setSize(size); this->updateMinMax(); } LLOctreeNode::insert(data); } else { - while (!(this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) + while (!(this->getSize()[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) { //the data is outside the root node, we need to grow - LLVector3d center(this->getCenter()); - LLVector3d size(this->getSize()); + LLVector4a center(this->getCenter()); + LLVector4a size(this->getSize()); //expand this node - LLVector3d newcenter(center); + LLVector4a newcenter(center); LLOctreeNode::pushCenter(newcenter, size, data); this->setCenter(newcenter); - this->setSize(size*2); + LLVector4a size2 = size; + size2.mul(2.f); + this->setSize(size2); this->updateMinMax(); //copy our children to a new branch diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c4172de651..72833c019f 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -295,7 +295,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } } -class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst +class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst { public: const LLVolumeFace* mFace; @@ -305,7 +305,7 @@ public: mFace = face; } - virtual void visit(const LLOctreeNode* branch) + virtual void visit(const LLOctreeNode* branch) { LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -314,12 +314,12 @@ public: if (branch->getElementCount() != 0) { - const LLVolumeFace::Triangle* tri = *(branch->getData().begin()); + const LLVolumeTriangle* tri = *(branch->getData().begin()); min = *(tri->mV[0]); max = *(tri->mV[0]); - for (LLOctreeNode::const_element_iter iter = + for (LLOctreeNode::const_element_iter iter = branch->getData().begin(); iter != branch->getData().end(); ++iter) { //stretch by triangles in node @@ -4394,7 +4394,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en LLVector4a box_size; box_size.setSub(face.mExtents[1], face.mExtents[0]); - if (LLLineSegmentBoxIntersect(start.getF32(), end.getF32(), box_center.getF32(), box_size.getF32())) + if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) { if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them { @@ -5418,12 +5418,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff) void LLVolumeFace::createOctree() { - mOctree = new LLOctreeRoot(LLVector3d(0,0,0), LLVector3d(1,1,1), NULL); + LLVector4a center; + LLVector4a size; + center.splat(0.f); + size.splat(1.f); + + mOctree = new LLOctreeRoot(center, size, NULL); new LLVolumeOctreeListener(mOctree); for (U32 i = 0; i < mNumIndices; i+= 3) { - Triangle* tri = new Triangle(); + LLPointer tri = new LLVolumeTriangle(); const LLVector4a& v0 = mPositions[mIndices[i]]; const LLVector4a& v1 = mPositions[mIndices[i+1]]; @@ -5449,8 +5454,7 @@ void LLVolumeFace::createOctree() center.setAdd(min, max); center.mul(0.5f); - - tri->mPositionGroup.setVec(center[0], center[1], center[2]); + *tri->mPositionGroup = center; LLVector4a size; size.setSub(max,min); @@ -5464,15 +5468,6 @@ void LLVolumeFace::createOctree() rebound.traverse(mOctree); } -const LLVector3d& LLVolumeFace::Triangle::getPositionGroup() const -{ - return mPositionGroup; -} - -const F64& LLVolumeFace::Triangle::getBinRadius() const -{ - return mRadius; -} void LLVolumeFace::swapData(LLVolumeFace& rhs) { diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 0ae8aa19ca..c49d1c650d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -46,6 +46,7 @@ template class LLOctreeNode; class LLVector4a; class LLVolumeFace; class LLVolume; +class LLVolumeTriangle; #include "lldarray.h" #include "lluuid.h" @@ -918,20 +919,7 @@ public: // mWeights.size() should be empty or match mVertices.size() LLVector4a* mWeights; - class Triangle : public LLRefCount - { - public: - const LLVector4a* mV[3]; - U16 mIndex[3]; - - LLVector3d mPositionGroup; - F64 mRadius; - - virtual const LLVector3d& getPositionGroup() const; - virtual const F64& getBinRadius() const; - }; - - LLOctreeNode* mOctree; + LLOctreeNode* mOctree; private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); -- cgit v1.2.3 From 7db6a5a64d8eacb63b45dc7cc48bdd681f3e19af Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 4 Jun 2010 00:10:05 -0500 Subject: Disable octree paranoia checks. --- indra/llmath/lloctree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index ae2259dba0..f61ce6ce05 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -45,7 +45,7 @@ #define OCT_ERRS LL_WARNS("OctreeErrors") #endif -#define LL_OCTREE_PARANOIA_CHECK 1 +#define LL_OCTREE_PARANOIA_CHECK 0 #if LL_DARWIN #define LL_OCTREE_MAX_CAPACITY 32 #else -- cgit v1.2.3 From 087b7499082c7f0ae867990a102bc8f90a83471d Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Fri, 4 Jun 2010 08:46:00 +0100 Subject: fix scoping issues for gcc --- indra/llmath/lloctree.h | 2 +- indra/llmath/llvolume.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index f61ce6ce05..df77971204 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -640,7 +640,7 @@ public: const LLVector4a& v = data->getPositionGroup(); LLVector4a val; - val.setSub(v, mD[CENTER]); + val.setSub(v, BaseType::mD[BaseType::CENTER]); val.setAbs(val); S32 lt = val.lessThan4(MAX_MAG).getComparisonMask() & 0x7; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 72833c019f..ef1ab57036 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4406,7 +4406,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en face.createOctree(); } - LLVector4a* p = (LLVector4a*) face.mPositions; + //LLVector4a* p = (LLVector4a*) face.mPositions; LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); intersect.traverse(face.mOctree); -- cgit v1.2.3 From dc2f50642bf6c785263d91ca53ec337f3898b990 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Fri, 4 Jun 2010 08:54:03 +0100 Subject: lots of _mm_malloc and _mm_free -> ll_aligned_malloc_16 and ll_aligned_free_16 more to come. --- indra/llmath/lloctree.h | 4 +-- indra/llmath/llvolume.cpp | 86 +++++++++++++++++++++++------------------------ 2 files changed, 45 insertions(+), 45 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index df77971204..59828ae565 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -102,7 +102,7 @@ public: : mParent((oct_node*)parent), mOctant(octant) { - mD = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*4, 16); + mD = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*4); mD[CENTER] = center; mD[SIZE] = size; @@ -125,7 +125,7 @@ public: delete getChild(i); } - _mm_free(mD); + ll_aligned_free_16(mD); } inline const BaseType* getParent() const { return mParent; } diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ef1ab57036..a8684759f3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1987,7 +1987,7 @@ BOOL LLVolume::generate() void LLVolumeFace::VertexData::init() { - mData = (LLVector4a*) _mm_malloc(32, 16); + mData = (LLVector4a*) ll_aligned_malloc_16(32); } LLVolumeFace::VertexData::VertexData() @@ -2004,7 +2004,7 @@ LLVolumeFace::VertexData::VertexData(const VertexData& rhs) LLVolumeFace::VertexData::~VertexData() { - _mm_free(mData); + ll_aligned_free_16(mData); } LLVector4a& LLVolumeFace::VertexData::getPosition() @@ -5196,7 +5196,7 @@ LLVolumeFace::LLVolumeFace() : mWeights(NULL), mOctree(NULL) { - mExtents = (LLVector4a*) _mm_malloc(48, 16); + mExtents = (LLVector4a*) ll_aligned_malloc_16(48); mCenter = mExtents+2; } @@ -5217,7 +5217,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mWeights(NULL), mOctree(NULL) { - mExtents = (LLVector4a*) _mm_malloc(48, 16); + mExtents = (LLVector4a*) ll_aligned_malloc_16(48); mCenter = mExtents+2; *this = src; } @@ -5264,7 +5264,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } else { - _mm_free(mBinormals); + ll_aligned_free_16(mBinormals); mBinormals = NULL; } @@ -5275,7 +5275,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } else { - _mm_free(mWeights); + ll_aligned_free_16(mWeights); mWeights = NULL; } } @@ -5295,7 +5295,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVolumeFace::~LLVolumeFace() { - _mm_free(mExtents); + ll_aligned_free_16(mExtents); mExtents = NULL; freeData(); @@ -5303,17 +5303,17 @@ LLVolumeFace::~LLVolumeFace() void LLVolumeFace::freeData() { - _mm_free(mPositions); + ll_aligned_free_16(mPositions); mPositions = NULL; - _mm_free(mNormals); + ll_aligned_free_16(mNormals); mNormals = NULL; - _mm_free(mTexCoords); + ll_aligned_free_16(mTexCoords); mTexCoords = NULL; - _mm_free(mIndices); + ll_aligned_free_16(mIndices); mIndices = NULL; - _mm_free(mBinormals); + ll_aligned_free_16(mBinormals); mBinormals = NULL; - _mm_free(mWeights); + ll_aligned_free_16(mWeights); mWeights = NULL; delete mOctree; @@ -6082,21 +6082,21 @@ void LLVolumeFace::createBinormals() void LLVolumeFace::resizeVertices(S32 num_verts) { - _mm_free(mPositions); - _mm_free(mNormals); - _mm_free(mBinormals); - _mm_free(mTexCoords); + ll_aligned_free_16(mPositions); + ll_aligned_free_16(mNormals); + ll_aligned_free_16(mBinormals); + ll_aligned_free_16(mTexCoords); mBinormals = NULL; if (num_verts) { - mPositions = (LLVector4a*) _mm_malloc(num_verts*16, 16); - mNormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); + mPositions = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); + mNormals = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); //pad texture coordinate block end to allow for QWORD reads S32 size = ((num_verts*8) + 0xF) & ~0xF; - mTexCoords = (LLVector2*) _mm_malloc(size, 16); + mTexCoords = (LLVector2*) ll_aligned_malloc_16(size); } else { @@ -6119,20 +6119,20 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con S32 new_size = new_verts*16; //positions - LLVector4a* dst = (LLVector4a*) _mm_malloc(new_size, 16); + LLVector4a* dst = (LLVector4a*) ll_aligned_malloc_16(new_size); if (mPositions) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mPositions, new_size/4); - _mm_free(mPositions); + ll_aligned_free_16(mPositions); } mPositions = dst; //normals - dst = (LLVector4a*) _mm_malloc(new_size, 16); + dst = (LLVector4a*) ll_aligned_malloc_16(new_size); if (mNormals) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mNormals, new_size/4); - _mm_free(mNormals); + ll_aligned_free_16(mNormals); } mNormals = dst; @@ -6140,16 +6140,16 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con new_size = ((new_verts*8)+0xF) & ~0xF; { - LLVector2* dst = (LLVector2*) _mm_malloc(new_size, 16); + LLVector2* dst = (LLVector2*) ll_aligned_malloc_16(new_size); if (mTexCoords) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mTexCoords, new_size/4); - _mm_free(mTexCoords); + ll_aligned_free_16(mTexCoords); } } //just clear binormals - _mm_free(mBinormals); + ll_aligned_free_16(mBinormals); mBinormals = NULL; mPositions[mNumVertices] = pos; @@ -6161,26 +6161,26 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con void LLVolumeFace::allocateBinormals(S32 num_verts) { - _mm_free(mBinormals); - mBinormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); + ll_aligned_free_16(mBinormals); + mBinormals = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); } void LLVolumeFace::allocateWeights(S32 num_verts) { - _mm_free(mWeights); - mWeights = (LLVector4a*) _mm_malloc(num_verts*16, 16); + ll_aligned_free_16(mWeights); + mWeights = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); } void LLVolumeFace::resizeIndices(S32 num_indices) { - _mm_free(mIndices); + ll_aligned_free_16(mIndices); if (num_indices) { //pad index block end to allow for QWORD reads S32 size = ((num_indices*2) + 0xF) & ~0xF; - mIndices = (U16*) _mm_malloc(size,16); + mIndices = (U16*) ll_aligned_malloc_16(size); } else { @@ -6198,9 +6198,9 @@ void LLVolumeFace::pushIndex(const U16& idx) S32 old_size = (mNumIndices+0xF) & ~0xF; if (new_size != old_size) { - U16* dst = (U16*) _mm_malloc(new_size, 16); + U16* dst = (U16*) ll_aligned_malloc_16(new_size); LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mIndices, new_size/4); - _mm_free(mIndices); + ll_aligned_free_16(mIndices); mIndices = dst; } @@ -6237,17 +6237,17 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } - LLVector4a* new_pos = (LLVector4a*) _mm_malloc(new_count*16, 16); - LLVector4a* new_norm = (LLVector4a*) _mm_malloc(new_count*16, 16); - LLVector2* new_tc = (LLVector2*) _mm_malloc((new_count*8+0xF) & ~0xF, 16); + LLVector4a* new_pos = (LLVector4a*) ll_aligned_malloc_16(new_count*16); + LLVector4a* new_norm = (LLVector4a*) ll_aligned_malloc_16(new_count*16); + LLVector2* new_tc = (LLVector2*) ll_aligned_malloc_16((new_count*8+0xF) & ~0xF); LLVector4a::memcpyNonAliased16((F32*) new_pos, (F32*) mPositions, new_count*4); LLVector4a::memcpyNonAliased16((F32*) new_norm, (F32*) mNormals, new_count*4); LLVector4a::memcpyNonAliased16((F32*) new_tc, (F32*) mTexCoords, new_count*2); - _mm_free(mPositions); - _mm_free(mNormals); - _mm_free(mTexCoords); + ll_aligned_free_16(mPositions); + ll_aligned_free_16(mNormals); + ll_aligned_free_16(mTexCoords); mPositions = new_pos; mNormals = new_norm; @@ -6287,9 +6287,9 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat new_count = mNumIndices + face.mNumIndices; - U16* new_indices = (U16*) _mm_malloc((new_count*2+0xF) & ~0xF, 16); + U16* new_indices = (U16*) ll_aligned_malloc_16((new_count*2+0xF) & ~0xF); LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, new_count/2); - _mm_free(mIndices); + ll_aligned_free_16(mIndices); mIndices = new_indices; mNumIndices = new_count; -- cgit v1.2.3 From 6ca40c7afbd794b161904b63b88a95273ae80c9c Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Fri, 4 Jun 2010 09:10:00 +0100 Subject: more needed #includes --- indra/llmath/llvolume.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index a8684759f3..ce7e20e9b4 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -31,6 +31,7 @@ */ #include "linden_common.h" +#include "llmemory.h" #include "llmath.h" #include -- cgit v1.2.3 From a8f0e47fd5deee1e45b4126ee43955a7bc68bb5d Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 4 Jun 2010 12:07:55 -0500 Subject: Normal debug display and fix for bad bump mapping and planar texture coordinates. --- indra/llmath/llvolume.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 72833c019f..8cb9475994 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6076,6 +6076,8 @@ void LLVolumeFace::createBinormals() for (U32 i = 0; i < mNumVertices; i++) { binorm[i].normalize3fast(); + //bump map/planar projection code requires normals to be normalized + mNormals[i].normalize3fast(); } } } -- cgit v1.2.3 From f9b13d8f8510b1f7f02fcf92685471461b79858e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Jun 2010 00:45:48 -0500 Subject: Add "LL_MESH_ENABLED" preprocessor flag for toggling mesh code. Couple of merge fixes. --- indra/llmath/llvolume.cpp | 13 ++++++++----- indra/llmath/llvolume.h | 7 +++++++ 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 09ab47b890..05868e3517 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2546,10 +2546,12 @@ S32 LLVolume::getNumFaces() const { U8 sculpt_type = (mParams.getSculptType() & LL_SCULPT_TYPE_MASK); +#if LL_MESH_ENABLED if (sculpt_type == LL_SCULPT_TYPE_MESH) { return LL_SCULPT_MESH_MAX_FACES; } +#endif return (S32)mProfilep->mFaces.size(); } @@ -2922,11 +2924,6 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, LLMemType m1(LLMemType::MTYPE_VOLUME); U8 sculpt_type = mParams.getSculptType(); - if (sculpt_type & LL_SCULPT_TYPE_MASK == LL_SCULPT_TYPE_MESH) - { - llerrs << "WTF?" << llendl; - } - BOOL data_is_empty = FALSE; if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL) @@ -4135,10 +4132,12 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, normals.clear(); segments.clear(); +#if LL_MESH_ENABLED if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { return; } +#endif S32 cur_index = 0; //for each face @@ -6335,10 +6334,14 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) resizeVertices(num_vertices); resizeIndices(num_indices); +#if LL_MESH_ENABLED if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { mEdge.resize(num_indices); } +#else + mEdge.resize(num_indices); +#endif } LLVector4a* pos = (LLVector4a*) mPositions; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c49d1c650d..0782944079 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -41,6 +41,8 @@ class LLVolumeParams; class LLProfile; class LLPath; +#define LL_MESH_ENABLED 0 + template class LLOctreeNode; class LLVector4a; @@ -190,10 +192,15 @@ 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; +#if LL_MESH_ENABLED 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; +#else +const U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE | + LL_SCULPT_TYPE_CYLINDER; +#endif const U8 LL_SCULPT_FLAG_INVERT = 64; const U8 LL_SCULPT_FLAG_MIRROR = 128; -- cgit v1.2.3 From 9440f84dca48e3e2f6022dbf5f916d6439c7a826 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Jun 2010 14:58:02 -0500 Subject: Potential fix for busted binormals on cubes. --- indra/llmath/llvolume.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 05868e3517..ba5d5e7ca1 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5566,6 +5566,8 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) corners[0].getPosition(), corners[0].mTexCoord, corners[1].getPosition(), corners[1].mTexCoord, corners[2].getPosition(), corners[2].mTexCoord); + + binormal.normalize3fast(); S32 size = (grid_size+1)*(grid_size+1); resizeVertices(size); -- cgit v1.2.3 From d2d49e3d84956ec4efb9f1a7a308d530c7fc4737 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Jun 2010 15:02:41 -0500 Subject: Fix for memcpyNonAliased16 issues. --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 09ab47b890..cafa1e5c44 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5255,7 +5255,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); - LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, vert_size); + LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); if (src.mBinormals) -- cgit v1.2.3 From 3ea0018dc6f94c029d7dbf13bdd5b0bc0558c8d8 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Jun 2010 15:07:30 -0500 Subject: Enable meshes. --- indra/llmath/llvolume.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 0782944079..98db7f31c0 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -41,7 +41,7 @@ class LLVolumeParams; class LLProfile; class LLPath; -#define LL_MESH_ENABLED 0 +#define LL_MESH_ENABLED 1 template class LLOctreeNode; -- cgit v1.2.3 From 2ff888d2bc7424e70a836adb8ec4cf27df75ab7b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Jun 2010 21:47:49 -0500 Subject: Unused variable. --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ba5d5e7ca1..ac3ed5d63e 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2544,9 +2544,9 @@ void LLVolume::copyVolumeFaces(LLVolume* volume) S32 LLVolume::getNumFaces() const { +#if LL_MESH_ENABLED U8 sculpt_type = (mParams.getSculptType() & LL_SCULPT_TYPE_MASK); -#if LL_MESH_ENABLED if (sculpt_type == LL_SCULPT_TYPE_MESH) { return LL_SCULPT_MESH_MAX_FACES; -- cgit v1.2.3 From 6e37ec08f678451a526f34218cb070d117cdf60a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 14 Jun 2010 23:13:10 -0500 Subject: Builds with LLConvexDecompInter as a static lib. --- indra/llmath/llvolume.cpp | 8 ++++---- indra/llmath/llvolume.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 10cef533b0..53f484fb79 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5355,9 +5355,9 @@ bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs getNormal().equal3(rhs.getNormal()); } -bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector4a& a, const LLVector4a& b) const +bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a, const LLVector3& b) const { - return a.less3(b); + return a < b; } void LLVolumeFace::optimize(F32 angle_cutoff) @@ -5375,7 +5375,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) getVertexData(index, cv); BOOL found = FALSE; - VertexMapData::PointMap::iterator point_iter = point_map.find(cv.getPosition()); + VertexMapData::PointMap::iterator point_iter = point_map.find(LLVector3(cv.getPosition().getF32())); if (point_iter != point_map.end()) { //duplicate point might exist for (U32 j = 0; j < point_iter->second.size(); ++j) @@ -5407,7 +5407,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) } else { - point_map[d.getPosition()].push_back(d); + point_map[LLVector3(d.getPosition().getF32())].push_back(d); } } } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 98db7f31c0..4aef3be973 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -873,10 +873,10 @@ public: struct ComparePosition { - bool operator()(const LLVector4a& a, const LLVector4a& b) const; + bool operator()(const LLVector3& a, const LLVector3& b) const; }; - typedef std::map, VertexMapData::ComparePosition > PointMap; + typedef std::map, VertexMapData::ComparePosition > PointMap; }; void optimize(F32 angle_cutoff = 2.f); -- cgit v1.2.3 From 66e353812f4732c77206322d271b2346dd74feec Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 15 Jun 2010 19:16:39 -0500 Subject: Get meshes working post-SSE pass. --- indra/llmath/llvolume.cpp | 89 +++++++++++++++++++++++++++-------------------- indra/llmath/llvolume.h | 2 ++ 2 files changed, 54 insertions(+), 37 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 62e488452a..a4022c842d 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1988,19 +1988,33 @@ BOOL LLVolume::generate() void LLVolumeFace::VertexData::init() { - mData = (LLVector4a*) ll_aligned_malloc_16(32); + if (!mData) + { + mData = (LLVector4a*) ll_aligned_malloc_16(32); + } } LLVolumeFace::VertexData::VertexData() { + mData = NULL; init(); } LLVolumeFace::VertexData::VertexData(const VertexData& rhs) { - init(); - LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); - mTexCoord = rhs.mTexCoord; + mData = NULL; + *this = rhs; +} + +const LLVolumeFace::VertexData& LLVolumeFace::VertexData::operator=(const LLVolumeFace::VertexData& rhs) +{ + if (this != &rhs) + { + init(); + LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); + mTexCoord = rhs.mTexCoord; + } + return *this; } LLVolumeFace::VertexData::~VertexData() @@ -2041,34 +2055,29 @@ void LLVolumeFace::VertexData::setNormal(const LLVector4a& norm) bool LLVolumeFace::VertexData::operator<(const LLVolumeFace::VertexData& rhs)const { - const U8* l = (const U8*) this; - const U8* r = (const U8*) &rhs; + if (mData[POSITION].notEqual3(rhs.getPosition())) + { + return mData[POSITION].less3(rhs.getPosition()); + } - for (U32 i = 0; i < sizeof(VertexData); ++i) + if (mData[NORMAL].notEqual3(rhs.getNormal())) { - if (l[i] != r[i]) - { - return r[i] < l[i]; - } + return mData[NORMAL].less3(rhs.getNormal()); } - + + if (mTexCoord != rhs.mTexCoord) + { + return mTexCoord < rhs.mTexCoord; + } + return false; } bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)const { - const U8* l = (const U8*) this; - const U8* r = (const U8*) &rhs; - - for (U32 i = 0; i < sizeof(VertexData); ++i) - { - if (l[i] != r[i]) - { - return false; - } - } - - return true; + return mData[POSITION].equal3(rhs.getPosition()) && + mData[NORMAL].equal3(rhs.getNormal()) && + mTexCoord == rhs.mTexCoord; } bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const @@ -6244,10 +6253,13 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat LLVector4a* new_pos = (LLVector4a*) ll_aligned_malloc_16(new_count*16); LLVector4a* new_norm = (LLVector4a*) ll_aligned_malloc_16(new_count*16); LLVector2* new_tc = (LLVector2*) ll_aligned_malloc_16((new_count*8+0xF) & ~0xF); - - LLVector4a::memcpyNonAliased16((F32*) new_pos, (F32*) mPositions, new_count*4); - LLVector4a::memcpyNonAliased16((F32*) new_norm, (F32*) mNormals, new_count*4); - LLVector4a::memcpyNonAliased16((F32*) new_tc, (F32*) mTexCoords, new_count*2); + + if (mNumVertices > 0) + { + LLVector4a::memcpyNonAliased16((F32*) new_pos, (F32*) mPositions, mNumVertices*4); + LLVector4a::memcpyNonAliased16((F32*) new_norm, (F32*) mNormals, mNumVertices*4); + LLVector4a::memcpyNonAliased16((F32*) new_tc, (F32*) mTexCoords, mNumVertices*2); + } ll_aligned_free_16(mPositions); ll_aligned_free_16(mNormals); @@ -6259,13 +6271,13 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat mNumVertices = new_count; - LLVector4a* dst_pos = (LLVector4a*) mPositions+offset; - LLVector2* dst_tc = (LLVector2*) mTexCoords+offset; - LLVector4a* dst_norm = (LLVector4a*) mNormals+offset; + LLVector4a* dst_pos = mPositions+offset; + LLVector2* dst_tc = mTexCoords+offset; + LLVector4a* dst_norm = mNormals+offset; - LLVector4a* src_pos = (LLVector4a*) face.mPositions; - LLVector2* src_tc = (LLVector2*) face.mTexCoords; - LLVector4a* src_norm = (LLVector4a*) face.mNormals; + const LLVector4a* src_pos = face.mPositions; + const LLVector2* src_tc = face.mTexCoords; + const LLVector4a* src_norm = face.mNormals; LLMatrix4a mat, norm_mat; mat.loadu(mat_in); @@ -6292,13 +6304,16 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat new_count = mNumIndices + face.mNumIndices; U16* new_indices = (U16*) ll_aligned_malloc_16((new_count*2+0xF) & ~0xF); - LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, new_count/2); + if (mNumIndices > 0) + { + LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, llmax(mNumIndices/2, 1)); + } + ll_aligned_free_16(mIndices); mIndices = new_indices; + U16* dst_idx = mIndices+mNumIndices; mNumIndices = new_count; - U16* dst_idx = mIndices+offset; - for (U32 i = 0; i < face.mNumIndices; ++i) { dst_idx[i] = face.mIndices[i]+offset; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 4aef3be973..af28337f57 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -817,6 +817,8 @@ public: public: VertexData(); VertexData(const VertexData& rhs); + const VertexData& operator=(const VertexData& rhs); + ~VertexData(); LLVector4a& getPosition(); LLVector4a& getNormal(); -- cgit v1.2.3 From 6f2bd694d9a21174648b4e4f76d6d078aa88265f Mon Sep 17 00:00:00 2001 From: Matthew Breindel Date: Sat, 26 Jun 2010 12:35:05 -0700 Subject: Fixed mac build (given LL_MESH_ENABLED set to 0). --- indra/llmath/llvolume.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index af28337f57..9cce94e6cf 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -41,7 +41,7 @@ class LLVolumeParams; class LLProfile; class LLPath; -#define LL_MESH_ENABLED 1 +#define LL_MESH_ENABLED 0 template class LLOctreeNode; -- cgit v1.2.3 From 46768c3c6c263ec27a80c854734ce0b61d29686f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 12 Jul 2010 07:39:23 -0500 Subject: Merge? --- indra/llmath/llvolume.cpp | 186 ++++++++++++++++++++++++++++------------------ 1 file changed, 112 insertions(+), 74 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index a4022c842d..38944d3855 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5245,6 +5245,10 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) mNumS = src.mNumS; mNumT = src.mNumT; + mExtents[0] = src.mExtents[0]; + mExtents[1] = src.mExtents[1]; + *mCenter = *src.mCenter; + mNumVertices = 0; mNumIndices = 0; @@ -5297,7 +5301,6 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size); } - //delete return *this; } @@ -5535,88 +5538,100 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) S32 offset = 0; if (mTypeMask & TOP_MASK) + { offset = (max_t-1) * max_s; + } else + { offset = mBeginS; - - VertexData corners[4]; - VertexData baseVert; - for(int t = 0; t < 4; t++){ - corners[t].getPosition().load3( mesh[offset + (grid_size*t)].mPos.mV); - corners[t].mTexCoord.mV[0] = profile[grid_size*t].mV[0]+0.5f; - corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t].mV[1]; } { - LLVector4a lhs; - lhs.setSub(corners[1].getPosition(), corners[0].getPosition()); - LLVector4a rhs; - rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); - baseVert.getNormal().setCross3(lhs, rhs); - baseVert.getNormal().normalize3fast(); - } + VertexData corners[4]; + VertexData baseVert; + for(S32 t = 0; t < 4; t++) + { + corners[t].getPosition().load3( mesh[offset + (grid_size*t)].mPos.mV); + corners[t].mTexCoord.mV[0] = profile[grid_size*t].mV[0]+0.5f; + corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t].mV[1]; + } - if(!(mTypeMask & TOP_MASK)){ - baseVert.getNormal().mul(-1.0f); - }else{ - //Swap the UVs on the U(X) axis for top face - LLVector2 swap; - swap = corners[0].mTexCoord; - corners[0].mTexCoord=corners[3].mTexCoord; - corners[3].mTexCoord=swap; - swap = corners[1].mTexCoord; - corners[1].mTexCoord=corners[2].mTexCoord; - corners[2].mTexCoord=swap; - } + { + LLVector4a lhs; + lhs.setSub(corners[1].getPosition(), corners[0].getPosition()); + LLVector4a rhs; + rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); + baseVert.getNormal().setCross3(lhs, rhs); + baseVert.getNormal().normalize3fast(); + } - LLVector4a binormal; - - calc_binormal_from_triangle( binormal, - corners[0].getPosition(), corners[0].mTexCoord, - corners[1].getPosition(), corners[1].mTexCoord, - corners[2].getPosition(), corners[2].mTexCoord); - - binormal.normalize3fast(); + if(!(mTypeMask & TOP_MASK)) + { + baseVert.getNormal().mul(-1.0f); + } + else + { + //Swap the UVs on the U(X) axis for top face + LLVector2 swap; + swap = corners[0].mTexCoord; + corners[0].mTexCoord=corners[3].mTexCoord; + corners[3].mTexCoord=swap; + swap = corners[1].mTexCoord; + corners[1].mTexCoord=corners[2].mTexCoord; + corners[2].mTexCoord=swap; + } - S32 size = (grid_size+1)*(grid_size+1); - resizeVertices(size); - allocateBinormals(size); + LLVector4a binormal; + + calc_binormal_from_triangle( binormal, + corners[0].getPosition(), corners[0].mTexCoord, + corners[1].getPosition(), corners[1].mTexCoord, + corners[2].getPosition(), corners[2].mTexCoord); + + binormal.normalize3fast(); - LLVector4a* pos = (LLVector4a*) mPositions; - LLVector4a* norm = (LLVector4a*) mNormals; - LLVector4a* binorm = (LLVector4a*) mBinormals; - LLVector2* tc = (LLVector2*) mTexCoords; + S32 size = (grid_size+1)*(grid_size+1); + resizeVertices(size); + allocateBinormals(size); - for(int gx = 0;gxsetAdd(min, max); - mCenter->mul(0.5f); + mCenter->setAdd(min, max); + mCenter->mul(0.5f); + } if (!partial_build) { @@ -6249,73 +6264,96 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat llerrs << "Cannot append face -- 16-bit overflow will occur." << llendl; } - + if (face.mNumVertices == 0) + { + llerrs << "Cannot append empty face." << llendl; + } + + //allocate new buffer space LLVector4a* new_pos = (LLVector4a*) ll_aligned_malloc_16(new_count*16); LLVector4a* new_norm = (LLVector4a*) ll_aligned_malloc_16(new_count*16); LLVector2* new_tc = (LLVector2*) ll_aligned_malloc_16((new_count*8+0xF) & ~0xF); + if (mNumVertices > 0) - { + { //copy old buffers LLVector4a::memcpyNonAliased16((F32*) new_pos, (F32*) mPositions, mNumVertices*4); LLVector4a::memcpyNonAliased16((F32*) new_norm, (F32*) mNormals, mNumVertices*4); LLVector4a::memcpyNonAliased16((F32*) new_tc, (F32*) mTexCoords, mNumVertices*2); } + //free old buffer space ll_aligned_free_16(mPositions); ll_aligned_free_16(mNormals); ll_aligned_free_16(mTexCoords); + //point to new buffers mPositions = new_pos; mNormals = new_norm; mTexCoords = new_tc; mNumVertices = new_count; + //get destination address of appended face LLVector4a* dst_pos = mPositions+offset; LLVector2* dst_tc = mTexCoords+offset; LLVector4a* dst_norm = mNormals+offset; + //get source addresses of appended face const LLVector4a* src_pos = face.mPositions; const LLVector2* src_tc = face.mTexCoords; const LLVector4a* src_norm = face.mNormals; + //load aligned matrices LLMatrix4a mat, norm_mat; mat.loadu(mat_in); norm_mat.loadu(norm_mat_in); for (U32 i = 0; i < face.mNumVertices; ++i) { + //transform appended face position and store mat.affineTransform(src_pos[i], dst_pos[i]); + + //transform appended face normal and store norm_mat.rotate(src_norm[i], dst_norm[i]); dst_norm[i].normalize3fast(); + //copy appended face texture coordinate dst_tc[i] = src_tc[i]; if (offset == 0 && i == 0) - { + { //initialize bounding box mExtents[0] = mExtents[1] = dst_pos[i]; } else { + //stretch bounding box update_min_max(mExtents[0], mExtents[1], dst_pos[i]); } } new_count = mNumIndices + face.mNumIndices; + + //allocate new index buffer U16* new_indices = (U16*) ll_aligned_malloc_16((new_count*2+0xF) & ~0xF); if (mNumIndices > 0) - { - LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, llmax(mNumIndices/2, 1)); + { //copy old index buffer + LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, llmax(mNumIndices/2, 4)); } + //free old index buffer ll_aligned_free_16(mIndices); + + //point to new index buffer mIndices = new_indices; + + //get destination address into new index buffer U16* dst_idx = mIndices+mNumIndices; mNumIndices = new_count; for (U32 i = 0; i < face.mNumIndices; ++i) - { + { //copy indices, offsetting by old vertex count dst_idx[i] = face.mIndices[i]+offset; } } -- cgit v1.2.3 From 2dd3a6be720ed6ce7c17415fc8d81869cf46f3a0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 13 Jul 2010 12:02:14 -0500 Subject: Fix for mesh upload, consolidate generating bad indices, and normal generation. --- indra/llmath/llvolume.cpp | 36 +++++++++++++++++++++++++++--------- indra/llmath/llvolume.h | 2 +- 2 files changed, 28 insertions(+), 10 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 38944d3855..51bcfb38d4 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5369,7 +5369,17 @@ bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a, const LLVector3& b) const { - return a < b; + if (a.mV[0] != b.mV[0]) + { + return a.mV[0] < b.mV[0]; + } + + if (a.mV[1] != b.mV[1]) + { + return a.mV[1] < b.mV[1]; + } + + return a.mV[2] < b.mV[2]; } void LLVolumeFace::optimize(F32 angle_cutoff) @@ -6145,12 +6155,13 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con { S32 new_verts = mNumVertices+1; S32 new_size = new_verts*16; - + S32 old_size = mNumVertices*16; + //positions LLVector4a* dst = (LLVector4a*) ll_aligned_malloc_16(new_size); if (mPositions) { - LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mPositions, new_size/4); + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mPositions, old_size/4); ll_aligned_free_16(mPositions); } mPositions = dst; @@ -6159,22 +6170,25 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con dst = (LLVector4a*) ll_aligned_malloc_16(new_size); if (mNormals) { - LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mNormals, new_size/4); + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mNormals, old_size/4); ll_aligned_free_16(mNormals); } mNormals = dst; //tex coords new_size = ((new_verts*8)+0xF) & ~0xF; + old_size = ((mNumVertices*8)+0xF) & ~0xF; + dst = (LLVector4a*) ll_aligned_malloc_16(new_size); { LLVector2* dst = (LLVector2*) ll_aligned_malloc_16(new_size); if (mTexCoords) { - LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mTexCoords, new_size/4); + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mTexCoords, old_size/4); ll_aligned_free_16(mTexCoords); } } + mTexCoords = (LLVector2*) dst; //just clear binormals ll_aligned_free_16(mBinormals); @@ -6223,12 +6237,15 @@ void LLVolumeFace::pushIndex(const U16& idx) S32 new_count = mNumIndices + 1; S32 new_size = ((new_count*2)+0xF) & ~0xF; - S32 old_size = (mNumIndices+0xF) & ~0xF; + S32 old_size = ((mNumIndices*2)+0xF) & ~0xF; if (new_size != old_size) { U16* dst = (U16*) ll_aligned_malloc_16(new_size); - LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mIndices, new_size/4); - ll_aligned_free_16(mIndices); + if (mIndices) + { + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mIndices, old_size/4); + ll_aligned_free_16(mIndices); + } mIndices = dst; } @@ -6339,7 +6356,8 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat U16* new_indices = (U16*) ll_aligned_malloc_16((new_count*2+0xF) & ~0xF); if (mNumIndices > 0) { //copy old index buffer - LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, llmax(mNumIndices/2, 4)); + S32 old_size = (mNumIndices*2+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, old_size/4); } //free old index buffer diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 9cce94e6cf..af28337f57 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -41,7 +41,7 @@ class LLVolumeParams; class LLProfile; class LLPath; -#define LL_MESH_ENABLED 0 +#define LL_MESH_ENABLED 1 template class LLOctreeNode; -- cgit v1.2.3