SL-18156 Cleanup of MikktSpace integration, apply MikktSpace tangents to all meshes.

master
Dave Parks 2022-09-23 12:53:24 -05:00
parent 8f1d226865
commit 75de4d3276
7 changed files with 43 additions and 88 deletions

View File

@ -2102,14 +2102,11 @@ void LLVolume::regen()
createVolumeFaces();
}
void LLVolume::genTangents(S32 face, bool mikktspace)
void LLVolume::genTangents(S32 face)
{
// generate legacy tangents for the specified face
// if mikktspace is true, only generate tangents if mikktspace tangents are not present (handles the case for non-mesh prims)
if (!mikktspace || mVolumeFaces[face].mMikktSpaceTangents == nullptr)
{
mVolumeFaces[face].createTangents();
}
llassert(!isMeshAssetLoaded() || mVolumeFaces[face].mTangents != nullptr); // if this is a complete mesh asset, we should already have tangents
mVolumeFaces[face].createTangents();
}
LLVolume::~LLVolume()
@ -2492,15 +2489,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
{
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;
@ -2551,17 +2540,16 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
}
#if 0
#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents
{
if (!tangent.empty())
{
face.allocateTangents(face.mNumVertices, true);
face.allocateTangents(face.mNumVertices);
U16* t = (U16*)&(tangent[0]);
// store incoming tangents in mMikktSpaceTangents
// NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the CLTF shaders to
// NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to
// maintain compliance with the GLTF spec
LLVector4a* t_out = face.mMikktSpaceTangents;
LLVector4a* t_out = face.mTangents;
for (U32 j = 0; j < num_verts; ++j)
{
@ -4111,7 +4099,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
{
if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them
{
genTangents(i);
genTangents(i);
}
if (isUnique())
@ -4854,15 +4842,15 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
mTangents = NULL;
}
if (src.mMikktSpaceTangents)
if (src.mTangents)
{
allocateTangents(src.mNumVertices, true);
LLVector4a::memcpyNonAliased16((F32*)mMikktSpaceTangents, (F32*)src.mMikktSpaceTangents, vert_size);
allocateTangents(src.mNumVertices);
LLVector4a::memcpyNonAliased16((F32*)mTangents, (F32*)src.mTangents, vert_size);
}
else
{
ll_aligned_free_16(mMikktSpaceTangents);
mMikktSpaceTangents = nullptr;
ll_aligned_free_16(mTangents);
mTangents = nullptr;
}
if (src.mWeights)
@ -4909,8 +4897,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
mOptimized = src.mOptimized;
mNormalizedScale = src.mNormalizedScale;
mNormalizedTranslation = src.mNormalizedTranslation;
//delete
return *this;
}
@ -4937,8 +4924,6 @@ void LLVolumeFace::freeData()
mIndices = NULL;
ll_aligned_free_16(mTangents);
mTangents = NULL;
ll_aligned_free_16(mMikktSpaceTangents);
mMikktSpaceTangents = nullptr;
ll_aligned_free_16(mWeights);
mWeights = NULL;
@ -5060,9 +5045,6 @@ void LLVolumeFace::remap()
ll_aligned_free_16(mTangents);
mTangents = NULL;
ll_aligned_free_16(mMikktSpaceTangents);
mMikktSpaceTangents = nullptr;
// Assign new values
mIndices = remap_indices;
mPositions = remap_positions;
@ -5484,10 +5466,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
llassert(!mOptimized);
mOptimized = TRUE;
if (mMikktSpaceTangents == nullptr && gen_tangents && mNormals && mTexCoords)
{ // make sure to generate mikkt space tangents for cache optimizing since the index buffer may change
allocateTangents(mNumVertices, true);
if (gen_tangents && mNormals && mTexCoords)
{ // generate mikkt space tangents before cache optimizing since the index buffer may change
// a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh
// and is executed on a background thread
SMikkTSpaceInterface ms;
ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext)
@ -5573,7 +5555,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
allocateWeights(vert_count);
}
allocateTangents(mNumVertices, true);
allocateTangents(mNumVertices);
for (int i = 0; i < mNumIndices; ++i)
{
@ -5585,7 +5567,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
mNormals[dst_idx].load3(data.n[src_idx].mV);
mTexCoords[dst_idx] = data.tc[src_idx];
mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV);
mTangents[dst_idx].loadua(data.t[src_idx].mV);
if (mWeights)
{
@ -5605,10 +5587,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
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;
F32 w = mTangents[i].getF32ptr()[3];
mTangents[i].mul(scale);
mTangents[i].normalize3();
mTangents[i].getF32ptr()[3] = w;
}
}
@ -5703,7 +5685,6 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs)
llswap(rhs.mPositions, mPositions);
llswap(rhs.mNormals, mNormals);
llswap(rhs.mTangents, mTangents);
llswap(rhs.mMikktSpaceTangents, mMikktSpaceTangents);
llswap(rhs.mTexCoords, mTexCoords);
llswap(rhs.mIndices,mIndices);
llswap(rhs.mNumVertices, mNumVertices);
@ -6415,7 +6396,6 @@ void LLVolumeFace::createTangents()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
if (!mTangents)
{
allocateTangents(mNumVertices);
@ -6539,11 +6519,10 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
mNumVertices++;
}
void LLVolumeFace::allocateTangents(S32 num_verts, bool mikktspace)
void LLVolumeFace::allocateTangents(S32 num_verts)
{
auto& buff = mikktspace ? mMikktSpaceTangents : mTangents;
ll_aligned_free_16(buff);
buff = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
ll_aligned_free_16(mTangents);
mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
}
void LLVolumeFace::allocateWeights(S32 num_verts)

View File

@ -873,7 +873,7 @@ public:
void createTangents();
void resizeVertices(S32 num_verts);
void allocateTangents(S32 num_verts, bool mikktspace = false);
void allocateTangents(S32 num_verts);
void allocateWeights(S32 num_verts);
void allocateJointIndices(S32 num_verts);
void resizeIndices(S32 num_indices);
@ -947,7 +947,6 @@ public:
LLVector4a* mPositions; // Contains vertices, nortmals and texcoords
LLVector4a* mNormals; // pointer into mPositions
LLVector4a* mTangents;
LLVector4a* mMikktSpaceTangents = nullptr; // for GLTF rendering, use mikkt space tangents
LLVector2* mTexCoords; // pointer into mPositions
// mIndices contains mNumIndices amount of elements.
@ -984,7 +983,6 @@ public:
// 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);
@ -1031,7 +1029,7 @@ public:
void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
void regen();
void genTangents(S32 face, bool mikktspace = false);
void genTangents(S32 face);
BOOL isConvex() const;
BOOL isCap(S32 face);

View File

@ -2581,7 +2581,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo
next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod];
next->getVolumeFaces() = remainder;
next->mNormalizedScale = ret->mNormalizedScale;
next->mNormalizedTranslation = ret->mNormalizedTranslation;
if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES)
{
next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end());

View File

@ -53,7 +53,6 @@ const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
LLModel::LLModel(LLVolumeParams& params, F32 detail)
: LLVolume(params, detail),
mNormalizedScale(1,1,1),
mNormalizedTranslation(0,0,0),
mPelvisOffset( 0.0f ),
mStatus(NO_ERRORS),
mSubmodelID(0)
@ -296,7 +295,7 @@ void LLModel::normalizeVolumeFaces()
// the positions to fit within the unit cube.
LLVector4a* pos = (LLVector4a*) face.mPositions;
LLVector4a* norm = (LLVector4a*) face.mNormals;
LLVector4a* t = (LLVector4a*)face.mMikktSpaceTangents;
LLVector4a* t = (LLVector4a*)face.mTangents;
for (U32 j = 0; j < face.mNumVertices; ++j)
{
@ -329,10 +328,10 @@ void LLModel::normalizeVolumeFaces()
mNormalizedTranslation.set(trans.getF32ptr());
mNormalizedTranslation *= -1.f;
// remember normalized scale so original dimensions can be recovered for mesh processing (i.e. tangent generation)
for (auto& face : mVolumeFaces)
{
face.mNormalizedScale = mNormalizedScale;
face.mNormalizedTranslation = mNormalizedTranslation;
}
}
}
@ -800,10 +799,10 @@ LLSD LLModel::writeModel(
}
}
#if 0
if (face.mMikktSpaceTangents)
#if 0 // keep this code for now in case we want to support transporting tangents with mesh assets
if (face.mTangents)
{ //normals
F32* tangent = face.mMikktSpaceTangents[j].getF32ptr();
F32* tangent = face.mTangents[j].getF32ptr();
for (U32 k = 0; k < 4; ++k)
{ //for each component
@ -848,7 +847,6 @@ LLSD LLModel::writeModel(
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;
@ -857,10 +855,12 @@ LLSD LLModel::writeModel(
mdl[model_names[idx]][i]["Normal"] = normals;
}
if (face.mMikktSpaceTangents)
#if 0 // keep this code for now in case we decide to transport tangents with mesh assets
if (face.mTangents)
{
mdl[model_names[idx]][i]["Tangent"] = tangents;
}
#endif
if (face.mTexCoords)
{

View File

@ -10558,17 +10558,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderUseMikktSpace</key>
<map>
<key>Comment</key>
<string>Use Mikkt Space tangents on GLTF materials.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderUseTriStrips</key>
<map>
<key>Comment</key>

View File

@ -1968,24 +1968,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
F32* tangents = (F32*) tangent.get();
LLGLTFMaterial* gltf_mat = tep->getGLTFMaterial();
static LLCachedControl<bool> use_mikktspace(gSavedSettings, "RenderUseMikktSpace");
bool mikktspace = use_mikktspace && gltf_mat != nullptr;
mVObjp->getVolume()->genTangents(f, mikktspace);
mVObjp->getVolume()->genTangents(f);
LLVector4Logical mask;
mask.clear();
mask.setElement<3>();
LLVector4a* tbuff = mikktspace ? vf.mMikktSpaceTangents : vf.mTangents;
if (tbuff == nullptr)
{ // non-mesh prims will not have mikktspace tangents
tbuff = vf.mTangents;
}
LLVector4a* src = tbuff;
LLVector4a* end = tbuff+num_vertices;
LLVector4a* src = vf.mTangents;
LLVector4a* end = vf.mTangents +num_vertices;
while (src < end)
{

View File

@ -1549,7 +1549,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
new_face.resizeIndices(buf_indices_copied);
new_face.resizeVertices(buf_positions_copied);
new_face.allocateTangents(buf_positions_copied, true);
new_face.allocateTangents(buf_positions_copied);
S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size);
@ -1839,7 +1839,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
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;