diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index e3cd086f79..57f83dbec2 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -1280,15 +1280,6 @@ LLPolyMesh* LLAvatarAppearance::getHeadMesh() return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh(); } -// Qarl's mesh deformer -//----------------------------------------------------------------------------- -// LLAvatarAppearance::getMesh() -//----------------------------------------------------------------------------- -LLPolyMesh* LLAvatarAppearance::getMesh(S32 which) -{ - return mMeshLOD[which]->mMeshParts[0]->getMesh(); -} -// //----------------------------------------------------------------------------- // LLAvatarAppearance::getUpperBodyMesh() diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 87f7da0428..f554468184 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -95,7 +95,6 @@ public: /*virtual*/ S32 getCollisionVolumeID(std::string &name); /*virtual*/ LLPolyMesh* getHeadMesh(); /*virtual*/ LLPolyMesh* getUpperBodyMesh(); - /*virtual*/ LLPolyMesh* getMesh(S32 which); // Qarl's mesh deformer /** Inherited ** ** diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp index e3b74c9d41..a01457246e 100644 --- a/indra/llappearance/llpolymesh.cpp +++ b/indra/llappearance/llpolymesh.cpp @@ -167,7 +167,6 @@ int compare_int(const void *a, const void *b); //----------------------------------------------------------------------------- // genIndices() //----------------------------------------------------------------------------- -#if 0 // Dead code void LLPolyMeshSharedData::genIndices(S32 index_offset) { if (index_offset == mLastIndexOffset) @@ -191,7 +190,6 @@ void LLPolyMeshSharedData::genIndices(S32 index_offset) mLastIndexOffset = index_offset; } -#endif //0 // //-------------------------------------------------------------------- // LLPolyMeshSharedData::getNumKB() diff --git a/indra/llappearance/llpolymesh.h b/indra/llappearance/llpolymesh.h index 71d85c29e0..ef1dfb1adb 100644 --- a/indra/llappearance/llpolymesh.h +++ b/indra/llappearance/llpolymesh.h @@ -133,8 +133,7 @@ private: BOOL loadMesh( const std::string& fileName ); public: - // Comment out dead code - //void genIndices(S32 offset); + void genIndices(S32 offset); const LLVector2 &getUVs(U32 index); diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 6b854fd089..5d41a964b0 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -314,251 +314,6 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } } - -// Qarl's mesh deformer -// find the point on a triangle closest to a given target point -// algorithm derived from: www.geometrictools.com/Documentation/DistancePoint3Triangle3.pdf -// (returns distance squared and barycentric coordinates) - -F32 LLTriangleClosestPoint(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& target, - F32& closest_a, F32& closest_b) -{ - // edges of triangle - LLVector3 edge0 = vert1 - vert0; - LLVector3 edge1 = vert2 - vert0; - - LLVector3 delta = vert0 - target; - - // length of triangle edges - F32 a00 = edge0.lengthSquared(); - F32 a01 = edge0 * edge1; - F32 a11 = edge1.lengthSquared(); - - F32 b0 = delta * edge0; - F32 b1 = delta * edge1; - - F32 c = delta.lengthSquared(); - - F32 det = fabs(a00*a11-a01*a01); - - F32 s = a01*b1-a11*b0; - F32 t = a01*b0-a00*b1; - - F32 dist_squared; - - if ( s + t <= det ) - { - if ( s < 0.0f ) - { - if ( t < 0.0f ) // region 4 - { - if ( b0 < 0.0f ) - { - t = 0.0f; - if ( -b0 >= a00 ) - { - s = 1.0f; - dist_squared = a00+(2.0f)*b0+c; - } - else - { - s = -b0/a00; - dist_squared = b0*s+c; - } - } - else - { - s = 0.0f; - if ( b1 >= 0.0f ) - { - t = 0.0f; - dist_squared = c; - } - else if ( -b1 >= a11 ) - { - t = 1.0f; - dist_squared = a11+(2.0f)*b1+c; - } - else - { - t = -b1/a11; - dist_squared = b1*t+c; - } - } - } - else // region 3 - { - s = 0.0f; - if ( b1 >= 0.0f ) - { - t = 0.0f; - dist_squared = c; - } - else if ( -b1 >= a11 ) - { - t = 1.0f; - dist_squared = a11+(2.0f)*b1+c; - } - else - { - t = -b1/a11; - dist_squared = b1*t+c; - } - } - } - else if ( t < 0.0f ) // region 5 - { - t = 0.0f; - if ( b0 >= 0.0f ) - { - s = 0.0f; - dist_squared = c; - } - else if ( -b0 >= a00 ) - { - s = 1.0f; - dist_squared = a00+(2.0f)*b0+c; - } - else - { - s = -b0/a00; - dist_squared = b0*s+c; - } - } - else // region 0 - { - // minimum at interior point - F32 det_inv = (1.0f)/det; - s *= det_inv; - t *= det_inv; - dist_squared = s*(a00*s+a01*t+(2.0f)*b0) + - t*(a01*s+a11*t+(2.0f)*b1)+c; - } - } - else - { - F32 tmp0, tmp1, numerator, denominator; - - if ( s < 0.0f ) // region 2 - { - tmp0 = a01 + b0; - tmp1 = a11 + b1; - if ( tmp1 > tmp0 ) - { - numerator = tmp1 - tmp0; - denominator = a00-2.0f*a01+a11; - if ( numerator >= denominator ) - { - s = 1.0f; - t = 0.0f; - dist_squared = a00+(2.0f)*b0+c; - } - else - { - s = numerator/denominator; - t = 1.0f - s; - dist_squared = s*(a00*s+a01*t+2.0f*b0) + - t*(a01*s+a11*t+(2.0f)*b1)+c; - } - } - else - { - s = 0.0f; - if ( tmp1 <= 0.0f ) - { - t = 1.0f; - dist_squared = a11+(2.0f)*b1+c; - } - else if ( b1 >= 0.0f ) - { - t = 0.0f; - dist_squared = c; - } - else - { - t = -b1/a11; - dist_squared = b1*t+c; - } - } - } - else if ( t < 0.0f ) // region 6 - { - tmp0 = a01 + b1; - tmp1 = a00 + b0; - if ( tmp1 > tmp0 ) - { - numerator = tmp1 - tmp0; - denominator = a00-(2.0f)*a01+a11; - if ( numerator >= denominator ) - { - t = 1.0f; - s = 0.0f; - dist_squared = a11+(2.0f)*b1+c; - } - else - { - t = numerator/denominator; - s = 1.0f - t; - dist_squared = s*(a00*s+a01*t+(2.0f)*b0) + - t*(a01*s+a11*t+(2.0f)*b1)+c; - } - } - else - { - t = 0.0f; - if ( tmp1 <= 0.0f ) - { - s = 1.0f; - dist_squared = a00+(2.0f)*b0+c; - } - else if ( b0 >= 0.0f ) - { - s = 0.0f; - dist_squared = c; - } - else - { - s = -b0/a00; - dist_squared = b0*s+c; - } - } - } - else // region 1 - { - numerator = a11 + b1 - a01 - b0; - if ( numerator <= 0.0f ) - { - s = 0.0f; - t = 1.0f; - dist_squared = a11+(2.0f)*b1+c; - } - else - { - denominator = a00-2.0f*a01+a11; - if ( numerator >= denominator ) - { - s = 1.0f; - t = 0.0f; - dist_squared = a00+(2.0f)*b0+c; - } - else - { - s = numerator/denominator; - t = 1.0f - s; - dist_squared = s*(a00*s+a01*t+(2.0f)*b0) + - t*(a01*s+a11*t+(2.0f)*b1)+c; - } - } - } - } - - closest_a = s; - closest_b = t; - - return fabs(dist_squared); -} -// - class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst { public: @@ -2329,7 +2084,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge generate(); - if ((mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) || mParams.getSculptType() == LL_SCULPT_TYPE_MESH) + if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE || mParams.getSculptType() == LL_SCULPT_TYPE_MESH) { createVolumeFaces(); } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index b69db19dbf..064c05598c 100755 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1100,11 +1100,7 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co 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); - -// Qarl's mesh deformer -F32 LLTriangleClosestPoint(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& target, - F32& closest_a, F32& closest_b); -// + #endif diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 917ca6acdf..6a1b4143cf 100755 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -274,67 +274,6 @@ const LLMatrix4& LLMatrix4::invert(void) return *this; } -// Qarl's mesh deformer -// does an actual inversion -const LLMatrix4& LLMatrix4::invert_real() -{ - F32* m = &mMatrix[0][0]; - - F32 inv[16]; - F32 det; - - inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15] - + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10]; - inv[4] = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15] - - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10]; - inv[8] = m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15] - + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9]; - inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14] - - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9]; - inv[1] = -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15] - - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10]; - inv[5] = m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15] - + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10]; - inv[9] = -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15] - - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9]; - inv[13] = m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14] - + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9]; - inv[2] = m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15] - + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6]; - inv[6] = -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15] - - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6]; - inv[10] = m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15] - + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5]; - inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14] - - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5]; - inv[3] = -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11] - - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6]; - inv[7] = m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11] - + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6]; - inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11] - - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5]; - inv[15] = m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10] - + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5]; - - det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12]; - - if (det == 0) - { - setZero(); - } - else - { - det = 1.0 / det; - - for (int i = 0; i < 16; i++) - m[i] = inv[i] * det; - - } - - return *this; -} -// - LLVector4 LLMatrix4::getFwdRow4() const { return LLVector4(mMatrix[VX][VX], mMatrix[VX][VY], mMatrix[VX][VZ], mMatrix[VX][VW]); diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index 56d93b1943..a7dce10397 100755 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -203,9 +203,6 @@ public: const LLMatrix4& transpose(); // Transpose LLMatrix4 const LLMatrix4& invert(); // Invert LLMatrix4 - // Qarl's mesh deformer - const LLMatrix4& invert_real(); // Invert LLMatrix4 - works for all matrices - // Rotate existing matrix // These are really, really, inefficient as implemented! - djs diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 7e90533ebc..7f7391fc21 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -2201,18 +2201,6 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) { mPelvisOffset = skin["pelvis_offset"].asReal(); } - - // Qarl's mesh deformer - if (skin.has("deform")) - { - mDeform = skin["deform"]; - } - else - { - mDeform = LLSD(); - } - // Qarl's mesh deformer - } LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const @@ -2256,8 +2244,6 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const ret["pelvis_offset"] = mPelvisOffset; } - ret["deform"] = mDeform; // Qarl's mesh deformer - return ret; } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 077aa8d77e..1cf528fd9f 100755 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -46,7 +46,6 @@ public: std::vector mInvBindMatrix; std::vector mAlternateBindMatrix; std::map mJointMap; - LLSD mDeform; // Qarl's mesh deformer LLMeshSkinInfo() { } LLMeshSkinInfo(LLSD& data); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 041d43b969..525fe115ad 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -247,7 +247,6 @@ set(viewer_SOURCE_FILES lldaycyclemanager.cpp lldebugmessagebox.cpp lldebugview.cpp - lldeformerworker.cpp lldeferredsounds.cpp lldelayedgestureerror.cpp lldirpicker.cpp @@ -451,7 +450,6 @@ set(viewer_SOURCE_FILES llmediadataclient.cpp llmenuoptionpathfindingrebakenavmesh.cpp llmeshrepository.cpp - llmeshsearch.cpp llmimetypes.cpp llmorphview.cpp llmoveview.cpp @@ -937,7 +935,6 @@ set(viewer_HEADER_FILES lldaycyclemanager.h lldebugmessagebox.h lldebugview.h - lldeformerworker.h lldeferredsounds.h lldelayedgestureerror.h lldirpicker.h @@ -1140,7 +1137,6 @@ set(viewer_HEADER_FILES llmediadataclient.h llmenuoptionpathfindingrebakenavmesh.h llmeshrepository.h - llmeshsearch.h llmimetypes.h llmorphview.h llmoveview.h diff --git a/indra/newview/lldeformerworker.cpp b/indra/newview/lldeformerworker.cpp deleted file mode 100644 index 9b6f88f59d..0000000000 --- a/indra/newview/lldeformerworker.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/** - * @file lldeformerworker.h - * @brief Threaded worker to compute deformation tables - * - * $LicenseInfo:firstyear=2012&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2012, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "lldrawable.h" -#include "llvoavatar.h" -#include "llvovolume.h" -#include "llviewerobjectlist.h" - -#include "lldeformerworker.h" - -// timer to watch the completed queue and process completed requests -// (needs to be done on main thread, hence this timer on 1 sec repeat.) -LLDeformerWorker::CompletedTimer::CompletedTimer() : LLEventTimer(1.0) -{ -} - -BOOL LLDeformerWorker::CompletedTimer::tick() -{ - LLDeformerWorker::processCompletedQ(); - return FALSE; -} - -// yes, global instance - -// LLSingleton appears to be incompatible with LLThread - they both keep track of the instance and -// want to delete it. - -LLDeformerWorker* gDeformerWorker; - - - - -LLDeformerWorker::LLDeformerWorker() -: LLThread("Deformer Worker") -{ - mQuitting = false; - - mSignal = new LLCondition(NULL); - mMutex = new LLMutex(NULL); -} - - -LLDeformerWorker::~LLDeformerWorker() -{ - shutdown(); - - if (mSignal) - { - delete mSignal; - mSignal = NULL; - } - - if (mMutex) - { - delete mMutex; - mMutex = NULL; - } -} - - -void LLDeformerWorker::shutdown() -{ - if (mSignal) - { - mQuitting = true; - mSignal->signal(); - - while (!isStopped()) - { - apr_sleep(10); - } - } -} - - -// static -void LLDeformerWorker::submitRequest(LLPointer request) -{ - if (!gDeformerWorker) - { - gDeformerWorker = new LLDeformerWorker; - } - - gDeformerWorker->instanceSubmitRequest(request); -} - - -void LLDeformerWorker::instanceSubmitRequest(LLPointer request) -{ - if (isStopped()) - { - start(); - } - - LLMutexLock lock(mMutex); - mRequestQ.push_back(request); - mSignal->signal(); -} - - -// static -BOOL LLDeformerWorker::alreadyQueued(LLPointer request) -{ - if (!gDeformerWorker) - { - return FALSE; - } - - for (request_queue::iterator iterator = gDeformerWorker->mRequestQ.begin(); - iterator != gDeformerWorker->mRequestQ.end(); - iterator++) - { - // the request is already here if we match MeshID, VertexCount, and Face - - LLPointer old_request = *iterator; - - - if ((request->mMeshID == old_request->mMeshID) && - (request->mFace == old_request->mFace) && - (request->mVertexCount == old_request->mVertexCount)) - { - return TRUE; - } - - } - - return FALSE; - -} - - -void LLDeformerWorker::buildDeformation(LLPointer request) -{ - request->mDeformedVolume->computeDeformTable(request); -} - -void LLDeformerWorker::run() -{ - while (!mQuitting) - { - mSignal->wait(); - while (!mQuitting && !mRequestQ.empty()) - { - LLPointer request; - - { - // alter Q while locked - LLMutexLock lock(mMutex); - request = mRequestQ.front(); - mRequestQ.pop_front(); - } - - buildDeformation(request); - - { - // alter Q while locked - LLMutexLock lock(mMutex); - mCompletedQ.push_back(request); - } - - } - - } -} - -// static -void LLDeformerWorker::processCompletedQ() -{ - if (!gDeformerWorker) - { - return; - } - - while ( !gDeformerWorker->mCompletedQ.empty()) - { - LLPointer request; - - { - // alter Q while locked - LLMutexLock lock(gDeformerWorker->mMutex); - request = gDeformerWorker->mCompletedQ.front(); - gDeformerWorker->mCompletedQ.pop_front(); - } - - // tag the drawable for rebuild - request->mDrawable->setState(LLDrawable::REBUILD_ALL); - } -} diff --git a/indra/newview/lldeformerworker.h b/indra/newview/lldeformerworker.h deleted file mode 100644 index 37ea06ada1..0000000000 --- a/indra/newview/lldeformerworker.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @file lldeformerworker.h - * @brief Threaded worker to compute deformation tables - * - * $LicenseInfo:firstyear=2012&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2012, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_DEFORMER_WORKER_H -#define LL_DEFORMER_WORKER_H - -#include "llthread.h" -#include "llsingleton.h" -#include "llpointer.h" -#include "llrefcount.h" -#include "lleventtimer.h" -#include "m4math.h" -#include -#include - -class LLDeformedVolume; -class LLDrawable; - -class LLDeformerWorker : LLThread -{ -public: - - // request that the worker compute a deform table: - class Request : public LLRefCount - { - public: - LLPointer mDeformedVolume; - LLPointer mDrawable; - LLUUID mMeshID; - S32 mFace; - S32 mVertexCount; - - // positions/normals of the volume vertices - std::vector< LLVector3 > mVolumePositions; - std::vector< LLVector3 > mVolumeNormals; - - // positions/normals/indices of the base avatar vertices - std::vector > mAvatarPositions; - std::vector > mAvatarNormals; - std::vector > mAvatarIndices; - - - LLMatrix4 mBindShapeMatrix; - F32 mScale; - }; - - // timer handles completed requests on main thread - class CompletedTimer : public LLEventTimer - { - public: - CompletedTimer(); - BOOL tick(); - }; - - - LLDeformerWorker(); - virtual ~LLDeformerWorker(); - - - // add a request to the Q (called from main thread) - static void submitRequest(LLPointer request); - - // see if request is already on queue - static BOOL alreadyQueued(LLPointer request); - - // do the work of building the deformation table - void buildDeformation(LLPointer request); - - // do the necessary work on the completed queue (on the main thread) - static void processCompletedQ(); - - - void shutdown(); - - virtual void run(); - - CompletedTimer mTimer; - - - - -private: - void instanceSubmitRequest(LLPointer request); - - LLCondition* mSignal; - LLMutex* mMutex; - - BOOL mQuitting; - - typedef std::list< LLPointer > request_queue; - - request_queue mRequestQ; - request_queue mCompletedQ; -}; - -extern LLDeformerWorker* gDeformerWorker; - -#endif - diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index dbce808035..503469a2e8 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -49,7 +49,6 @@ #include "llappviewer.h" #include "llrendersphere.h" #include "llviewerpartsim.h" -#include "llviewernetwork.h" // Qarl's mesh deformer - for hopefully temporary grid checks static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK; static U32 sBufferUsage = GL_STREAM_DRAW_ARB; @@ -1445,12 +1444,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) } } -// Qarl's mesh deformer -//void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) -void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, - const LLMeshSkinInfo* skin, LLVolume* volume, - const LLVolumeFace& vol_face, LLVOVolume* vobj) -// +void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) { LLVector4a* weight = vol_face.mWeights; if (!weight) @@ -1459,17 +1453,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* } LLPointer buffer = face->getVertexBuffer(); - // Qarl's mesh deformer - //LLDrawable* drawable = face->getDrawable(); - LLPointer drawable = face->getDrawable(); - - // NOTE: Remove this next bit as well as the rest of the grid checking if LL ever gets their act together - // and adds the deformer - bool is_opensim = false; -#if OPENSIM - is_opensim = LLGridManager::getInstance()->isInOpenSim(); -#endif // OPENSIM - // + LLDrawable* drawable = face->getDrawable(); U32 data_mask = face->getRiggedVertexBufferDataMask(); @@ -1530,21 +1514,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face->setPoolType(LLDrawPool::POOL_AVATAR); } - // Qarl's mesh deformer - //face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); - - // swap in deformed volume if conditions are met: - LLVolume* which_volume = volume; - if (skin->mDeform["version"].asInteger() != 0//) - && is_opensim) // Remove the grid check if LL ever gets it together - // - { - LLDeformedVolume* deformed_volume = vobj->getDeformedVolume(); - deformed_volume->deform(volume, avatar, skin, face->getTEOffset(), drawable); - which_volume = deformed_volume; - } - - face->getGeometryVolume(*which_volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); + face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); buffer->flush(); } @@ -1583,19 +1553,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); - // Qarl's mesh deformer - // swap in deformed volume if conditions are met: - LLVolume* which_volume = volume; - if (skin->mDeform["version"].asInteger() != 0//) - && is_opensim) // NOTE: Remove the grid check if LL ever gets it together - { - which_volume = vobj->getDeformedVolume(); - } - - LLVector4a* positions = which_volume->getVolumeFace(face->getTEOffset()).mPositions; - LLVector4a* normals = which_volume->getVolumeFace(face->getTEOffset()).mNormals; - // - for (U32 j = 0; j < buffer->getNumVerts(); ++j) { LLMatrix4a final_mat; @@ -1627,10 +1584,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* final_mat.add(src); } - // Qarl's mesh deformer - //LLVector4a& v = vol_face.mPositions[j]; - LLVector4a& v = positions[j]; - // + + LLVector4a& v = vol_face.mPositions[j]; LLVector4a t; LLVector4a dst; bind_shape_matrix.affineTransform(v, t); @@ -1639,15 +1594,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* if (norm) { - // Qarl's mesh deformer - //LLVector4a& n = vol_face.mNormals[j]; - - // normals are not transformed by the same math as points. - // you need the inverse transpose. - // these matrices are non-uniformly scaled (by a lot) so this - // math is wrong. (i think.) -qarl - LLVector4a& n = normals[j]; - // + LLVector4a& n = vol_face.mNormals[j]; bind_shape_matrix.rotate(n, t); final_mat.rotate(t, dst); norm[j] = dst; @@ -1895,10 +1842,7 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) stop_glerror(); const LLVolumeFace& vol_face = volume->getVolumeFace(te); - // Qarl's mesh deformer - //updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); - updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face, vobj); - // + updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); } } } diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 50a9833438..7d0368a945 100755 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -35,7 +35,6 @@ class LLFace; class LLMeshSkinInfo; class LLVolume; class LLVolumeFace; -class LLVOVolume; // Qarl's mesh deformer class LLDrawPoolAvatar : public LLFacePool @@ -138,8 +137,7 @@ public: LLFace* facep, const LLMeshSkinInfo* skin, LLVolume* volume, - const LLVolumeFace& vol_face, - LLVOVolume* vobj); // Qarl's mesh deformer + const LLVolumeFace& vol_face); void updateRiggedVertexBuffers(LLVOAvatar* avatar); void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false); diff --git a/indra/newview/llface.h b/indra/newview/llface.h index d9d2dbeb16..0687544d53 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -146,10 +146,7 @@ public: LLFacePool* getPool() const { return mDrawPoolp; } U32 getPoolType() const { return mPoolType; } - // Qarl's mesh deformer - //LLDrawable* getDrawable() const { return mDrawablep; } - LLPointer getDrawable() const { return mDrawablep; } - // + LLDrawable* getDrawable() const { return mDrawablep; } LLViewerObject* getViewerObject() const { return mVObjp; } S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; } void setPoolType(U32 type) { mPoolType = type; } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 973eabafa7..a663a61e83 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -459,10 +459,6 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("import_scale", onImportScaleCommit, this); childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this); - // Qarl's mesh deformer - childSetCommitCallback("deform", onDeformCommit, this); - childSetCommitCallback("deform_base", onDeformCommit, this); - // getChild("show_edges")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); getChild("show_physics")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); @@ -472,13 +468,6 @@ BOOL LLFloaterModelPreview::postBuild() childDisable("upload_skin"); childDisable("upload_joints"); - // Qarls' mesh deformer - childDisable("deform"); - childDisable("deform_base"); - - // initialize base radio buttons - getChild("deform_base")->setValue(LLSD(0)); - // initDecompControls(); @@ -707,25 +696,6 @@ void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata ) fp->mModelPreview->refresh(); } -// Qarl's mesh deformer -//static -void LLFloaterModelPreview::onDeformCommit( LLUICtrl*, void* userdata ) -{ - LLFloaterModelPreview *fp =(LLFloaterModelPreview*)userdata; - - if (!fp->mModelPreview) - { - return; - } - - fp->mModelPreview->mDirty = true; - - fp->toggleCalculateButton(true); - - fp->mModelPreview->refresh(); -} -// - //static void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata) { @@ -3294,45 +3264,6 @@ LLModelPreview::~LLModelPreview() //glodShutdown(); } -// Qarl's mesh deformer -// map the base deformation type to it's corresponding LLSD -// if a person wanted to add standard sizing parameters, here -// is where they'd do it. -LLSD deformation_parameters(BOOL deform, S32 base_type) -{ - - if (!deform) - return LLSD(); - - LLSD parameters; - - parameters = LLSD::emptyMap(); - parameters["version"] = 1; - parameters["visual_params"] = LLSD::emptyMap(); - - if (base_type == 0) // male - { - parameters["visual_params"]["male"] = 1.0f; - } - - if (base_type == 1) // female - { - // female base needs no modifications - } - - // example stub for how one might implement standard sizing parameters - if (base_type == 2) // male - scrawny - { - parameters["visual_params"]["male"] = 1.0f; - parameters["visual_params"]["Love_Handles"] = -1.0f; - parameters["visual_params"]["Leg Muscles"] = 0.0f; - - } - - return parameters; -} -// - U32 LLModelPreview::calcResourceCost() { assert_main_thread(); @@ -3355,7 +3286,6 @@ U32 LLModelPreview::calcResourceCost() F32 debug_scale = mFMP ? mFMP->childGetValue("import_scale").asReal() : 1.f; mPelvisZOffset = mFMP ? mFMP->childGetValue("pelvis_offset").asReal() : 3.0f; - BOOL deform = mFMP ? mFMP->childGetValue("deform").asBoolean() : FALSE; // Qarl's mesh deformer if ( mFMP && mFMP->childGetValue("upload_joints").asBoolean() ) { @@ -3377,16 +3307,12 @@ U32 LLModelPreview::calcResourceCost() instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics : instance.mModel->mPhysics; - //update instance skin info for each lods pelvisZoffset and deform + //update instance skin info for each lods pelvisZoffset for ( int j=0; jmSkinInfo.mPelvisOffset = mPelvisZOffset; - // Qarl's mesh deformer - instance.mLOD[j]->mSkinInfo.mDeform = - deformation_parameters(deform, mFMP->childGetValue("deform_base").asInteger()); - // } } @@ -5184,7 +5110,6 @@ BOOL LLModelPreview::render() bool has_skin_weights = false; bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean(); bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean(); - bool deform = mFMP->childGetValue("deform").asBoolean(); // Qarl's mesh deformer if ( upload_joints != mLastJointUpdate ) { @@ -5212,21 +5137,11 @@ BOOL LLModelPreview::render() fmp->enableViewOption("show_skin_weight"); fmp->setViewOptionEnabled("show_joint_positions", skin_weight); mFMP->childEnable("upload_skin"); - // Qarl's mesh deformer - mFMP->childEnable("deform"); - mFMP->childEnable("deform_base"); - // - } } else { mFMP->childDisable("upload_skin"); - // Qarl's mesh deformer - mFMP->childDisable("deform"); - mFMP->childDisable("deform_base"); - // - if (fmp) { mViewOption["show_skin_weight"] = false; @@ -5248,26 +5163,12 @@ BOOL LLModelPreview::render() upload_joints = false; } - // Qarl's mesh deformer - if (!upload_skin && deform) - { // can't deform if model has no skin weights - mFMP->childSetValue("deform", false); - deform = false; - } - // - //Only enable joint offsets if it passed the earlier critiquing if ( isRigValidForJointPositionUpload() ) { mFMP->childSetEnabled("upload_joints", upload_skin); } - // Qarl's mesh deformer - // Only enable deform if skins are enabled - mFMP->childSetEnabled("deform", upload_skin); - mFMP->childSetEnabled("deform_base", upload_skin); - // - F32 explode = mFMP->childGetValue("physics_explode").asReal(); glClear(GL_DEPTH_BUFFER_BIT); diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 207a33d1c8..32ddad0305 100755 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -217,7 +217,6 @@ protected: static void onImportScaleCommit(LLUICtrl*, void*); static void onPelvisOffsetCommit(LLUICtrl*, void*); - static void onDeformCommit(LLUICtrl*, void*); // Qarl's mesh deformer static void onUploadJointsCommit(LLUICtrl*,void*); static void onUploadSkinCommit(LLUICtrl*,void*); diff --git a/indra/newview/llmeshsearch.cpp b/indra/newview/llmeshsearch.cpp deleted file mode 100644 index 8edc9ac0cf..0000000000 --- a/indra/newview/llmeshsearch.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/** - * @file llmeshsearch.cpp - * @brief Search meshes efficiently - * @author Karl Stiefvater - * - * $LicenseInfo:firstyear=2013&license=viewerlgpl$ - * InWorldz Viewer Source Code - * Copyright (C) 2013, InWorldz, LLC. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License or later. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * $/LicenseInfo$ - */ - - - -#include "llviewerprecompiledheaders.h" - - -#include "llmeshsearch.h" - -#include "llrand.h" -#include "llvolume.h" - - -LLMeshSearch::LLMeshSearch(std::vector& positions, std::vector& indices) : - mPositions(positions), mIndices(indices) -{ - // compute bounding box - mBBox.setMin(mPositions[0]); - mBBox.setMax(mPositions[0]); - for (S32 i = 0; i < mPositions.size(); i++) - { - mBBox.addPoint(mPositions[i]); - } - - // size of each voxel - emperically determined to give good performance - mVoxelSize = 0.05; - - mWidth = (S32)ceil(mBBox.getExtent().mV[VX] / mVoxelSize); - mHeight = (S32)ceil(mBBox.getExtent().mV[VY] / mVoxelSize); - mDepth = (S32)ceil(mBBox.getExtent().mV[VZ] / mVoxelSize); - - // the voxel table - mVoxels.resize(mWidth * mHeight * mDepth, NULL); - - - // insert triangles into voxel table - for (S32 triangle_index = 0; triangle_index < mIndices.size(); triangle_index += 3) - { - S32 index0 = mIndices[triangle_index]; - S32 index1 = mIndices[triangle_index+1]; - S32 index2 = mIndices[triangle_index+2]; - - LLVector3& position0 = mPositions[index0]; - LLVector3& position1 = mPositions[index1]; - LLVector3& position2 = mPositions[index2]; - - S32 x, y, z; - - cellLocation(position0, x, y, z); - insertTriangle(triangle_index, x, y, z); - cellLocation(position1, x, y, z); - insertTriangle(triangle_index, x, y, z); - cellLocation(position2, x, y, z); - insertTriangle(triangle_index, x, y, z); - } -} - - -LLMeshSearch::~LLMeshSearch() -{ - for (S32 i = 0; i < mVoxels.size(); i++) - { - if (mVoxels[i]) - { - delete mVoxels[i]; - } - } -} - -// given a point in space, find it's entry coordinates in the voxel table -void LLMeshSearch::cellLocation(LLVector3& position, S32& x, S32& y, S32& z) -{ - LLVector3 local_position = position - mBBox.getMin(); - x = (S32)floor(local_position.mV[VX] / mVoxelSize); - y = (S32)floor(local_position.mV[VY] / mVoxelSize); - z = (S32)floor(local_position.mV[VZ] / mVoxelSize); -} - - -// insert a new triangle into the voxel table -void LLMeshSearch::insertTriangle(S32 triangle_index, S32 x, S32 y, S32 z) -{ - S32 voxel_index = (x * mHeight + y) * mDepth + z; - - std::vector* vector_pointer = mVoxels[voxel_index]; - - if (!vector_pointer) - { - vector_pointer = new std::vector; - mVoxels[voxel_index] = vector_pointer; - } - - // don't insert dupes (which will only appear sequentially so this test catches them all) - if ((vector_pointer->size() == 0) || (vector_pointer->back() != triangle_index)) - { - vector_pointer->push_back(triangle_index); - } -} - - -// find point on mesh which is closest to target mesh, within a given distance, return TRUE if found - -BOOL LLMeshSearch::findClosestPoint(LLVector3 target, F32 within, - F32& distance, S32& index0, S32& index1, S32& index2, F32& bary_a, F32& bary_b) -{ - BOOL found = FALSE; - - F32 closest_distance_squared = powf(within, 2.0f); - - S32 target_x, target_y, target_z; - cellLocation(target, target_x, target_y, target_z); - - // cycle over all voxels - for (S32 x = 0; x < mWidth; x++) - { - F32 delta_x = llmax(abs(x-target_x)-1, 0) * mVoxelSize; - F32 delta_x_squared = delta_x * delta_x; - - // if this plane is too far away, skip it - if ((delta_x_squared) > closest_distance_squared) - continue; - - - for (S32 y = 0; y < mHeight; y++) - { - F32 delta_y = llmax(abs(y-target_y)-1, 0) * mVoxelSize; - F32 delta_y_squared = delta_y * delta_y; - - // if this line is too far away, skip it - if ((delta_x_squared + delta_y_squared) > closest_distance_squared) - continue; - - - for (S32 z = 0; z < mDepth; z++) - { - F32 delta_z = llmax(abs(z-target_z)-1, 0) * mVoxelSize; - F32 delta_z_squared = delta_z * delta_z; - - // if this voxel is too far away, skip it - if ((delta_x_squared + delta_y_squared + delta_z_squared) > closest_distance_squared) - continue; - - S32 voxel_index = (x * mHeight + y) * mDepth + z; - - std::vector* vector_pointer = mVoxels[voxel_index]; - - // if the voxel is empty, skip it - if (!vector_pointer) - continue; - - - // cycle over all triangles - for (S32 j = 0; j < vector_pointer->size(); j++) - { - S32 triangle_index = (*vector_pointer)[j]; - - // indices for triangle corners - S32 this_index0 = mIndices[triangle_index+0]; - S32 this_index1 = mIndices[triangle_index+1]; - S32 this_index2 = mIndices[triangle_index+2]; - - // positions of triangle corners - LLVector3 this_position0 = mPositions[this_index0]; - LLVector3 this_position1 = mPositions[this_index1]; - LLVector3 this_position2 = mPositions[this_index2]; - - // barycentric coord of closest point - F32 this_bary_a; - F32 this_bary_b; - - F32 this_distance_squared = LLTriangleClosestPoint(this_position0, this_position1, this_position2, - target, this_bary_a, this_bary_b); - - - if (this_distance_squared < closest_distance_squared) - { - found = TRUE; - - // record corner indices of this triangle - index0 = this_index0; - index1 = this_index1; - index2 = this_index2; - - // compute weights from barycentric coordinates - bary_a = this_bary_a; - bary_b = this_bary_b; - - closest_distance_squared = this_distance_squared; - } - - - } - - } - } - } - - - if (found) - { - distance = sqrt(closest_distance_squared); - } - - - return found; -} diff --git a/indra/newview/llmeshsearch.h b/indra/newview/llmeshsearch.h deleted file mode 100644 index 00d33dd5e9..0000000000 --- a/indra/newview/llmeshsearch.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file llmeshsearch.cpp - * @brief Search meshes efficiently - * @author Karl Stiefvater - * - * $LicenseInfo:firstyear=2013&license=viewerlgpl$ - * InWorldz Viewer Source Code - * Copyright (C) 2013, InWorldz, LLC. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License or later. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * $/LicenseInfo$ - */ - -class LLVector3; -class LLBBox; - -#ifndef LL_MESHSEARCH_H -#define LL_MESHSEARCH_H - -class LLMeshSearch -{ - std::vector mPositions; - std::vector mIndices; - LLBBoxLocal mBBox; - - // voxel table - F32 mVoxelSize; - U32 mWidth; - U32 mHeight; - U32 mDepth; - - std::vector* > mVoxels; - - -public: - LLMeshSearch(std::vector& positions, std::vector& indices); - ~LLMeshSearch(); - - void cellLocation(LLVector3& position, S32& x, S32& y, S32& z); - void insertTriangle(S32 triangle_index, S32 x, S32 y, S32 z); - - - BOOL findClosestPoint(LLVector3 target, F32 within, F32& distance, S32& index0, S32& index1, S32& index2, F32& bary_a, F32& bary_b); -}; - - -#endif // LL_MESHSEARCH_H - - - - - - - - diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f1cb154138..39c482f37d 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5609,7 +5609,6 @@ void LLVOAvatar::updateVisualParams() dirtyMesh(); updateHeadOffset(); - rebuildRiggedAttachments(); // Qarl's mesh deformer } //----------------------------------------------------------------------------- diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d3d7805546..dbbc937201 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -82,10 +82,6 @@ #include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] -// Qarl's mesh deformer -#include "lldeformerworker.h" -#include "llmeshsearch.h" -// const S32 MIN_QUIET_FRAMES_COALESCE = 30; const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; @@ -4015,9 +4011,8 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLVector4a* weight = vol_face.mWeights; - // Qarl's mesh deformer - //if ( weight ) - //{ + if ( weight ) + { LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); @@ -4062,8 +4057,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLVector4a& v = vol_face.mPositions[j]; LLVector4a t; LLVector4a dst; - bind_shape_matrix.affineTransform(v, t); // shouldn't this matrix be premultiplied into the matrix palette? this is expensive. - + bind_shape_matrix.affineTransform(v, t); final_mat.affineTransform(t, dst); pos[j] = dst; } @@ -4101,456 +4095,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons dst_face.createOctree(1.f); } - //} // Qarl's mesh deformer + } } } -// Qarl's mesh deformer -LLDeformedVolume* LLVOVolume::getDeformedVolume() -{ - if (!mDeformedVolume) - { - // doesn't exist yet - make it - mDeformedVolume = new LLDeformedVolume; - } - - return mDeformedVolume; -} - -static LLFastTimer::DeclareTimer FTM_SKIN_RIGGED_DEFORM("Deform"); - - -// these are the meshes we follow -static S32 MORPH_MESHES[] = { LLAvatarAppearanceDefines::MESH_ID_HEAD, - LLAvatarAppearanceDefines::MESH_ID_UPPER_BODY, - LLAvatarAppearanceDefines::MESH_ID_LOWER_BODY }; - - - -// attempt to find the cached deform table. if not found, generate request for it to be built and -// send to deform worker -LLDeformedVolume::LLDeformTable* LLDeformedVolume::getDeformTable(LLVolume* source, LLVOAvatar* avatar2, - const LLMeshSkinInfo* skin, S32 face, - LLPointer drawable) -{ - // see if we can find this deform table in the cache - LLDeformTableCacheIndex cache_index(source->getParams().getSculptID(), face, - source->getVolumeFace(face).mNumVertices); - - - - deform_cache_t::iterator i = mDeformCache.find(cache_index); - - if (i != mDeformCache.end()) - { - // found it, return it - return &(i->second); - } - - - // doesn't exist in cache, must create - // send a request to the deformer worker. - - LLPointer request = new LLDeformerWorker::Request; - - - // pack the request - request->mDeformedVolume = this; - request->mDrawable = drawable; - request->mMeshID = source->getParams().getSculptID(); - request->mFace = face; - request->mVertexCount = source->getVolumeFace(face).mNumVertices; - - // before we do any more work, see if this request is already on the queue - if (LLDeformerWorker::alreadyQueued(request)) - { - // no more to be done here, return NULL - return NULL; - } - - // we copy this data now so that when we do the work in - // the second thread, there's no chance it will be clobbered - - // - // fill volume vertex positions/normals - // - const LLVolumeFace& source_face = source->getVolumeFace(face); - request->mVolumePositions.resize(source_face.mNumVertices); - request->mVolumeNormals.resize(source_face.mNumVertices); - - for (S32 i = 0; i < source_face.mNumVertices; i++) - { - LLVector3 position(source_face.mPositions[i].getF32ptr()); - request->mVolumePositions[i] = position; - LLVector3 normal(source_face.mNormals[i].getF32ptr()); - normal.normalize(); - request->mVolumeNormals[i] = normal; - } - - // scale and matrix constants - // maps volume space to object (avatar) space - LLMatrix4a bind_shape_matrix_a; - request->mBindShapeMatrix = skin->mBindShapeMatrix; - // skeleton scaling factor - assumes all joints have same scale and that the scale is uniform in XYZ (currently true) - request->mScale = powf(skin->mInvBindMatrix[0].determinant(), 1.0f / 3.0f); - - - - // - // compute the base avatar shape for this deformed volume - // - - // create default avatar - LLPointer avatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion()); - avatar->mIsDummy = TRUE; - avatar->mSpecialRenderMode = 2; - - avatar->updateJointLODs(); - - // apply base visual_params - LLSD visual_params = skin->mDeform["visual_params"]; - - // at this point i planned to loop over the map and set the parameters it - // specified. but i learned that LLSD does not implement LLSD::mapBegin() and - // LLSD::mapEnd(). (they are defined, just not implemented. yay.) so instead - // i loop over all the possible visual params in the avatar, and see if they are - // present in the map. - LLVisualParam* this_param = avatar->getFirstVisualParam(); - - while(this_param != NULL) - { - std::string name = this_param->getName(); - if (visual_params.has(name)) - { - avatar->setVisualParamWeight(name.c_str(), visual_params[name].asReal()); - } - - this_param = avatar->getNextVisualParam(); - } - - // and apply this parameters - avatar->updateVisualParams(); - - - // extract the data from this avatar, store it in the request - S32 num_meshes = sizeof(MORPH_MESHES)/sizeof(S32); - request->mAvatarIndices.resize(num_meshes); - request->mAvatarPositions.resize(num_meshes); - request->mAvatarNormals.resize(num_meshes); - - - for (S32 j = 0; j < num_meshes; j++) - { - S32 mesh_id = MORPH_MESHES[j]; - - LLPolyMesh* avatar_mesh = avatar->getMesh(mesh_id); - - LLPolyFace* faces = avatar_mesh->getFaces(); - - // store avatar indices (LLPolyFaces are triangles) - S32 num_triangles = avatar_mesh->getNumFaces(); - request->mAvatarIndices[j].resize(num_triangles * 3); - for (S32 k = 0; k < num_triangles; k++) - { - // indices for triangle corners - S32 index0 = faces[k][0]; - S32 index1 = faces[k][1]; - S32 index2 = faces[k][2]; - - request->mAvatarIndices[j][k * 3 + 0] = index0; - request->mAvatarIndices[j][k * 3 + 1] = index1; - request->mAvatarIndices[j][k * 3 + 2] = index2; - } - - // store avatar vertices/normals - const LLVector4a* base_positions = avatar_mesh->getCoords(); - const LLVector4a* base_normals = avatar_mesh->getNormals(); - S32 num_vertices = avatar_mesh->getNumVertices(); - request->mAvatarPositions[j].resize(num_vertices); - request->mAvatarNormals[j].resize(num_vertices); - for (S32 k = 0; k < num_vertices; k++) - { - request->mAvatarPositions[j][k] = LLVector3(base_positions[k].getF32ptr()); - request->mAvatarNormals[j][k] = LLVector3(base_normals[k].getF32ptr()); - request->mAvatarNormals[j][k].normalize(); - } - - // clean-up avatar - avatar->markDead(); - } - - - - // submit request to deformer worker - LLDeformerWorker::submitRequest(request); - - return NULL; -} - - - -void LLDeformedVolume::computeDeformTable(LLPointer request) -{ - // see if this table is already in the cache. if so, return (no work needed) - LLDeformTableCacheIndex cache_index(request->mMeshID, request->mFace, request->mVertexCount); - - - deform_cache_t::iterator i = mDeformCache.find(cache_index); - - if (i != mDeformCache.end()) - { - // found it, nothing more to do here - return; - } - - // tables are fairly small, we keep them around in case the user is switching between meshes for poorman's animation - // one entry per face per LOD per sculpt_ID - U32 MAX_CACHE_SIZE = 20; - - if (mDeformCache.size() > MAX_CACHE_SIZE) - { - // this table will very infrequently fill - so make space in simple way: - // delete element at random - U32 random = ll_rand(MAX_CACHE_SIZE-1); - - deform_cache_t::iterator iterator = mDeformCache.begin(); - - for (int i = 0; i < random; i++) - { - iterator++; - } - - mDeformCache.erase(iterator); - } - - - LLDeformTable deform_table; - - // table is a mapping from verts on the volume to verts on the avatar mesh. - // currently we take closest point - but may want to modify this in favor - // verts with similar skin weights and/or normals (so verts on the left leg - // don't move with the right leg by accident.) - - - // build mapping - deform_table.mMap.resize(request->mVertexCount); - - - // find matrices (vert and normal) - LLMatrix4a vertex_matrix; - vertex_matrix.loadu(request->mBindShapeMatrix); - - LLMatrix4 normal_matrix_noA = request->mBindShapeMatrix; - normal_matrix_noA.invert_real(); // normals are transformed by inverse transpose - normal_matrix_noA.transpose(); - LLMatrix4a normal_matrix; - normal_matrix.loadu(normal_matrix_noA); - - // build optimized mesh searchers - one for each avatar mesh - LLMeshSearch* search[sizeof(MORPH_MESHES)/sizeof(S32)]; - for (S32 i = 0; i < sizeof(MORPH_MESHES)/sizeof(S32); i++) - { - search[i] = new LLMeshSearch(request->mAvatarPositions[i], request->mAvatarIndices[i]); - } - - - // for each vertex in the volume, find the closest point on the avatar mesh(es) - // "closest" is defined to be a mixture of spatial position and distance between - // normals. - - for (S32 i = 0; i < request->mVertexCount; i++) - { - // position to get closest to - LLVector4a source_position; - source_position.load3(request->mVolumePositions[i].mV); - LLVector4a source_position_transformed; - vertex_matrix.affineTransform(source_position, source_position_transformed); - source_position_transformed.mul(request->mScale); - LLVector3 target_position(source_position_transformed.getF32ptr()); - - - F32 closest_distance = F32_MAX; - S32 closest_mesh = 0; - // corners of the triangle containing the closest point; - S32 closest_vertex[LL_DEFORMER_WEIGHT_COUNT]; - // weights of those corners (barycentric coordinates) - F32 closest_vertex_weights[LL_DEFORMER_WEIGHT_COUNT]; - - for (S32 k = 0; k < sizeof(MORPH_MESHES)/sizeof(S32); k++) - { - F32 this_distance; - - S32 index0, index1, index2; - F32 bary_a, bary_b; - - BOOL found = search[k]->findClosestPoint(target_position, closest_distance, - this_distance, index0, index1, index2, bary_a, bary_b); - - if (found) - { - // record corner indices of this triangle - closest_vertex[0] = index0; - closest_vertex[1] = index1; - closest_vertex[2] = index2; - - // compute weights from barycentric coordinates - closest_vertex_weights[0] = 1.0f - bary_a - bary_b; - closest_vertex_weights[1] = bary_a; - closest_vertex_weights[2] = bary_b; - - // and closest mesh - closest_mesh = k; - - closest_distance = this_distance; - } - - } - - - // create entry for found vertices - for (S32 k = 0; k < LL_DEFORMER_WEIGHT_COUNT; k++) - { - deform_table.mMap[i].mMesh[k] = (U8)closest_mesh; - deform_table.mMap[i].mVertex[k] = closest_vertex[k]; - deform_table.mMap[i].mWeight[k] = closest_vertex_weights[k]; - } - } - - // free mesh searchers - for (S32 i = 0; i < sizeof(MORPH_MESHES)/sizeof(S32); i++) - { - delete search[i]; - } - - - // store base positions for avatar verts - deform_table.mBasePositions = request->mAvatarPositions; - - - // now put it in the cache - mDeformCache[cache_index] = deform_table; - - return; -} - - - -BOOL LLDeformedVolume::deform(LLVolume* source, LLVOAvatar* avatar, - const LLMeshSkinInfo* skin, S32 face, LLPointer drawable) -{ - LLFastTimer t(FTM_SKIN_RIGGED_DEFORM); - - - // first copy the source volume - bool copy = false; - if (source->getNumVolumeFaces() != getNumVolumeFaces()) - { - copy = true; - } - - for (S32 i = 0; i < source->getNumVolumeFaces() && !copy; ++i) - { - const LLVolumeFace& src_face = source->getVolumeFace(i); - const LLVolumeFace& dst_face = getVolumeFace(i); - - if (src_face.mNumIndices != dst_face.mNumIndices || - src_face.mNumVertices != dst_face.mNumVertices) - { - copy = true; - } - } - - if (copy) - { - copyVolumeFaces(source); - } - - - // get the deform table - LLDeformTable* deform_table = getDeformTable(source, avatar, skin, face, drawable); - - - // if it's not available, fail - if (!deform_table) - { - return FALSE; - } - - - const LLVolumeFace& source_face = source->getVolumeFace(face); - const LLVolumeFace& destination_face = getVolumeFace(face); - - - // transforms volume space to avatar space - LLMatrix4a bind_shape_matrix_a; - bind_shape_matrix_a.loadu(skin->mBindShapeMatrix); - - // transforms back again - LLMatrix4 bind_shape_matrix_inverse = skin->mBindShapeMatrix; - bind_shape_matrix_inverse.invert_real(); - LLMatrix4a bind_shape_matrix_inverse_a; - bind_shape_matrix_inverse_a.loadu(bind_shape_matrix_inverse); - - // skeleton scaling factor - assumes all joints have same scale and that the scale is uniform in XYZ (currently true) - F32 scale = powf(skin->mInvBindMatrix[0].determinant(), 1.0f / 3.0f); - - - for (S32 i = 0; i < source_face.mNumVertices; i++) - { - LLVector4a weighted_morph_delta; - weighted_morph_delta.clear(); - - F32 total_weight = 0; - - for (S32 j = 0; j < LL_DEFORMER_WEIGHT_COUNT; j++) - { - U16 closest_vertex = deform_table->mMap[i].mVertex[j]; - S32 closest_mesh = deform_table->mMap[i].mMesh[j]; - F32 closest_weight = deform_table->mMap[i].mWeight[j]; - - // find the current mesh - LLPolyMesh* avatar_mesh = avatar->getMesh(MORPH_MESHES[closest_mesh]); - // and get positions for and morphed vertices - const LLVector4a* morph_positions = avatar_mesh->getCoords(); - - // find the movement of this vertex due to morphing - LLVector4a base_position; - base_position.load3(deform_table->mBasePositions[closest_mesh][closest_vertex].mV); - LLVector4a morph_delta; - morph_delta.setSub(morph_positions[closest_vertex], base_position); - - // weight this delta and add to total - morph_delta.mul(closest_weight); - weighted_morph_delta.add(morph_delta); - total_weight += closest_weight; - } - - // normalize - weighted_morph_delta.mul(1.0f/total_weight); - - // source position mapped to avatar space - LLVector4a source_position = source_face.mPositions[i]; - LLVector4a source_position_transformed; - bind_shape_matrix_a.affineTransform(source_position, source_position_transformed); - source_position_transformed.mul(scale); - - // modify by movement delta - LLVector4a destination_position_transformed; - destination_position_transformed.setAdd(source_position_transformed, weighted_morph_delta); - - // map back to volume space - destination_position_transformed.mul(1.0f / scale); - LLVector4a destination_position; - bind_shape_matrix_inverse_a.affineTransform(destination_position_transformed, destination_position); - - destination_face.mPositions[i] = destination_position; - } - - - return TRUE; // success! -} -// - U32 LLVOVolume::getPartitionType() const { if (isHUDAttachment()) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 12382963b2..5d94bfa598 100755 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -35,7 +35,6 @@ #include "m3math.h" // LLMatrix3 #include "m4math.h" // LLMatrix4 #include -#include "lldeformerworker.h" // Qarl's mesh deformer class LLViewerTextureAnim; class LLDrawPool; @@ -65,92 +64,6 @@ public: void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume); }; - -// Qarl's mesh deformer -const S32 LL_DEFORMER_WEIGHT_COUNT = 3; - - -class LLDeformedVolume : public LLVolume -{ -public: - LLDeformedVolume() - : LLVolume(LLVolumeParams(), 0.f) - { - } - - // used as a key for the deform table cache - class LLDeformTableCacheIndex - { - public: - LLDeformTableCacheIndex(const LLUUID& id, S32 face, S32 vertex_count) : - mID(id), mFace(face), mVertexCount(vertex_count) {} - - S32 mBaseShape; - LLUUID mID; - S32 mFace; - S32 mVertexCount; - - bool operator<(const LLDeformTableCacheIndex& lhs) const - { - if (mID < lhs.mID) - return TRUE; - if (mID > lhs.mID) - return FALSE; - if (mFace < lhs.mFace) - return TRUE; - if (mFace > lhs.mFace) - return FALSE; - if (mVertexCount < lhs.mVertexCount) - return TRUE; - - return FALSE; - } - }; - - - // these are entries in the deformer table. - // they map vertices on the volume mesh to - // vertices on the avatar mesh(es). - struct LLDeformMap - { - U8 mMesh[LL_DEFORMER_WEIGHT_COUNT]; - U16 mVertex[LL_DEFORMER_WEIGHT_COUNT]; - F32 mWeight[LL_DEFORMER_WEIGHT_COUNT]; - }; - - - // the deform table contains precomputed information - // necessary to perform deformation on a volume face in - // realtime. - - class LLDeformTable - { - public: - - std::vector mMap; - std::vector > mBasePositions; - }; - - - // the deform table cache holds tables for each face and mesh asset ID - typedef std::map deform_cache_t; - deform_cache_t mDeformCache; - - - // apply deformation to source volume and store it in this volume - BOOL deform(LLVolume* source, LLVOAvatar* avatar, const LLMeshSkinInfo* skin, S32 face, LLPointer drawable); - - // look-up the cached deform table - LLDeformTable* getDeformTable(LLVolume* source, LLVOAvatar* avatar, const LLMeshSkinInfo* skin, - S32 face, LLPointer drawable); - - // compute the cached deform table - void computeDeformTable(LLPointer request); - -}; -// - - // Base class for implementations of the volume - Primitive, Flexible Object, etc. class LLVolumeInterface { @@ -419,11 +332,6 @@ public: //clear out rigged volume and revert back to non-rigged state for picking/LOD/distance updates void clearRiggedVolume(); - // Qarl's mesh deformer - // deformed volume (rigged attachments follow avatar morph shape changes - LLDeformedVolume* getDeformedVolume(); - // - protected: S32 computeLODDetail(F32 distance, F32 radius); BOOL calcLOD(); @@ -469,7 +377,6 @@ private: S32 mMDCImplCount; LLPointer mRiggedVolume; - LLPointer mDeformedVolume; // Qarl's mesh deformer // statics public: diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 520618eebb..6d9aeb7be0 100755 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -275,7 +275,7 @@ Additional code generously contributed to Firestorm by: top_pad="4" width="420" wrap="true"> -Albatroz Hird, Alexie Birman, Andromeda Rage, Armin Weatherwax, Casper Warden, Chalice Yao, Cron Stardust, Damian Zhaoying, Dawa Gurbux, Felyza Wishbringer, f0rbidden, Fractured Crystal, Geenz Spad, Hitomi Tiponi, Inworldz LLC, Karl Stiefvater, Katharine Berry, Kittin Ninetails, Kool Koolhoven, Lance Corrimal, Magne Metaverse LLC, Magus Freston, Manami Hokkigai, MartinRJ Fayray, Melancholy Lemon, Miguael Liamano, Mimika Oh, Mister Acacia, Mysty Saunders, Nagi Michinaga, Name Short, nhede Core, NiranV Dean, Nogardrevlis Lectar, paperwork, Peyton Menges, programmtest, Qwerty Venom, Revolution Smythe, Sahkolihaa Contepomi, sal Kaligawa, Satomi Ahn, Sei Lisa, Shin Wasp, Shyotl Kuhr, Sione Lomu, Skills Hak, StarlightShining, Sunset Faulkes, Thickbrick Sleaford, Vaalith Jinn, Whirly Fizzle, Zwagoth Klaar and others. +Albatroz Hird, Alexie Birman, Andromeda Rage, Armin Weatherwax, Casper Warden, Chalice Yao, Cron Stardust, Damian Zhaoying, Dawa Gurbux, Felyza Wishbringer, f0rbidden, Fractured Crystal, Geenz Spad, Hitomi Tiponi, Katharine Berry, Kittin Ninetails, Kool Koolhoven, Lance Corrimal, Magne Metaverse LLC, Magus Freston, Manami Hokkigai, MartinRJ Fayray, Melancholy Lemon, Miguael Liamano, Mimika Oh, Mister Acacia, Mysty Saunders, Nagi Michinaga, Name Short, nhede Core, NiranV Dean, Nogardrevlis Lectar, paperwork, Peyton Menges, programmtest, Qwerty Venom, Revolution Smythe, Sahkolihaa Contepomi, sal Kaligawa, Satomi Ahn, Sei Lisa, Shin Wasp, Shyotl Kuhr, Sione Lomu, Skills Hak, StarlightShining, Sunset Faulkes, Thickbrick Sleaford, Vaalith Jinn, Whirly Fizzle, Zwagoth Klaar and others. - - - - - -