summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-09-15 17:23:34 -0500
committerDave Parks <davep@lindenlab.com>2022-09-15 17:23:34 -0500
commit82ab5f9765ad76c73d1d7ddd5716b22d6b92bf62 (patch)
tree80008bf0bfa44df1d962c5d030c0a7be787ce2fb
parente61b6570b15e5d7843712ea65e11c3df42bf4f81 (diff)
SL-18156 WIP -- Add NormalizedScale/NormalizedTranslation to mesh assets to recover mesh's original coordinate frame when generating tangents post download.
-rw-r--r--indra/llmath/llvolume.cpp78
-rw-r--r--indra/llmath/llvolume.h6
-rw-r--r--indra/llprimitive/llmodel.cpp13
-rw-r--r--indra/newview/llmodelpreview.cpp9
4 files changed, 81 insertions, 25 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 563a325f03..ae753fc0f3 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2483,6 +2483,24 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]);
max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]);
+ //unpack normalized scale/translation
+ if (mdl[i].has("NormalizedScale"))
+ {
+ face.mNormalizedScale.setValue(mdl[i]["NormalizedScale"]);
+ }
+ else
+ {
+ face.mNormalizedScale.set(1, 1, 1);
+ }
+ if (mdl[i].has("NormalizedTranslation"))
+ {
+ face.mNormalizedTranslation.setValue(mdl[i]["NormalizedTranslation"]);
+ }
+ else
+ {
+ face.mNormalizedTranslation.set(1, 1, 1);
+ }
+
LLVector4a pos_range;
pos_range.setSub(max_pos, min_pos);
LLVector2 tc_range2 = max_tc - min_tc;
@@ -2533,6 +2551,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
}
+#if 0
{
if (!tangent.empty())
{
@@ -2559,6 +2578,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
}
}
+#endif
{
if (!tc.empty())
@@ -4888,7 +4908,9 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
}
mOptimized = src.mOptimized;
-
+ mNormalizedScale = src.mNormalizedScale;
+ mNormalizedTranslation = src.mNormalizedTranslation;
+
//delete
return *this;
}
@@ -5432,12 +5454,19 @@ struct MikktData
w.resize(count);
}
+
+ LLVector3 inv_scale(1.f / face->mNormalizedScale.mV[0], 1.f / face->mNormalizedScale.mV[1], 1.f / face->mNormalizedScale.mV[2]);
+
+
for (int i = 0; i < face->mNumIndices; ++i)
{
U32 idx = face->mIndices[i];
p[i].set(face->mPositions[idx].getF32ptr());
+ p[i].scaleVec(face->mNormalizedScale); //put mesh in original coordinate frame when reconstructing tangents
n[i].set(face->mNormals[idx].getF32ptr());
+ n[i].scaleVec(inv_scale);
+ n[i].normalize();
tc[i].set(face->mTexCoords[idx]);
if (face->mWeights)
@@ -5481,10 +5510,7 @@ bool LLVolumeFace::cacheOptimize()
ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert)
{
MikktData* data = (MikktData*)pContext->m_pUserData;
- LLVolumeFace* face = data->face;
- S32 idx = face->mIndices[iFace * 3 + iVert];
- auto& vert = face->mPositions[idx];
- F32* v = vert.getF32ptr();
+ F32* v = data->p[iFace * 3 + iVert].mV;
fvPosOut[0] = v[0];
fvPosOut[1] = v[1];
fvPosOut[2] = v[2];
@@ -5493,10 +5519,7 @@ bool LLVolumeFace::cacheOptimize()
ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert)
{
MikktData* data = (MikktData*)pContext->m_pUserData;
- LLVolumeFace* face = data->face;
- S32 idx = face->mIndices[iFace * 3 + iVert];
- auto& norm = face->mNormals[idx];
- F32* n = norm.getF32ptr();
+ F32* n = data->n[iFace * 3 + iVert].mV;
fvNormOut[0] = n[0];
fvNormOut[1] = n[1];
fvNormOut[2] = n[2];
@@ -5505,27 +5528,16 @@ bool LLVolumeFace::cacheOptimize()
ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert)
{
MikktData* data = (MikktData*)pContext->m_pUserData;
- LLVolumeFace* face = data->face;
- S32 idx = face->mIndices[iFace * 3 + iVert];
- auto& tc = face->mTexCoords[idx];
- fvTexcOut[0] = tc.mV[0];
- fvTexcOut[1] = tc.mV[1];
+ F32* tc = data->tc[iFace * 3 + iVert].mV;
+ fvTexcOut[0] = tc[0];
+ fvTexcOut[1] = tc[1];
};
ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert)
{
MikktData* data = (MikktData*)pContext->m_pUserData;
- LLVolumeFace* face = data->face;
S32 i = iFace * 3 + iVert;
- S32 idx = face->mIndices[i];
-
- LLVector3 p(face->mPositions[idx].getF32ptr());
- LLVector3 n(face->mNormals[idx].getF32ptr());
- LLVector3 t(fvTangent);
-
- // assert that this tangent hasn't already been set
- llassert(data->t[i].magVec() < 0.1f);
-
+
data->t[i].set(fvTangent);
data->t[i].mV[3] = fSign;
};
@@ -5585,6 +5597,24 @@ bool LLVolumeFace::cacheOptimize()
mWeights[dst_idx].loadua(data.w[src_idx].mV);
}
}
+
+
+ // put back in normalized coordinate frame
+ LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]);
+ LLVector4a scale;
+ scale.load3(mNormalizedScale.mV);
+ scale.getF32ptr()[3] = 1.f;
+
+ for (int i = 0; i < mNumVertices; ++i)
+ {
+ mPositions[i].mul(inv_scale);
+ mNormals[i].mul(scale);
+ mNormals[i].normalize3();
+ F32 w = mMikktSpaceTangents[i].getF32ptr()[3];
+ mMikktSpaceTangents[i].mul(scale);
+ mMikktSpaceTangents[i].normalize3();
+ mMikktSpaceTangents[i].getF32ptr()[3] = w;
+ }
}
// cache optimize index buffer
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index f1feaade58..e373d0175d 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -984,6 +984,12 @@ public:
//whether or not face has been cache optimized
BOOL mOptimized;
+ // if this is a mesh asset, scale and translation that were applied
+ // when encoding the source mesh into a unit cube
+ // used for regenerating tangents
+ LLVector3 mNormalizedScale = LLVector3(1,1,1);
+ LLVector3 mNormalizedTranslation;
+
private:
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 1ce287d773..ab507edc40 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -337,6 +337,12 @@ void LLModel::normalizeVolumeFaces()
mNormalizedScale.set(normalized_scale.getF32ptr());
mNormalizedTranslation.set(trans.getF32ptr());
mNormalizedTranslation *= -1.f;
+
+ for (auto& face : mVolumeFaces)
+ {
+ face.mNormalizedScale = mNormalizedScale;
+ face.mNormalizedTranslation = mNormalizedTranslation;
+ }
}
}
@@ -749,7 +755,7 @@ LLSD LLModel::writeModel(
U32 vert_idx = 0;
U32 norm_idx = 0;
- U32 tan_idx = 0;
+ //U32 tan_idx = 0;
U32 tc_idx = 0;
LLVector2* ftc = (LLVector2*) face.mTexCoords;
@@ -803,6 +809,7 @@ LLSD LLModel::writeModel(
}
}
+#if 0
if (face.mMikktSpaceTangents)
{ //normals
F32* tangent = face.mMikktSpaceTangents[j].getF32ptr();
@@ -818,6 +825,7 @@ LLSD LLModel::writeModel(
tangents[tan_idx++] = buff[1];
}
}
+#endif
//texcoord
if (face.mTexCoords)
@@ -848,6 +856,9 @@ LLSD LLModel::writeModel(
//write out face data
mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue();
mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue();
+ mdl[model_names[idx]][i]["NormalizedScale"] = face.mNormalizedScale.getValue();
+ mdl[model_names[idx]][i]["NormalizedTranslation"] = face.mNormalizedTranslation.getValue();
+
mdl[model_names[idx]][i]["Position"] = verts;
if (face.mNormals)
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 2c0f0ae443..4a85d459c5 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -1843,6 +1843,15 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
LLModel* target_model = mModel[lod][mdl_idx];
+ // carry over normalized transform into simplified model
+ for (int i = 0; i < base->getNumVolumeFaces(); ++i)
+ {
+ LLVolumeFace& src = base->getVolumeFace(i);
+ LLVolumeFace& dst = target_model->getVolumeFace(i);
+ dst.mNormalizedScale = src.mNormalizedScale;
+ dst.mNormalizedTranslation = src.mNormalizedTranslation;
+ }
+
S32 model_meshopt_mode = meshopt_mode;
// Ideally this should run not per model,