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 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 344 insertions(+), 6 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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 { -- 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/llvolume.cpp') 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/llvolume.cpp') 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/llvolume.cpp') 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 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'indra/llmath/llvolume.cpp') 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) { -- 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 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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; -- 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 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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) -- 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/llvolume.cpp') 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/llvolume.cpp') 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/llvolume.cpp') 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 - 1 file changed, 1 deletion(-) (limited to 'indra/llmath/llvolume.cpp') 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 { -- 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 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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); -- 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/llvolume.cpp') 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 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'indra/llmath/llvolume.cpp') 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() //----------------------------------------------------------------------------- -- 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 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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); } -- 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 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 157 insertions(+), 44 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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]); } } -- 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/llvolume.cpp') 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 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'indra/llmath/llvolume.cpp') 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); -- 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 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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); -- 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/llvolume.cpp') 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 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/llvolume.cpp') 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/llvolume.cpp') 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 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/llvolume.cpp') 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 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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, -- 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 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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) -- 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 ++++++++++++++++------------------------------ 1 file changed, 45 insertions(+), 90 deletions(-) (limited to 'indra/llmath/llvolume.cpp') 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"]); -- 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/llvolume.cpp') 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 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/llvolume.cpp') 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/llvolume.cpp') 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