Remande skeleton translation from default skeleton to overriden skeletonmaster
parent
8322a9a61e
commit
54660c8931
|
|
@ -14,6 +14,7 @@ set(llappearance_SOURCE_FILES
|
|||
llavatarjoint.cpp
|
||||
llavatarjointmesh.cpp
|
||||
lldriverparam.cpp
|
||||
lljointdata.h
|
||||
lllocaltextureobject.cpp
|
||||
llpolyskeletaldistortion.cpp
|
||||
llpolymesh.cpp
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "llavatarappearance.h"
|
||||
#include "llavatarappearancedefines.h"
|
||||
#include "llavatarjointmesh.h"
|
||||
#include "lljointdata.h"
|
||||
#include "llstl.h"
|
||||
#include "lldir.h"
|
||||
#include "llpolymorph.h"
|
||||
|
|
@ -108,11 +109,9 @@ public:
|
|||
|
||||
private:
|
||||
typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t;
|
||||
static void getJointRestMatrices(
|
||||
const bone_info_list_t& bone_list,
|
||||
const std::string &parent_name,
|
||||
LLAvatarAppearance::joint_rest_map_t& rest,
|
||||
LLAvatarAppearance::joint_parent_map_t& parent_map,
|
||||
static void getJointMatricesAndHierarhy(
|
||||
LLAvatarBoneInfo* bone_info,
|
||||
LLJointData& data,
|
||||
const glm::mat4& parent_mat);
|
||||
|
||||
private:
|
||||
|
|
@ -1677,19 +1676,18 @@ bool LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
|
|||
return true;
|
||||
}
|
||||
|
||||
void LLAvatarSkeletonInfo::getJointRestMatrices(
|
||||
const bone_info_list_t& bone_list,
|
||||
const std::string& parent_name,
|
||||
LLAvatarAppearance::joint_rest_map_t& rest,
|
||||
LLAvatarAppearance::joint_parent_map_t& parent_map,
|
||||
void LLAvatarSkeletonInfo::getJointMatricesAndHierarhy(
|
||||
LLAvatarBoneInfo* bone_info,
|
||||
LLJointData& data,
|
||||
const glm::mat4& parent_mat)
|
||||
{
|
||||
for (LLAvatarBoneInfo* bone_info : bone_list)
|
||||
data.mName = bone_info->mName;
|
||||
data.mJointMatrix = bone_info->getJointMatrix();
|
||||
data.mRestMatrix = parent_mat * data.mJointMatrix;
|
||||
for (LLAvatarBoneInfo* child_info : bone_info->mChildren)
|
||||
{
|
||||
glm::mat4 rest_mat = parent_mat * bone_info->getJointMatrix();
|
||||
rest[bone_info->mName] = rest_mat;
|
||||
parent_map[bone_info->mName] = parent_name;
|
||||
getJointRestMatrices(bone_info->mChildren, bone_info->mName, rest, parent_map, rest_mat);
|
||||
LLJointData& child_data = data.mChildren.emplace_back();
|
||||
getJointMatricesAndHierarhy(child_info, child_data, data.mRestMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1754,10 +1752,14 @@ const LLAvatarAppearance::joint_alias_map_t& LLAvatarAppearance::getJointAliases
|
|||
return mJointAliasMap;
|
||||
}
|
||||
|
||||
void LLAvatarAppearance:: getJointRestMatrices(LLAvatarAppearance::joint_rest_map_t& rest_map, LLAvatarAppearance::joint_parent_map_t& parent_map) const
|
||||
void LLAvatarAppearance::getJointMatricesAndHierarhy(std::vector<LLJointData> &data) const
|
||||
{
|
||||
glm::mat4 identity(1.f);
|
||||
LLAvatarSkeletonInfo::getJointRestMatrices(sAvatarSkeletonInfo->mBoneInfoList, std::string(), rest_map, parent_map, identity);
|
||||
for (LLAvatarBoneInfo* bone_info : sAvatarSkeletonInfo->mBoneInfoList)
|
||||
{
|
||||
LLJointData& child_data = data.emplace_back();
|
||||
LLAvatarSkeletonInfo::getJointMatricesAndHierarhy(bone_info, child_data, identity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class LLTexGlobalColorInfo;
|
|||
class LLWearableData;
|
||||
class LLAvatarBoneInfo;
|
||||
class LLAvatarSkeletonInfo;
|
||||
class LLJointData;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLAvatarAppearance
|
||||
|
|
@ -156,7 +157,7 @@ public:
|
|||
const joint_alias_map_t& getJointAliases();
|
||||
typedef std::map<std::string, std::string> joint_parent_map_t; // matrix plus parent
|
||||
typedef std::map<std::string, glm::mat4> joint_rest_map_t;
|
||||
void getJointRestMatrices(joint_rest_map_t& rest_map, joint_parent_map_t& parent_map) const;
|
||||
void getJointMatricesAndHierarhy(std::vector<LLJointData> &data) const;
|
||||
|
||||
protected:
|
||||
static bool parseSkeletonFile(const std::string& filename, LLXmlTree& skeleton_xml_tree);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* @file lljointdata.h
|
||||
* @brief LLJointData class for holding individual joint data and skeleton
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2025, 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_LLJOINTDATA_H
|
||||
#define LL_LLJOINTDATA_H
|
||||
|
||||
#include "v4math.h"
|
||||
|
||||
// may be just move LLAvatarBoneInfo
|
||||
class LLJointData
|
||||
{
|
||||
public:
|
||||
std::string mName;
|
||||
glm::mat4 mJointMatrix;
|
||||
glm::mat4 mRestMatrix;
|
||||
|
||||
typedef std::vector<LLJointData> bones_t;
|
||||
bones_t mChildren;
|
||||
};
|
||||
|
||||
#endif //LL_LLJOINTDATA_H
|
||||
|
|
@ -95,8 +95,7 @@ LLGLTFLoader::LLGLTFLoader(std::string filename,
|
|||
std::map<std::string, std::string> &jointAliasMap,
|
||||
U32 maxJointsPerMesh,
|
||||
U32 modelLimit,
|
||||
joint_viewer_rest_map_t jointRestMatrices,
|
||||
joint_viewer_parent_map_t jointParentMap) //,
|
||||
std::vector<LLJointData> viewer_skeleton) //,
|
||||
//bool preprocess)
|
||||
: LLModelLoader( filename,
|
||||
lod,
|
||||
|
|
@ -113,8 +112,7 @@ LLGLTFLoader::LLGLTFLoader(std::string filename,
|
|||
, mMeshesLoaded(false)
|
||||
, mMaterialsLoaded(false)
|
||||
, mGeneratedModelLimit(modelLimit)
|
||||
, mJointViewerRestMatrices(jointRestMatrices)
|
||||
, mJointViewerParentMap(jointParentMap)
|
||||
, mViewerJointData(viewer_skeleton)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -934,13 +932,45 @@ void LLGLTFLoader::populateJointFromSkin(S32 skin_idx)
|
|||
mAlternateBindMatrices.resize(skin_idx + 1);
|
||||
}
|
||||
|
||||
// Build gltf rest matrices
|
||||
// This is very inefficienct, todo: run from root to children, not from children to root
|
||||
joint_node_mat4_map_t gltf_rest_map;
|
||||
// fill up joints related data
|
||||
joints_data_map_t joints_data;
|
||||
joints_name_to_node_map_t names_to_nodes;
|
||||
for (S32 i = 0; i < joint_count; i++)
|
||||
{
|
||||
S32 joint = skin.mJoints[i];
|
||||
gltf_rest_map[joint] = buildGltfRestMatrix(joint, skin);
|
||||
LL::GLTF::Node jointNode = mGLTFAsset.mNodes[joint];
|
||||
JointNodeData& data = joints_data[joint];
|
||||
data.mNodeIdx = joint;
|
||||
data.mJointListIdx = i;
|
||||
data.mGltfRestMatrix = buildGltfRestMatrix(joint, skin);
|
||||
data.mGltfMatrix = jointNode.mMatrix;
|
||||
data.mOverrideMatrix = glm::mat4(1.f);
|
||||
|
||||
if (mJointMap.find(jointNode.mName) != mJointMap.end())
|
||||
{
|
||||
data.mName = mJointMap[jointNode.mName];
|
||||
data.mIsValidViewerJoint = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.mName = jointNode.mName;
|
||||
data.mIsValidViewerJoint = false;
|
||||
}
|
||||
names_to_nodes[data.mName] = joint;
|
||||
|
||||
for (S32 child : jointNode.mChildren)
|
||||
{
|
||||
JointNodeData& child_data = joints_data[child];
|
||||
child_data.mParentNodeIdx = joint;
|
||||
child_data.mIsParentValidViewerJoint = data.mIsValidViewerJoint;
|
||||
}
|
||||
}
|
||||
|
||||
// Go over viewer joints and build overrides
|
||||
glm::mat4 ident(1.0);
|
||||
for (auto &viewer_data : mViewerJointData)
|
||||
{
|
||||
buildOverrideMatrix(viewer_data, joints_data, names_to_nodes, ident, ident);
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < joint_count; i++)
|
||||
|
|
@ -971,7 +1001,7 @@ void LLGLTFLoader::populateJointFromSkin(S32 skin_idx)
|
|||
// todo: probably should be 'to viewer's overriden skeleton'
|
||||
glm::mat4 original_bind_matrix = glm::inverse(skin.mInverseBindMatricesData[i]);
|
||||
glm::mat4 rotated_original = coord_system_rotation * original_bind_matrix;
|
||||
glm::mat4 skeleton_transform = computeGltfToViewerSkeletonTransform(gltf_rest_map, joint, legal_name);
|
||||
glm::mat4 skeleton_transform = computeGltfToViewerSkeletonTransform(joints_data, joint, legal_name);
|
||||
glm::mat4 tranlated_original = skeleton_transform * rotated_original;
|
||||
glm::mat4 final_inverse_bind_matrix = glm::inverse(tranlated_original);
|
||||
|
||||
|
|
@ -985,7 +1015,7 @@ void LLGLTFLoader::populateJointFromSkin(S32 skin_idx)
|
|||
// assume an identy matrix
|
||||
// todo: find a model with this, might need to use rotated matrix
|
||||
glm::mat4 inv_bind(1.0f);
|
||||
glm::mat4 skeleton_transform = computeGltfToViewerSkeletonTransform(gltf_rest_map, joint, legal_name);
|
||||
glm::mat4 skeleton_transform = computeGltfToViewerSkeletonTransform(joints_data, joint, legal_name);
|
||||
inv_bind = glm::inverse(skeleton_transform * inv_bind);
|
||||
|
||||
LLMatrix4 gltf_transform = LLMatrix4(glm::value_ptr(inv_bind));
|
||||
|
|
@ -994,37 +1024,15 @@ void LLGLTFLoader::populateJointFromSkin(S32 skin_idx)
|
|||
}
|
||||
|
||||
// Compute Alternative matrices also known as overrides
|
||||
|
||||
glm::mat4 joint_mat = glm::mat4(1.f);
|
||||
if (legal_joint)
|
||||
{
|
||||
joint_viewer_parent_map_t::const_iterator found = mJointViewerParentMap.find(legal_name);
|
||||
if (found != mJointViewerParentMap.end() && !found->second.empty())
|
||||
{
|
||||
glm::mat4 gltf_joint_rest_pose = coord_system_rotation * buildGltfRestMatrix(joint, skin);
|
||||
if (mApplyXYRotation)
|
||||
{
|
||||
gltf_joint_rest_pose = coord_system_rotationxy * gltf_joint_rest_pose;
|
||||
}
|
||||
// Compute viewer's override by moving joint to viewer's base
|
||||
// This might be overused or somewhat incorect for regular cases
|
||||
// But this logic should be solid for cases where model lacks
|
||||
// parent joints that viewer has.
|
||||
// ex: like boots that have only knees and feet, but no pelvis,
|
||||
// or anything else, in which case we take viewer's pelvis
|
||||
glm::mat4 viewer_rest = mJointViewerRestMatrices[found->second];
|
||||
joint_mat = glm::inverse(viewer_rest) * gltf_joint_rest_pose;
|
||||
}
|
||||
}
|
||||
LLMatrix4 original_joint_transform(glm::value_ptr(joint_mat));
|
||||
LLMatrix4 original_joint_transform(glm::value_ptr(joints_data[joint].mOverrideMatrix));
|
||||
|
||||
// Viewer seems to care only about translation part,
|
||||
// but for parity with collada taking original value
|
||||
LLMatrix4 newInverse = LLMatrix4(mInverseBindMatrices[skin_idx].back().getF32ptr());
|
||||
newInverse.setTranslation(original_joint_transform.getTranslation());
|
||||
|
||||
LL_INFOS("GLTF_DEBUG") << "mAlternateBindMatrix name: " << legal_name << " val: " << original_joint_transform << LL_ENDL;
|
||||
mAlternateBindMatrices[skin_idx].push_back(LLMatrix4a(original_joint_transform));
|
||||
LL_INFOS("GLTF_DEBUG") << "mAlternateBindMatrix name: " << legal_name << " val: " << newInverse << LL_ENDL;
|
||||
mAlternateBindMatrices[skin_idx].push_back(LLMatrix4a(newInverse));
|
||||
|
||||
if (legal_joint)
|
||||
{
|
||||
|
|
@ -1139,6 +1147,57 @@ S32 LLGLTFLoader::findParentNode(S32 node) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
void LLGLTFLoader::buildOverrideMatrix(LLJointData& viewer_data, joints_data_map_t &gltf_nodes, joints_name_to_node_map_t &names_to_nodes, glm::mat4& parent_rest, glm::mat4& leftover) const
|
||||
{
|
||||
glm::mat4 new_lefover(1.f);
|
||||
glm::mat4 rest(1.f);
|
||||
joints_name_to_node_map_t::iterator found_node = names_to_nodes.find(viewer_data.mName);
|
||||
if (found_node != names_to_nodes.end())
|
||||
{
|
||||
S32 gltf_node_idx = found_node->second;
|
||||
JointNodeData& node = gltf_nodes[gltf_node_idx];
|
||||
node.mIsOverrideValid = true;
|
||||
|
||||
glm::mat4 gltf_joint_rest_pose = coord_system_rotation * node.mGltfRestMatrix;
|
||||
if (mApplyXYRotation)
|
||||
{
|
||||
gltf_joint_rest_pose = coord_system_rotationxy * gltf_joint_rest_pose;
|
||||
}
|
||||
node.mOverrideMatrix = glm::inverse(parent_rest) * gltf_joint_rest_pose;
|
||||
|
||||
glm::vec3 override;
|
||||
glm::vec3 skew;
|
||||
glm::vec3 scale;
|
||||
glm::vec4 perspective;
|
||||
glm::quat rotation;
|
||||
glm::decompose(node.mOverrideMatrix, scale, rotation, override, skew, perspective);
|
||||
glm::vec3 translate;
|
||||
glm::decompose(viewer_data.mJointMatrix, scale, rotation, translate, skew, perspective);
|
||||
glm::mat4 viewer_joint = glm::recompose(scale, rotation, override, skew, perspective);
|
||||
|
||||
node.mOverrideMatrix = viewer_joint;
|
||||
rest = parent_rest * viewer_joint;
|
||||
node.mOverrideRestMatrix = rest;
|
||||
if (viewer_data.mName == "mPelvis")
|
||||
{
|
||||
// Todo: This is wrong, but this is a temporary
|
||||
// solution for parts staying behind.
|
||||
// Something is still missing with override mechanics
|
||||
node.mOverrideMatrix = glm::mat4(1.f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No override for this joint
|
||||
new_lefover = leftover * viewer_data.mJointMatrix;
|
||||
rest = parent_rest * viewer_data.mJointMatrix;
|
||||
}
|
||||
for (LLJointData& child_data : viewer_data.mChildren)
|
||||
{
|
||||
buildOverrideMatrix(child_data, gltf_nodes, names_to_nodes, rest, new_lefover);
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 LLGLTFLoader::buildGltfRestMatrix(S32 joint_node_index, const LL::GLTF::Skin& gltf_skin) const
|
||||
{
|
||||
// This is inefficient since we are recalculating some joints multiple times over
|
||||
|
|
@ -1172,23 +1231,40 @@ glm::mat4 LLGLTFLoader::buildGltfRestMatrix(S32 joint_node_index, const LL::GLTF
|
|||
return node.mMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 LLGLTFLoader::buildGltfRestMatrix(S32 joint_node_index, const joints_data_map_t& joint_data) const
|
||||
{
|
||||
// This is inefficient since we are recalculating some joints multiple times over
|
||||
// Todo: cache it?
|
||||
|
||||
if (joint_node_index < 0 || joint_node_index >= static_cast<S32>(mGLTFAsset.mNodes.size()))
|
||||
{
|
||||
return glm::mat4(1.0f);
|
||||
}
|
||||
|
||||
auto& data = joint_data.at(joint_node_index);
|
||||
|
||||
if (data.mParentNodeIdx >=0)
|
||||
{
|
||||
return buildGltfRestMatrix(data.mParentNodeIdx, joint_data) * data.mGltfMatrix;
|
||||
}
|
||||
// Should we return armature or stop earlier?
|
||||
return data.mGltfMatrix;
|
||||
}
|
||||
|
||||
// This function computes the transformation matrix needed to convert from GLTF skeleton space
|
||||
// to viewer skeleton space for a specific joint
|
||||
|
||||
glm::mat4 LLGLTFLoader::computeGltfToViewerSkeletonTransform(const joint_node_mat4_map_t& gltf_rest_map, S32 gltf_node_index, const std::string& joint_name) const
|
||||
glm::mat4 LLGLTFLoader::computeGltfToViewerSkeletonTransform(const joints_data_map_t& joints_data_map, S32 gltf_node_index, const std::string& joint_name) const
|
||||
{
|
||||
joint_viewer_rest_map_t::const_iterator found = mJointViewerRestMatrices.find(joint_name);
|
||||
if (found == mJointViewerRestMatrices.end())
|
||||
const JointNodeData& node_data = joints_data_map.at(gltf_node_index);
|
||||
if (!node_data.mIsOverrideValid)
|
||||
{
|
||||
// For now assume they are identical and return an identity (for ease of debuging)
|
||||
// But there should be no joints viewer isn't aware about
|
||||
// Warn or assert about missing joints
|
||||
return glm::mat4(1.0f);
|
||||
}
|
||||
glm::mat4 viewer_joint_rest_pose = found->second;
|
||||
|
||||
// Get the GLTF joint's rest pose (in GLTF coordinate system)
|
||||
const glm::mat4 &gltf_joint_rest_pose = gltf_rest_map.at(gltf_node_index);
|
||||
const glm::mat4 &gltf_joint_rest_pose = node_data.mGltfRestMatrix;
|
||||
glm::mat4 rest_pose = coord_system_rotation * gltf_joint_rest_pose;
|
||||
|
||||
LL_INFOS("GLTF_DEBUG") << "rest matrix for joint " << joint_name << ": ";
|
||||
|
|
@ -1199,7 +1275,7 @@ glm::mat4 LLGLTFLoader::computeGltfToViewerSkeletonTransform(const joint_node_ma
|
|||
|
||||
// Compute transformation from GLTF space to viewer space
|
||||
// This assumes both skeletons are in rest pose initially
|
||||
return viewer_joint_rest_pose * glm::inverse(rest_pose);
|
||||
return node_data.mOverrideRestMatrix * glm::inverse(rest_pose);
|
||||
}
|
||||
|
||||
bool LLGLTFLoader::checkForXYrotation(const LL::GLTF::Skin& gltf_skin, S32 joint_idx, S32 bind_indx)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "asset.h"
|
||||
|
||||
#include "llglheaders.h"
|
||||
#include "lljointdata.h"
|
||||
#include "llmodelloader.h"
|
||||
|
||||
// gltf_* structs are temporary, used to organize the subset of data that eventually goes into the material LLSD
|
||||
|
|
@ -125,6 +126,34 @@ class LLGLTFLoader : public LLModelLoader
|
|||
typedef std::map<std::string, glm::mat4> joint_viewer_rest_map_t;
|
||||
typedef std::map<S32, glm::mat4> joint_node_mat4_map_t;
|
||||
|
||||
struct JointNodeData
|
||||
{
|
||||
JointNodeData()
|
||||
: mJointListIdx(-1)
|
||||
, mNodeIdx(-1)
|
||||
, mParentNodeIdx(-1)
|
||||
, mIsValidViewerJoint(false)
|
||||
, mIsParentValidViewerJoint(false)
|
||||
, mIsOverrideValid(false)
|
||||
{
|
||||
|
||||
}
|
||||
S32 mJointListIdx;
|
||||
S32 mNodeIdx;
|
||||
S32 mParentNodeIdx;
|
||||
glm::mat4 mGltfRestMatrix;
|
||||
glm::mat4 mViewerRestMatrix;
|
||||
glm::mat4 mOverrideRestMatrix;
|
||||
glm::mat4 mGltfMatrix;
|
||||
glm::mat4 mOverrideMatrix;
|
||||
std::string mName;
|
||||
bool mIsValidViewerJoint;
|
||||
bool mIsParentValidViewerJoint;
|
||||
bool mIsOverrideValid;
|
||||
};
|
||||
typedef std::map <S32, JointNodeData> joints_data_map_t;
|
||||
typedef std::map <std::string, S32> joints_name_to_node_map_t;
|
||||
|
||||
LLGLTFLoader(std::string filename,
|
||||
S32 lod,
|
||||
LLModelLoader::load_callback_t load_cb,
|
||||
|
|
@ -137,8 +166,7 @@ class LLGLTFLoader : public LLModelLoader
|
|||
std::map<std::string, std::string> &jointAliasMap,
|
||||
U32 maxJointsPerMesh,
|
||||
U32 modelLimit,
|
||||
joint_viewer_rest_map_t jointRestMatrices,
|
||||
joint_viewer_parent_map_t jointParentPap); //,
|
||||
std::vector<LLJointData> viewer_skeleton); //,
|
||||
//bool preprocess );
|
||||
virtual ~LLGLTFLoader();
|
||||
|
||||
|
|
@ -172,8 +200,7 @@ protected:
|
|||
// GLTF isn't aware of viewer's skeleton and uses it's own,
|
||||
// so need to take viewer's joints and use them to
|
||||
// recalculate iverse bind matrices
|
||||
joint_viewer_rest_map_t mJointViewerRestMatrices;
|
||||
joint_viewer_parent_map_t mJointViewerParentMap;
|
||||
std::vector<LLJointData> mViewerJointData;
|
||||
|
||||
// vector of vectors because of a posibility of having more than one skin
|
||||
typedef std::vector<LLMeshSkinInfo::matrix_list_t> bind_matrices_t;
|
||||
|
|
@ -194,8 +221,10 @@ private:
|
|||
S32 findValidRootJointNode(S32 source_joint_node, const LL::GLTF::Skin& gltf_skin) const;
|
||||
S32 findGLTFRootJointNode(const LL::GLTF::Skin& gltf_skin) const; // if there are multiple roots, gltf stores them under one commor joint
|
||||
S32 findParentNode(S32 node) const;
|
||||
void buildOverrideMatrix(LLJointData& data, joints_data_map_t &gltf_nodes, joints_name_to_node_map_t &names_to_nodes, glm::mat4& parent_rest, glm::mat4& leftover) const;
|
||||
glm::mat4 buildGltfRestMatrix(S32 joint_node_index, const LL::GLTF::Skin& gltf_skin) const;
|
||||
glm::mat4 computeGltfToViewerSkeletonTransform(const joint_node_mat4_map_t &gltf_rest_map, S32 gltf_node_index, const std::string& joint_name) const;
|
||||
glm::mat4 buildGltfRestMatrix(S32 joint_node_index, const joints_data_map_t& joint_data) const;
|
||||
glm::mat4 computeGltfToViewerSkeletonTransform(const joints_data_map_t& joints_data_map, S32 gltf_node_index, const std::string& joint_name) const;
|
||||
bool checkForXYrotation(const LL::GLTF::Skin& gltf_skin, S32 joint_idx, S32 bind_indx);
|
||||
void checkForXYrotation(const LL::GLTF::Skin& gltf_skin);
|
||||
LLUUID imageBufferToTextureUUID(const gltf_texture& tex);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "lldrawable.h"
|
||||
#include "llface.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "lljointdata.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "llmeshrepository.h"
|
||||
#include "llmeshoptimizer.h"
|
||||
|
|
@ -811,9 +812,8 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
|
|||
else
|
||||
{
|
||||
LLVOAvatar* av = getPreviewAvatar();
|
||||
LLAvatarAppearance::joint_rest_map_t rest_pose;
|
||||
LLAvatarAppearance::joint_parent_map_t rest_parent_map;
|
||||
av->getJointRestMatrices(rest_pose, rest_parent_map);
|
||||
std::vector<LLJointData> viewer_skeleton;
|
||||
av->getJointMatricesAndHierarhy(viewer_skeleton);
|
||||
mModelLoader = new LLGLTFLoader(
|
||||
filename,
|
||||
lod,
|
||||
|
|
@ -827,8 +827,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
|
|||
joint_alias_map,
|
||||
LLSkinningUtil::getMaxJointCount(),
|
||||
gSavedSettings.getU32("ImporterModelLimit"),
|
||||
rest_pose,
|
||||
rest_parent_map);
|
||||
viewer_skeleton);
|
||||
}
|
||||
|
||||
if (force_disable_slm)
|
||||
|
|
|
|||
Loading…
Reference in New Issue