Fixes texture transforms being reset when switching from Blinn-Phong to PBR materials and between PBR. Previously, custom scale, offset, and rotation settings would be lost, making it tedious to switch between PBR materials.master
parent
a54a96a1f4
commit
5fe152cfea
|
|
@ -923,3 +923,34 @@ void LLGLTFMaterial::updateTextureTracking()
|
|||
// setTEGLTFMaterialOverride is responsible for tracking
|
||||
// for material overrides editor will set it
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::convertTextureTransformToPBR(
|
||||
F32 tex_scale_s,
|
||||
F32 tex_scale_t,
|
||||
F32 tex_offset_s,
|
||||
F32 tex_offset_t,
|
||||
F32 tex_rotation,
|
||||
LLVector2& pbr_scale,
|
||||
LLVector2& pbr_offset,
|
||||
F32& pbr_rotation)
|
||||
{
|
||||
pbr_scale.set(tex_scale_s, tex_scale_t);
|
||||
pbr_rotation = -(tex_rotation) / 2.f;
|
||||
const F32 adjusted_offset_s = tex_offset_s;
|
||||
const F32 adjusted_offset_t = -tex_offset_t;
|
||||
F32 center_adjust_s = 0.5f * (1.0f - tex_scale_s);
|
||||
F32 center_adjust_t = 0.5f * (1.0f - tex_scale_t);
|
||||
|
||||
if (pbr_rotation != 0.0f)
|
||||
{
|
||||
const F32 c = cosf(pbr_rotation);
|
||||
const F32 s = sinf(pbr_rotation);
|
||||
const F32 tmp_s = center_adjust_s * c - center_adjust_t * s;
|
||||
const F32 tmp_t = center_adjust_s * s + center_adjust_t * c;
|
||||
center_adjust_s = tmp_s;
|
||||
center_adjust_t = tmp_t;
|
||||
}
|
||||
|
||||
pbr_offset.set(adjusted_offset_s + center_adjust_s,
|
||||
adjusted_offset_t + center_adjust_t);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,6 +214,14 @@ public:
|
|||
bool hasLocalTextures() { return !mTrackingIdToLocalTexture.empty(); }
|
||||
virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id);
|
||||
virtual void updateTextureTracking();
|
||||
|
||||
// Convert legacy TE transform values to PBR transform values.
|
||||
static void convertTextureTransformToPBR(F32 tex_scale_s, F32 tex_scale_t,
|
||||
F32 tex_offset_s, F32 tex_offset_t,
|
||||
F32 tex_rotation,
|
||||
LLVector2& pbr_scale,
|
||||
LLVector2& pbr_offset,
|
||||
F32& pbr_rotation);
|
||||
protected:
|
||||
static LLVector2 vec2FromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const LLVector2& default_value);
|
||||
static F32 floatFromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const F32 default_value);
|
||||
|
|
|
|||
|
|
@ -380,17 +380,6 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L
|
|||
LLGLTFMaterial* material = new LLGLTFMaterial(*material_override);
|
||||
sApplyQueue.push_back({ obj->getID(), side, asset_id, material });
|
||||
}
|
||||
|
||||
if (sUpdates.size() >= MAX_TASK_UPDATES)
|
||||
{
|
||||
LLCoros::instance().launch("modifyMaterialCoro",
|
||||
std::bind(&LLGLTFMaterialList::modifyMaterialCoro,
|
||||
gAgent.getRegionCapability("ModifyMaterialParams"),
|
||||
sUpdates,
|
||||
std::shared_ptr<CallbackHolder>(nullptr)));
|
||||
|
||||
sUpdates = LLSD::emptyArray();
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterialList::queueUpdate(const LLSD& data)
|
||||
|
|
|
|||
|
|
@ -1996,9 +1996,96 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
|
|||
asset_id = BLANK_MATERIAL_ASSET_ID;
|
||||
}
|
||||
}
|
||||
|
||||
// If this face already has the target material ID, do nothing.
|
||||
// This prevents re-sending the same ID on OK, which can cause the server
|
||||
// to drop overrides when queueApply is invoked with the OLD id.
|
||||
if (objectp->getRenderMaterialID(te) == asset_id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Preserve existing texture transforms when switching to PBR material
|
||||
LLTextureEntry* tep = objectp->getTE(te);
|
||||
bool should_preserve_transforms = false;
|
||||
LLGLTFMaterial* preserved_override = nullptr;
|
||||
|
||||
if (tep && asset_id.notNull())
|
||||
{
|
||||
// Only preserve transforms from existing GLTF material override
|
||||
// Do not fall back to texture entry transforms when switching between PBR materials
|
||||
LLGLTFMaterial* existing_override = tep->getGLTFMaterialOverride();
|
||||
if (existing_override)
|
||||
{
|
||||
// Check if existing override has non-default transforms
|
||||
const LLGLTFMaterial::TextureTransform& existing_transform = existing_override->mTextureTransform[0];
|
||||
const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
|
||||
|
||||
if (existing_transform.mScale != default_transform.mScale ||
|
||||
existing_transform.mOffset != default_transform.mOffset ||
|
||||
existing_transform.mRotation != default_transform.mRotation)
|
||||
{
|
||||
// Preserve non-default transforms from current PBR material
|
||||
preserved_override = new LLGLTFMaterial();
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
preserved_override->mTextureTransform[i].mScale = existing_transform.mScale;
|
||||
preserved_override->mTextureTransform[i].mOffset = existing_transform.mOffset;
|
||||
preserved_override->mTextureTransform[i].mRotation = existing_transform.mRotation;
|
||||
}
|
||||
should_preserve_transforms = true;
|
||||
}
|
||||
// If existing override has default transforms, don't preserve anything
|
||||
}
|
||||
else
|
||||
{
|
||||
// No existing PBR material override - check texture entry transforms
|
||||
// This handles the case of switching from Blinn-Phong to PBR material
|
||||
F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation;
|
||||
tep->getScale(&existing_scale_s, &existing_scale_t);
|
||||
tep->getOffset(&existing_offset_s, &existing_offset_t);
|
||||
existing_rotation = tep->getRotation();
|
||||
|
||||
const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
|
||||
if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] ||
|
||||
existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] ||
|
||||
existing_rotation != default_transform.mRotation)
|
||||
{
|
||||
// Preserve non-default transforms from texture entry
|
||||
preserved_override = new LLGLTFMaterial();
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
LLVector2 pbr_scale, pbr_offset;
|
||||
F32 pbr_rotation;
|
||||
LLGLTFMaterial::convertTextureTransformToPBR(
|
||||
existing_scale_s, existing_scale_t,
|
||||
existing_offset_s, existing_offset_t,
|
||||
existing_rotation,
|
||||
pbr_scale, pbr_offset, pbr_rotation);
|
||||
preserved_override->mTextureTransform[i].mScale = pbr_scale;
|
||||
preserved_override->mTextureTransform[i].mOffset = pbr_offset;
|
||||
preserved_override->mTextureTransform[i].mRotation = pbr_rotation;
|
||||
}
|
||||
should_preserve_transforms = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objectp->clearTEWaterExclusion(te);
|
||||
// Blank out most override data on the object and send to server
|
||||
objectp->setRenderMaterialID(te, asset_id);
|
||||
if (should_preserve_transforms && preserved_override)
|
||||
{
|
||||
// Apply material with preserved transforms
|
||||
LLGLTFMaterialList::queueApply(objectp, te, asset_id, preserved_override);
|
||||
// Update local state
|
||||
objectp->setRenderMaterialID(te, asset_id, false, true);
|
||||
tep->setGLTFMaterialOverride(preserved_override);
|
||||
}
|
||||
else
|
||||
{
|
||||
objectp->setRenderMaterialID(te, asset_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
// library headers
|
||||
#include "llnotificationsutil.h"
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
// project headers
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
|
|
@ -1297,7 +1299,89 @@ void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj,
|
|||
asset_id = BLANK_MATERIAL_ASSET_ID;
|
||||
}
|
||||
|
||||
hit_obj->setRenderMaterialID(hit_face, asset_id);
|
||||
// Preserve existing texture transforms when switching to PBR material
|
||||
LLTextureEntry* tep = hit_obj->getTE(hit_face);
|
||||
F32 existing_scale_s = LLGLTFMaterial::TextureTransform().mScale.mV[0];
|
||||
F32 existing_scale_t = LLGLTFMaterial::TextureTransform().mScale.mV[1];
|
||||
F32 existing_offset_s = LLGLTFMaterial::TextureTransform().mOffset.mV[0];
|
||||
F32 existing_offset_t = LLGLTFMaterial::TextureTransform().mOffset.mV[1];
|
||||
F32 existing_rotation = LLGLTFMaterial::TextureTransform().mRotation;
|
||||
bool should_preserve_transforms = false;
|
||||
LLGLTFMaterial* preserved_override = nullptr;
|
||||
|
||||
if (tep && asset_id.notNull())
|
||||
{
|
||||
// Only preserve transforms from existing GLTF material override
|
||||
// Do not fall back to texture entry transforms when switching between PBR materials
|
||||
LLGLTFMaterial* existing_override = tep->getGLTFMaterialOverride();
|
||||
if (existing_override)
|
||||
{
|
||||
// Check if existing override has non-default transforms
|
||||
const LLGLTFMaterial::TextureTransform& existing_transform = existing_override->mTextureTransform[0];
|
||||
const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
|
||||
|
||||
if (existing_transform.mScale != default_transform.mScale ||
|
||||
existing_transform.mOffset != default_transform.mOffset ||
|
||||
existing_transform.mRotation != default_transform.mRotation)
|
||||
{
|
||||
// Preserve non-default transforms from current PBR material
|
||||
preserved_override = new LLGLTFMaterial();
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
preserved_override->mTextureTransform[i].mScale = existing_transform.mScale;
|
||||
preserved_override->mTextureTransform[i].mOffset = existing_transform.mOffset;
|
||||
preserved_override->mTextureTransform[i].mRotation = existing_transform.mRotation;
|
||||
}
|
||||
should_preserve_transforms = true;
|
||||
}
|
||||
// If existing override has default transforms, don't preserve anything
|
||||
}
|
||||
else
|
||||
{
|
||||
// No existing PBR material override - check texture entry transforms
|
||||
// This handles the case of switching from Blinn-Phong to PBR material
|
||||
F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation;
|
||||
tep->getScale(&existing_scale_s, &existing_scale_t);
|
||||
tep->getOffset(&existing_offset_s, &existing_offset_t);
|
||||
existing_rotation = tep->getRotation();
|
||||
|
||||
const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
|
||||
if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] ||
|
||||
existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] ||
|
||||
existing_rotation != default_transform.mRotation)
|
||||
{
|
||||
// Preserve non-default transforms from texture entry
|
||||
preserved_override = new LLGLTFMaterial();
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
LLVector2 pbr_scale, pbr_offset;
|
||||
F32 pbr_rotation;
|
||||
LLGLTFMaterial::convertTextureTransformToPBR(
|
||||
existing_scale_s, existing_scale_t,
|
||||
existing_offset_s, existing_offset_t,
|
||||
existing_rotation,
|
||||
pbr_scale, pbr_offset, pbr_rotation);
|
||||
preserved_override->mTextureTransform[i].mScale = pbr_scale;
|
||||
preserved_override->mTextureTransform[i].mOffset = pbr_offset;
|
||||
preserved_override->mTextureTransform[i].mRotation = pbr_rotation;
|
||||
}
|
||||
should_preserve_transforms = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (should_preserve_transforms && preserved_override)
|
||||
{
|
||||
// Apply material with preserved transforms
|
||||
LLGLTFMaterialList::queueApply(hit_obj, hit_face, asset_id, preserved_override);
|
||||
// Update local state
|
||||
hit_obj->setRenderMaterialID(hit_face, asset_id, false, true);
|
||||
tep->setGLTFMaterialOverride(preserved_override);
|
||||
}
|
||||
else
|
||||
{
|
||||
hit_obj->setRenderMaterialID(hit_face, asset_id);
|
||||
}
|
||||
|
||||
dialog_refresh_all();
|
||||
|
||||
|
|
@ -1333,7 +1417,134 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
|
|||
asset_id = BLANK_MATERIAL_ASSET_ID;
|
||||
}
|
||||
|
||||
hit_obj->setRenderMaterialIDs(asset_id);
|
||||
// Preserve existing texture transforms when switching to PBR material for all faces
|
||||
std::vector<std::pair<bool, LLGLTFMaterial*>> preserved_transforms(hit_obj->getNumTEs());
|
||||
|
||||
if (asset_id.notNull())
|
||||
{
|
||||
for (S32 te = 0; te < hit_obj->getNumTEs(); ++te)
|
||||
{
|
||||
LLTextureEntry* tep = hit_obj->getTE(te);
|
||||
if (!tep) continue;
|
||||
|
||||
bool should_preserve = false;
|
||||
LLGLTFMaterial* preserved_override = nullptr;
|
||||
|
||||
// Only preserve transforms from existing GLTF material override
|
||||
// Do not fall back to texture entry transforms when switching between PBR materials
|
||||
LLGLTFMaterial* existing_override = tep->getGLTFMaterialOverride();
|
||||
if (existing_override)
|
||||
{
|
||||
// Check if existing override has non-default transforms
|
||||
const LLGLTFMaterial::TextureTransform& existing_transform = existing_override->mTextureTransform[0];
|
||||
const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
|
||||
|
||||
if (existing_transform.mScale != default_transform.mScale ||
|
||||
existing_transform.mOffset != default_transform.mOffset ||
|
||||
existing_transform.mRotation != default_transform.mRotation)
|
||||
{
|
||||
// Preserve non-default transforms from current PBR material
|
||||
preserved_override = new LLGLTFMaterial();
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
preserved_override->mTextureTransform[i].mScale = existing_transform.mScale;
|
||||
preserved_override->mTextureTransform[i].mOffset = existing_transform.mOffset;
|
||||
preserved_override->mTextureTransform[i].mRotation = existing_transform.mRotation;
|
||||
}
|
||||
should_preserve = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Existing override has default transforms, fall back to texture entry
|
||||
F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation;
|
||||
tep->getScale(&existing_scale_s, &existing_scale_t);
|
||||
tep->getOffset(&existing_offset_s, &existing_offset_t);
|
||||
existing_rotation = tep->getRotation();
|
||||
|
||||
if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] ||
|
||||
existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] ||
|
||||
existing_rotation != default_transform.mRotation)
|
||||
{
|
||||
// Preserve non-default transforms from texture entry
|
||||
preserved_override = new LLGLTFMaterial();
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
LLVector2 pbr_scale, pbr_offset;
|
||||
F32 pbr_rotation;
|
||||
LLGLTFMaterial::convertTextureTransformToPBR(
|
||||
existing_scale_s, existing_scale_t,
|
||||
existing_offset_s, existing_offset_t,
|
||||
existing_rotation,
|
||||
pbr_scale, pbr_offset, pbr_rotation);
|
||||
preserved_override->mTextureTransform[i].mScale = pbr_scale;
|
||||
preserved_override->mTextureTransform[i].mOffset = pbr_offset;
|
||||
preserved_override->mTextureTransform[i].mRotation = pbr_rotation;
|
||||
}
|
||||
should_preserve = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No existing PBR material override - check texture entry transforms
|
||||
// This handles the case of switching from Blinn-Phong to PBR material
|
||||
F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation;
|
||||
tep->getScale(&existing_scale_s, &existing_scale_t);
|
||||
tep->getOffset(&existing_offset_s, &existing_offset_t);
|
||||
existing_rotation = tep->getRotation();
|
||||
|
||||
const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
|
||||
if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] ||
|
||||
existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] ||
|
||||
existing_rotation != default_transform.mRotation)
|
||||
{
|
||||
// Preserve non-default transforms from texture entry
|
||||
preserved_override = new LLGLTFMaterial();
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
LLVector2 pbr_scale, pbr_offset;
|
||||
F32 pbr_rotation;
|
||||
LLGLTFMaterial::convertTextureTransformToPBR(
|
||||
existing_scale_s, existing_scale_t,
|
||||
existing_offset_s, existing_offset_t,
|
||||
existing_rotation,
|
||||
pbr_scale, pbr_offset, pbr_rotation);
|
||||
preserved_override->mTextureTransform[i].mScale = pbr_scale;
|
||||
preserved_override->mTextureTransform[i].mOffset = pbr_offset;
|
||||
preserved_override->mTextureTransform[i].mRotation = pbr_rotation;
|
||||
}
|
||||
should_preserve = true;
|
||||
}
|
||||
}
|
||||
|
||||
preserved_transforms[te] = std::make_pair(should_preserve, preserved_override);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply materials with preserved transforms
|
||||
if (asset_id.notNull())
|
||||
{
|
||||
for (S32 te = 0; te < hit_obj->getNumTEs(); ++te)
|
||||
{
|
||||
LLGLTFMaterial* preserved_override = preserved_transforms[te].second;
|
||||
if (preserved_override)
|
||||
{
|
||||
// Apply material with preserved transforms
|
||||
LLGLTFMaterialList::queueApply(hit_obj, te, asset_id, preserved_override);
|
||||
// Update local state
|
||||
hit_obj->setRenderMaterialID(te, asset_id, false, true);
|
||||
hit_obj->getTE(te)->setGLTFMaterialOverride(preserved_override);
|
||||
}
|
||||
else
|
||||
{
|
||||
hit_obj->setRenderMaterialID(te, asset_id, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hit_obj->setRenderMaterialIDs(asset_id);
|
||||
}
|
||||
dialog_refresh_all();
|
||||
// send the update to the simulator
|
||||
hit_obj->sendTEUpdate();
|
||||
|
|
|
|||
Loading…
Reference in New Issue