commit
87b34fb742
|
|
@ -34,6 +34,7 @@ set(llprimitive_HEADER_FILES
|
|||
lldaeloader.h
|
||||
llgltfloader.h
|
||||
llgltfmaterial.h
|
||||
llgltfmaterial_templates.h
|
||||
legacy_object_types.h
|
||||
llmaterial.h
|
||||
llmaterialid.h
|
||||
|
|
|
|||
|
|
@ -24,25 +24,28 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llgltfmaterial.h"
|
||||
|
||||
#include "llsdserialize.h"
|
||||
|
||||
// NOTE -- this should be the one and only place tiny_gltf.h is included
|
||||
#include "tinygltf/tiny_gltf.h"
|
||||
#include "llgltfmaterial_templates.h"
|
||||
|
||||
const char* const LLGLTFMaterial::ASSET_VERSION = "1.1";
|
||||
const char* const LLGLTFMaterial::ASSET_TYPE = "GLTF 2.0";
|
||||
const std::array<std::string, 2> LLGLTFMaterial::ACCEPTED_ASSET_VERSIONS = { "1.0", "1.1" };
|
||||
|
||||
const char* const GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform";
|
||||
const char* const GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale";
|
||||
const char* const GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset";
|
||||
const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation";
|
||||
const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform";
|
||||
const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale";
|
||||
const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset";
|
||||
const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation";
|
||||
|
||||
// special UUID that indicates a null UUID in override data
|
||||
static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
|
||||
const LLUUID LLGLTFMaterial::GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
|
||||
|
||||
void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8]) const
|
||||
{
|
||||
|
|
@ -68,14 +71,14 @@ LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs)
|
|||
|
||||
LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
|
||||
{
|
||||
//have to do a manual operator= because of LLRefCount
|
||||
//have to do a manual operator= because of LLRefCount
|
||||
mTextureId = rhs.mTextureId;
|
||||
|
||||
mTextureTransform = rhs.mTextureTransform;
|
||||
|
||||
mBaseColor = rhs.mBaseColor;
|
||||
mEmissiveColor = rhs.mEmissiveColor;
|
||||
|
||||
|
||||
mMetallicFactor = rhs.mMetallicFactor;
|
||||
mRoughnessFactor = rhs.mRoughnessFactor;
|
||||
mAlphaCutoff = rhs.mAlphaCutoff;
|
||||
|
|
@ -97,7 +100,7 @@ bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
|
|||
|
||||
mBaseColor == rhs.mBaseColor &&
|
||||
mEmissiveColor == rhs.mEmissiveColor &&
|
||||
|
||||
|
||||
mMetallicFactor == rhs.mMetallicFactor &&
|
||||
mRoughnessFactor == rhs.mRoughnessFactor &&
|
||||
mAlphaCutoff == rhs.mAlphaCutoff &&
|
||||
|
|
@ -122,6 +125,7 @@ bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, st
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -190,7 +194,8 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index)
|
|||
}
|
||||
}
|
||||
|
||||
LLVector2 vec2_from_json(const tinygltf::Value::Object& object, const char* key, const LLVector2& default_value)
|
||||
// static
|
||||
LLVector2 LLGLTFMaterial::vec2FromJson(const tinygltf::Value::Object& object, const char* key, const LLVector2& default_value)
|
||||
{
|
||||
const auto it = object.find(key);
|
||||
if (it == object.end())
|
||||
|
|
@ -215,7 +220,8 @@ LLVector2 vec2_from_json(const tinygltf::Value::Object& object, const char* key,
|
|||
return value;
|
||||
}
|
||||
|
||||
F32 float_from_json(const tinygltf::Value::Object& object, const char* key, const F32 default_value)
|
||||
// static
|
||||
F32 LLGLTFMaterial::floatFromJson(const tinygltf::Value::Object& object, const char* key, const F32 default_value)
|
||||
{
|
||||
const auto it = object.find(key);
|
||||
if (it == object.end())
|
||||
|
|
@ -230,52 +236,6 @@ F32 float_from_json(const tinygltf::Value::Object& object, const char* key, cons
|
|||
return (F32)real_json.GetNumberAsDouble();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string gltf_get_texture_image(const tinygltf::Model& model, const T& texture_info)
|
||||
{
|
||||
const S32 texture_idx = texture_info.index;
|
||||
if (texture_idx < 0 || texture_idx >= model.textures.size())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
const tinygltf::Texture& texture = model.textures[texture_idx];
|
||||
|
||||
// Ignore texture.sampler for now
|
||||
|
||||
const S32 image_idx = texture.source;
|
||||
if (image_idx < 0 || image_idx >= model.images.size())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
const tinygltf::Image& image = model.images[image_idx];
|
||||
|
||||
return image.uri;
|
||||
}
|
||||
|
||||
// *NOTE: Use template here as workaround for the different similar texture info classes
|
||||
template<typename T>
|
||||
void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
const std::string uri = gltf_get_texture_image(model, texture_info);
|
||||
mTextureId[texture_info_id].set(uri);
|
||||
|
||||
const tinygltf::Value::Object& extensions_object = texture_info.extensions;
|
||||
const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM);
|
||||
if (transform_it != extensions_object.end())
|
||||
{
|
||||
const tinygltf::Value& transform_json = std::get<1>(*transform_it);
|
||||
if (transform_json.IsObject())
|
||||
{
|
||||
const tinygltf::Value::Object& transform_object = transform_json.Get<tinygltf::Value::Object>();
|
||||
TextureTransform& transform = mTextureTransform[texture_info_id];
|
||||
transform.mOffset = vec2_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_OFFSET, getDefaultTextureOffset());
|
||||
transform.mScale = vec2_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_SCALE, getDefaultTextureScale());
|
||||
transform.mRotation = float_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_ROTATION, getDefaultTextureRotation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
|
@ -302,7 +262,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
|
|||
|
||||
material_out.alphaMode = getAlphaMode();
|
||||
material_out.alphaCutoff = mAlphaCutoff;
|
||||
|
||||
|
||||
mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor);
|
||||
|
||||
if (mEmissiveColor != LLGLTFMaterial::getDefaultEmissiveColor())
|
||||
|
|
@ -320,7 +280,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
|
|||
tinygltf::Value::Object extras;
|
||||
bool write_extras = false;
|
||||
if (mOverrideAlphaMode && mAlphaMode == getDefaultAlphaMode())
|
||||
{
|
||||
{
|
||||
extras["override_alpha_mode"] = tinygltf::Value(mOverrideAlphaMode);
|
||||
write_extras = true;
|
||||
}
|
||||
|
|
@ -339,57 +299,6 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
|
|||
model.asset.version = "2.0";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void gltf_allocate_texture_image(tinygltf::Model& model, T& texture_info, const std::string& uri)
|
||||
{
|
||||
const S32 image_idx = model.images.size();
|
||||
model.images.emplace_back();
|
||||
model.images[image_idx].uri = uri;
|
||||
|
||||
// The texture, not to be confused with the texture info
|
||||
const S32 texture_idx = model.textures.size();
|
||||
model.textures.emplace_back();
|
||||
tinygltf::Texture& texture = model.textures[texture_idx];
|
||||
texture.source = image_idx;
|
||||
|
||||
texture_info.index = texture_idx;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write) const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
const LLUUID& texture_id = mTextureId[texture_info_id];
|
||||
const TextureTransform& transform = mTextureTransform[texture_info_id];
|
||||
const bool is_blank_transform = transform == sDefault.mTextureTransform[0];
|
||||
// Check if this material matches all the fallback values, and if so, then
|
||||
// skip including it to reduce material size
|
||||
if (!force_write && texture_id.isNull() && is_blank_transform)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// tinygltf will discard this texture info if there is no valid texture,
|
||||
// causing potential loss of information for overrides, so ensure one is
|
||||
// defined. -Cosmic,2023-01-30
|
||||
gltf_allocate_texture_image(model, texture_info, texture_id.asString());
|
||||
|
||||
if (!is_blank_transform)
|
||||
{
|
||||
tinygltf::Value::Object transform_map;
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({
|
||||
tinygltf::Value(transform.mOffset.mV[VX]),
|
||||
tinygltf::Value(transform.mOffset.mV[VY])
|
||||
}));
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({
|
||||
tinygltf::Value(transform.mScale.mV[VX]),
|
||||
tinygltf::Value(transform.mScale.mV[VY])
|
||||
}));
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation);
|
||||
texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::sanitizeAssetMaterial()
|
||||
{
|
||||
mTextureTransform = sDefault.mTextureTransform;
|
||||
|
|
@ -403,19 +312,19 @@ bool LLGLTFMaterial::setBaseMaterial()
|
|||
return *this != old_override;
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::isClearedForBaseMaterial()
|
||||
{
|
||||
LLGLTFMaterial cleared_override = sDefault;
|
||||
cleared_override.setBaseMaterial(*this);
|
||||
return *this == cleared_override;
|
||||
}
|
||||
|
||||
// For material overrides only. Copies transforms from the old override.
|
||||
void LLGLTFMaterial::setBaseMaterial(const LLGLTFMaterial& old_override_mat)
|
||||
{
|
||||
mTextureTransform = old_override_mat.mTextureTransform;
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::isClearedForBaseMaterial() const
|
||||
{
|
||||
LLGLTFMaterial cleared_override = sDefault;
|
||||
cleared_override.setBaseMaterial(*this);
|
||||
return *this == cleared_override;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLGLTFMaterial::hackOverrideUUID(LLUUID& id)
|
||||
|
|
@ -516,7 +425,7 @@ void LLGLTFMaterial::setAlphaMode(const std::string& mode, bool for_override)
|
|||
{
|
||||
m = ALPHA_MODE_BLEND;
|
||||
}
|
||||
|
||||
|
||||
setAlphaMode(m, for_override);
|
||||
}
|
||||
|
||||
|
|
@ -709,7 +618,6 @@ void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& d
|
|||
{
|
||||
data["tex"][i] = LLSD::UUID(override_texture_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (override_mat.mBaseColor != getDefaultBaseColor())
|
||||
|
|
@ -764,23 +672,6 @@ void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& d
|
|||
data["ti"][i]["r"] = override_mat.mTextureTransform[i].mRotation;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
LLSDSerialize::serialize(data, ostr, LLSDSerialize::LLSD_NOTATION);
|
||||
std::string param_str(ostr.str());
|
||||
LL_INFOS() << param_str << LL_ENDL;
|
||||
LL_INFOS() << "Notation size: " << param_str.size() << LL_ENDL;
|
||||
}
|
||||
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
LLSDSerialize::serialize(data, ostr, LLSDSerialize::LLSD_BINARY);
|
||||
std::string param_str(ostr.str());
|
||||
LL_INFOS() << "Binary size: " << param_str.size() << LL_ENDL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,10 +35,13 @@
|
|||
#include "hbxxh.h"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace tinygltf
|
||||
{
|
||||
class Model;
|
||||
struct TextureInfo;
|
||||
class Value;
|
||||
}
|
||||
|
||||
class LLTextureEntry;
|
||||
|
|
@ -52,6 +55,9 @@ public:
|
|||
|
||||
static const char* const ASSET_VERSION;
|
||||
static const char* const ASSET_TYPE;
|
||||
// Max allowed size of a GLTF material asset or override, when serialized
|
||||
// as a minified JSON string
|
||||
static constexpr size_t MAX_ASSET_LENGTH = 2048;
|
||||
static const std::array<std::string, 2> ACCEPTED_ASSET_VERSIONS;
|
||||
static bool isAcceptedVersion(const std::string& version) { return std::find(ACCEPTED_ASSET_VERSIONS.cbegin(), ACCEPTED_ASSET_VERSIONS.cend(), version) != ACCEPTED_ASSET_VERSIONS.cend(); }
|
||||
|
||||
|
|
@ -64,6 +70,7 @@ public:
|
|||
void getPacked(F32 (&packed)[8]) const;
|
||||
|
||||
bool operator==(const TextureTransform& other) const;
|
||||
bool operator!=(const TextureTransform& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
enum AlphaMode
|
||||
|
|
@ -96,8 +103,13 @@ public:
|
|||
GLTF_TEXTURE_INFO_COUNT
|
||||
};
|
||||
|
||||
std::array<LLUUID, GLTF_TEXTURE_INFO_COUNT> mTextureId;
|
||||
static const char* const GLTF_FILE_EXTENSION_TRANSFORM;
|
||||
static const char* const GLTF_FILE_EXTENSION_TRANSFORM_SCALE;
|
||||
static const char* const GLTF_FILE_EXTENSION_TRANSFORM_OFFSET;
|
||||
static const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION;
|
||||
static const LLUUID GLTF_OVERRIDE_NULL_UUID;
|
||||
|
||||
std::array<LLUUID, GLTF_TEXTURE_INFO_COUNT> mTextureId;
|
||||
std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform;
|
||||
|
||||
// NOTE: initialize values to defaults according to the GLTF spec
|
||||
|
|
@ -137,7 +149,7 @@ public:
|
|||
void setAlphaMode(S32 mode, bool for_override = false);
|
||||
void setDoubleSided(bool double_sided, bool for_override = false);
|
||||
|
||||
//NOTE: texture offsets only exist in overrides, so "for_override" is not needed
|
||||
// *NOTE: texture offsets only exist in overrides, so "for_override" is not needed
|
||||
|
||||
void setTextureOffset(TextureInfo texture_info, const LLVector2& offset);
|
||||
void setTextureScale(TextureInfo texture_info, const LLVector2& scale);
|
||||
|
|
@ -155,7 +167,6 @@ public:
|
|||
static LLVector2 getDefaultTextureScale();
|
||||
static F32 getDefaultTextureRotation();
|
||||
|
||||
|
||||
static void hackOverrideUUID(LLUUID& id);
|
||||
static void applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id);
|
||||
|
||||
|
|
@ -164,7 +175,7 @@ public:
|
|||
void setAlphaMode(const std::string& mode, bool for_override = false);
|
||||
|
||||
const char* getAlphaMode() const;
|
||||
|
||||
|
||||
// set the contents of this LLGLTFMaterial from the given json
|
||||
// returns true if successful
|
||||
// if unsuccessful, the contents of this LLGLTFMaterial should be left unchanged and false is returned
|
||||
|
|
@ -176,7 +187,6 @@ public:
|
|||
// get the contents of this LLGLTFMaterial as a json string
|
||||
std::string asJSON(bool prettyprint = false) const;
|
||||
|
||||
|
||||
// initialize from given tinygltf::Model
|
||||
// model - the model to reference
|
||||
// mat_index - index of material in model's material array
|
||||
|
|
@ -202,21 +212,29 @@ public:
|
|||
// For material overrides only. Clears most properties to
|
||||
// default/fallthrough, but preserves the transforms.
|
||||
bool setBaseMaterial();
|
||||
void setBaseMaterial(const LLGLTFMaterial& old_override_mat);
|
||||
// True if setBaseMaterial() was just called
|
||||
bool isClearedForBaseMaterial();
|
||||
bool isClearedForBaseMaterial() const;
|
||||
|
||||
// For local materials, they have to keep track of where
|
||||
// they are assigned to for full updates
|
||||
virtual void addTextureEntry(LLTextureEntry* te) {};
|
||||
virtual void removeTextureEntry(LLTextureEntry* te) {};
|
||||
|
||||
private:
|
||||
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);
|
||||
|
||||
template<typename T>
|
||||
static void allocateTextureImage(tinygltf::Model& model, T& texture_info, const std::string& uri);
|
||||
|
||||
template<typename T>
|
||||
void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id);
|
||||
template<typename T>
|
||||
static void setFromTexture(const tinygltf::Model& model, const T& texture_info, LLUUID& texture_id, TextureTransform& transform);
|
||||
|
||||
template<typename T>
|
||||
void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const;
|
||||
|
||||
void setBaseMaterial(const LLGLTFMaterial& old_override_mat);
|
||||
template<typename T>
|
||||
static void writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write = false);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
/**
|
||||
* @file llgltfmaterial_templates.h
|
||||
* @brief Material template definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, 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$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "llgltfmaterial.h"
|
||||
|
||||
// Use templates here as workaround for the different similar texture info classes in tinygltf
|
||||
// Includer must first include tiny_gltf.h with the desired flags
|
||||
|
||||
template<typename T>
|
||||
std::string gltf_get_texture_image(const tinygltf::Model& model, const T& texture_info)
|
||||
{
|
||||
const S32 texture_idx = texture_info.index;
|
||||
if (texture_idx < 0 || texture_idx >= model.textures.size())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
const tinygltf::Texture& texture = model.textures[texture_idx];
|
||||
|
||||
// Ignore texture.sampler for now
|
||||
|
||||
const S32 image_idx = texture.source;
|
||||
if (image_idx < 0 || image_idx >= model.images.size())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
const tinygltf::Image& image = model.images[image_idx];
|
||||
|
||||
return image.uri;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id)
|
||||
{
|
||||
setFromTexture(model, texture_info, mTextureId[texture_info_id], mTextureTransform[texture_info_id]);
|
||||
const std::string uri = gltf_get_texture_image(model, texture_info);
|
||||
}
|
||||
|
||||
// static
|
||||
template<typename T>
|
||||
void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, LLUUID& texture_id, TextureTransform& transform)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
const std::string uri = gltf_get_texture_image(model, texture_info);
|
||||
texture_id.set(uri);
|
||||
|
||||
const tinygltf::Value::Object& extensions_object = texture_info.extensions;
|
||||
const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM);
|
||||
if (transform_it != extensions_object.end())
|
||||
{
|
||||
const tinygltf::Value& transform_json = std::get<1>(*transform_it);
|
||||
if (transform_json.IsObject())
|
||||
{
|
||||
const tinygltf::Value::Object& transform_object = transform_json.Get<tinygltf::Value::Object>();
|
||||
transform.mOffset = vec2FromJson(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_OFFSET, getDefaultTextureOffset());
|
||||
transform.mScale = vec2FromJson(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_SCALE, getDefaultTextureScale());
|
||||
transform.mRotation = floatFromJson(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_ROTATION, getDefaultTextureRotation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
template<typename T>
|
||||
void LLGLTFMaterial::allocateTextureImage(tinygltf::Model& model, T& texture_info, const std::string& uri)
|
||||
{
|
||||
const S32 image_idx = model.images.size();
|
||||
model.images.emplace_back();
|
||||
model.images[image_idx].uri = uri;
|
||||
|
||||
// The texture, not to be confused with the texture info
|
||||
const S32 texture_idx = model.textures.size();
|
||||
model.textures.emplace_back();
|
||||
tinygltf::Texture& texture = model.textures[texture_idx];
|
||||
texture.source = image_idx;
|
||||
|
||||
texture_info.index = texture_idx;
|
||||
}
|
||||
|
||||
// static
|
||||
template<typename T>
|
||||
void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write) const
|
||||
{
|
||||
writeToTexture(model, texture_info, mTextureId[texture_info_id], mTextureTransform[texture_info_id], force_write);
|
||||
}
|
||||
|
||||
// static
|
||||
template<typename T>
|
||||
void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
const bool is_blank_transform = transform == sDefault.mTextureTransform[0];
|
||||
// Check if this material matches all the fallback values, and if so, then
|
||||
// skip including it to reduce material size
|
||||
if (!force_write && texture_id.isNull() && is_blank_transform)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// tinygltf will discard this texture info if there is no valid texture,
|
||||
// causing potential loss of information for overrides, so ensure one is
|
||||
// defined. -Cosmic,2023-01-30
|
||||
allocateTextureImage(model, texture_info, texture_id.asString());
|
||||
|
||||
if (!is_blank_transform)
|
||||
{
|
||||
tinygltf::Value::Object transform_map;
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({
|
||||
tinygltf::Value(transform.mOffset.mV[VX]),
|
||||
tinygltf::Value(transform.mOffset.mV[VY])
|
||||
}));
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({
|
||||
tinygltf::Value(transform.mScale.mV[VX]),
|
||||
tinygltf::Value(transform.mScale.mV[VY])
|
||||
}));
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation);
|
||||
texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue