mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-05 06:20:03 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into one
This commit is contained in:
commit
84cd2a8ef6
20 changed files with 180 additions and 75 deletions
|
@ -435,7 +435,11 @@ void AudioMixer::start() {
|
|||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
int numToRetain = nodeList->size() * (1 - _throttlingRatio);
|
||||
int numToRetain = -1;
|
||||
assert(_throttlingRatio >= 0.0f && _throttlingRatio <= 1.0f);
|
||||
if (_throttlingRatio > EPSILON) {
|
||||
numToRetain = nodeList->size() * (1.0f - _throttlingRatio);
|
||||
}
|
||||
nodeList->nestedEach([&](NodeList::const_iterator cbegin, NodeList::const_iterator cend) {
|
||||
// mix across slave threads
|
||||
auto mixTimer = _mixTiming.timer();
|
||||
|
|
|
@ -416,7 +416,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
|||
// NOTE: Here's where we determine if we are over budget and drop remaining avatars,
|
||||
// or send minimal avatar data in uncommon case of PALIsOpen.
|
||||
int minimRemainingAvatarBytes = minimumBytesPerAvatar * remainingAvatars;
|
||||
bool overBudget = (identityBytesSent + numAvatarDataBytes + minimRemainingAvatarBytes) > maxAvatarBytesPerFrame;
|
||||
auto frameByteEstimate = identityBytesSent + traitBytesSent + numAvatarDataBytes + minimRemainingAvatarBytes;
|
||||
bool overBudget = frameByteEstimate > maxAvatarBytesPerFrame;
|
||||
if (overBudget) {
|
||||
if (PALIsOpen) {
|
||||
_stats.overBudgetAvatars++;
|
||||
|
@ -497,8 +498,11 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
|||
_stats.avatarDataPackingElapsedTime +=
|
||||
(quint64) chrono::duration_cast<chrono::microseconds>(endAvatarDataPacking - startAvatarDataPacking).count();
|
||||
|
||||
// use helper to add any changed traits to our packet list
|
||||
traitBytesSent += addChangedTraitsToBulkPacket(nodeData, otherNodeData, *traitsPacketList);
|
||||
if (!overBudget) {
|
||||
// use helper to add any changed traits to our packet list
|
||||
traitBytesSent += addChangedTraitsToBulkPacket(nodeData, otherNodeData, *traitsPacketList);
|
||||
}
|
||||
|
||||
remainingAvatars--;
|
||||
}
|
||||
|
||||
|
|
|
@ -701,9 +701,9 @@
|
|||
"y": 0.04787999764084816
|
||||
},
|
||||
"position": {
|
||||
"x": -0.53203323516845703,
|
||||
"x": -0.59333323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": -0.07286686894893646
|
||||
"z": 0.037454843521118164
|
||||
},
|
||||
"modelURL": "meshes/keyboard/SM_key.fbx",
|
||||
"texture": {
|
||||
|
@ -752,7 +752,7 @@
|
|||
"y": 0.04787999764084816
|
||||
},
|
||||
"position": {
|
||||
"x": -0.59333323516845703,
|
||||
"x": -0.65333323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": 0.037454843521118164
|
||||
},
|
||||
|
@ -777,9 +777,9 @@
|
|||
"y": 0.04787999764084816
|
||||
},
|
||||
"position": {
|
||||
"x": -0.5103323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": -0.127054843521118164
|
||||
"x": -0.5503323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": -0.07282185554504395
|
||||
},
|
||||
"modelURL": "meshes/keyboard/SM_enter.fbx",
|
||||
"texture": {
|
||||
|
@ -1479,9 +1479,9 @@
|
|||
"y": 0.04787999764084816
|
||||
},
|
||||
"position": {
|
||||
"x": -0.53203323516845703,
|
||||
"x": -0.59333323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": -0.07286686894893646
|
||||
"z": 0.037454843521118164
|
||||
},
|
||||
"modelURL": "meshes/keyboard/SM_key.fbx",
|
||||
"texture": {
|
||||
|
@ -1530,7 +1530,7 @@
|
|||
"y": 0.04787999764084816
|
||||
},
|
||||
"position": {
|
||||
"x": -0.59333323516845703,
|
||||
"x": -0.65333323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": 0.037454843521118164
|
||||
},
|
||||
|
@ -1555,9 +1555,9 @@
|
|||
"y": 0.04787999764084816
|
||||
},
|
||||
"position": {
|
||||
"x": -0.5103323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": -0.127054843521118164
|
||||
"x": -0.5503323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": -0.07282185554504395
|
||||
},
|
||||
"modelURL": "meshes/keyboard/SM_enter.fbx",
|
||||
"texture": {
|
||||
|
@ -2305,9 +2305,9 @@
|
|||
"y": 0.04787999764084816
|
||||
},
|
||||
"position": {
|
||||
"x": -0.53203323516845703,
|
||||
"x": -0.59333323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": -0.07286686894893646
|
||||
"z": 0.037454843521118164
|
||||
},
|
||||
"modelURL": "meshes/keyboard/SM_key.fbx",
|
||||
"texture": {
|
||||
|
@ -2356,7 +2356,7 @@
|
|||
"y": 0.04787999764084816
|
||||
},
|
||||
"position": {
|
||||
"x": -0.59333323516845703,
|
||||
"x": -0.65333323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": 0.037454843521118164
|
||||
},
|
||||
|
@ -2381,9 +2381,9 @@
|
|||
"y": 0.04787999764084816
|
||||
},
|
||||
"position": {
|
||||
"x": -0.5103323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": -0.127054843521118164
|
||||
"x": -0.5503323516845703,
|
||||
"y": 0.019300000742077827,
|
||||
"z": -0.07282185554504395
|
||||
},
|
||||
"modelURL": "meshes/keyboard/SM_enter.fbx",
|
||||
"texture": {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
window.isKeyboardRaised = false;
|
||||
window.isNumericKeyboard = false;
|
||||
window.isPasswordField = false;
|
||||
window.lastActiveElement = null;
|
||||
window.lastActiveInputElement = null;
|
||||
|
||||
function getActiveElement() {
|
||||
return document.activeElement;
|
||||
|
@ -70,11 +70,15 @@
|
|||
var keyboardRaised = shouldRaiseKeyboard();
|
||||
var numericKeyboard = shouldSetNumeric();
|
||||
var passwordField = shouldSetPasswordField();
|
||||
var activeElement = getActiveElement();
|
||||
var activeInputElement = null;
|
||||
// Only set the active input element when there is an input element focussed, otherwise it will scroll on body focus as well.
|
||||
if (keyboardRaised) {
|
||||
activeInputElement = getActiveElement();
|
||||
}
|
||||
|
||||
if (isWindowFocused &&
|
||||
(keyboardRaised !== window.isKeyboardRaised || numericKeyboard !== window.isNumericKeyboard
|
||||
|| passwordField !== window.isPasswordField || activeElement !== window.lastActiveElement)) {
|
||||
|| passwordField !== window.isPasswordField || activeInputElement !== window.lastActiveInputElement)) {
|
||||
|
||||
if (typeof EventBridge !== "undefined" && EventBridge !== null) {
|
||||
EventBridge.emitWebEvent(
|
||||
|
@ -96,7 +100,7 @@
|
|||
window.isKeyboardRaised = keyboardRaised;
|
||||
window.isNumericKeyboard = numericKeyboard;
|
||||
window.isPasswordField = passwordField;
|
||||
window.lastActiveElement = activeElement;
|
||||
window.lastActiveInputElement = activeInputElement;
|
||||
}
|
||||
}, POLL_FREQUENCY);
|
||||
|
||||
|
|
Binary file not shown.
|
@ -141,6 +141,7 @@ TabletModalWindow {
|
|||
|
||||
Component.onDestruction: {
|
||||
loginKeyboard.raised = false;
|
||||
KeyboardScriptingInterface.raised = false;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
|
|
BIN
interface/resources/sounds/keyboardPress.mp3
Normal file
BIN
interface/resources/sounds/keyboardPress.mp3
Normal file
Binary file not shown.
Binary file not shown.
|
@ -45,6 +45,7 @@
|
|||
#include "scripting/HMDScriptingInterface.h"
|
||||
#include "scripting/WindowScriptingInterface.h"
|
||||
#include "scripting/SelectionScriptingInterface.h"
|
||||
#include "scripting/HMDScriptingInterface.h"
|
||||
#include "DependencyManager.h"
|
||||
|
||||
#include "raypick/StylusPointer.h"
|
||||
|
@ -54,9 +55,9 @@
|
|||
static const int LEFT_HAND_CONTROLLER_INDEX = 0;
|
||||
static const int RIGHT_HAND_CONTROLLER_INDEX = 1;
|
||||
|
||||
static const float MALLET_LENGTH = 0.2f;
|
||||
static const float MALLET_TOUCH_Y_OFFSET = 0.052f;
|
||||
static const float MALLET_Y_OFFSET = 0.180f;
|
||||
static const float MALLET_LENGTH = 0.18f;
|
||||
static const float MALLET_TOUCH_Y_OFFSET = 0.050f;
|
||||
static const float MALLET_Y_OFFSET = 0.160f;
|
||||
|
||||
static const glm::quat MALLET_ROTATION_OFFSET{0.70710678f, 0.0f, -0.70710678f, 0.0f};
|
||||
static const glm::vec3 MALLET_MODEL_DIMENSIONS{0.03f, MALLET_LENGTH, 0.03f};
|
||||
|
@ -65,14 +66,14 @@ static const glm::vec3 MALLET_TIP_OFFSET{0.0f, MALLET_LENGTH - MALLET_TOUCH_Y_OF
|
|||
|
||||
|
||||
static const glm::vec3 Z_AXIS {0.0f, 0.0f, 1.0f};
|
||||
static const glm::vec3 KEYBOARD_TABLET_OFFSET{0.28f, -0.3f, -0.05f};
|
||||
static const glm::vec3 KEYBOARD_TABLET_OFFSET{0.30f, -0.38f, -0.04f};
|
||||
static const glm::vec3 KEYBOARD_TABLET_DEGREES_OFFSET{-45.0f, 0.0f, 0.0f};
|
||||
static const glm::vec3 KEYBOARD_TABLET_LANDSCAPE_OFFSET{-0.2f, -0.27f, -0.05f};
|
||||
static const glm::vec3 KEYBOARD_TABLET_LANDSCAPE_DEGREES_OFFSET{-45.0f, 0.0f, -90.0f};
|
||||
static const glm::vec3 KEYBOARD_AVATAR_OFFSET{-0.6f, 0.3f, -0.7f};
|
||||
static const glm::vec3 KEYBOARD_AVATAR_DEGREES_OFFSET{0.0f, 180.0f, 0.0f};
|
||||
|
||||
static const QString SOUND_FILE = PathUtils::resourcesUrl() + "sounds/keyboard_key.mp3";
|
||||
static const QString SOUND_FILE = PathUtils::resourcesUrl() + "sounds/keyboardPress.mp3";
|
||||
static const QString MALLET_MODEL_URL = PathUtils::resourcesUrl() + "meshes/drumstick.fbx";
|
||||
|
||||
static const float PULSE_STRENGTH = 0.6f;
|
||||
|
@ -221,6 +222,7 @@ Keyboard::Keyboard() {
|
|||
auto pointerManager = DependencyManager::get<PointerManager>();
|
||||
auto windowScriptingInterface = DependencyManager::get<WindowScriptingInterface>();
|
||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
auto hmdScriptingInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||
connect(pointerManager.data(), &PointerManager::triggerBeginOverlay, this, &Keyboard::handleTriggerBegin, Qt::QueuedConnection);
|
||||
connect(pointerManager.data(), &PointerManager::triggerContinueOverlay, this, &Keyboard::handleTriggerContinue, Qt::QueuedConnection);
|
||||
connect(pointerManager.data(), &PointerManager::triggerEndOverlay, this, &Keyboard::handleTriggerEnd, Qt::QueuedConnection);
|
||||
|
@ -228,6 +230,7 @@ Keyboard::Keyboard() {
|
|||
connect(pointerManager.data(), &PointerManager::hoverEndOverlay, this, &Keyboard::handleHoverEnd, Qt::QueuedConnection);
|
||||
connect(myAvatar.get(), &MyAvatar::sensorToWorldScaleChanged, this, &Keyboard::scaleKeyboard, Qt::QueuedConnection);
|
||||
connect(windowScriptingInterface.data(), &WindowScriptingInterface::domainChanged, [&]() { setRaised(false); });
|
||||
connect(hmdScriptingInterface.data(), &HMDScriptingInterface::displayModeChanged, [&]() { setRaised(false); });
|
||||
}
|
||||
|
||||
void Keyboard::registerKeyboardHighlighting() {
|
||||
|
@ -483,7 +486,7 @@ void Keyboard::handleTriggerBegin(const OverlayID& overlayID, const PointerEvent
|
|||
AudioInjectorOptions audioOptions;
|
||||
audioOptions.localOnly = true;
|
||||
audioOptions.position = keyWorldPosition;
|
||||
audioOptions.volume = 0.1f;
|
||||
audioOptions.volume = 0.05f;
|
||||
|
||||
AudioInjector::playSoundAndDelete(_keySound, audioOptions);
|
||||
|
||||
|
@ -835,8 +838,8 @@ void Keyboard::loadKeyboardFile(const QString& keyboardFile) {
|
|||
_textDisplay = textDisplay;
|
||||
|
||||
_ignoreItemsLock.withWriteLock([&] {
|
||||
_itemsToIgnore.push_back(_textDisplay.overlayID);
|
||||
_itemsToIgnore.push_back(_anchor.overlayID);
|
||||
_itemsToIgnore.append(_textDisplay.overlayID);
|
||||
_itemsToIgnore.append(_anchor.overlayID);
|
||||
});
|
||||
_layerIndex = 0;
|
||||
auto pointerManager = DependencyManager::get<PointerManager>();
|
||||
|
|
|
@ -535,7 +535,7 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay
|
|||
bool bestIsFront = false;
|
||||
bool bestIsTablet = false;
|
||||
auto tabletIDs = qApp->getTabletIDs();
|
||||
|
||||
const QVector<OverlayID> keyboardKeysToDiscard = DependencyManager::get<Keyboard>()->getKeysID();
|
||||
QMutexLocker locker(&_mutex);
|
||||
RayToOverlayIntersectionResult result;
|
||||
QMapIterator<OverlayID, Overlay::Pointer> i(_overlaysWorld);
|
||||
|
@ -545,7 +545,8 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay
|
|||
auto thisOverlay = std::dynamic_pointer_cast<Base3DOverlay>(i.value());
|
||||
|
||||
if ((overlaysToDiscard.size() > 0 && overlaysToDiscard.contains(thisID)) ||
|
||||
(overlaysToInclude.size() > 0 && !overlaysToInclude.contains(thisID))) {
|
||||
(overlaysToInclude.size() > 0 && !overlaysToInclude.contains(thisID)) ||
|
||||
(keyboardKeysToDiscard.size() > 0 && keyboardKeysToDiscard.contains(thisID))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,39 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) {
|
|||
for (auto& joint : hfmModel.joints) {
|
||||
joints.push_back(joint);
|
||||
}
|
||||
buildSkeletonFromJoints(joints);
|
||||
buildSkeletonFromJoints(joints, hfmModel.jointRotationOffsets);
|
||||
|
||||
// we make a copy of the inverseBindMatrices in order to prevent mutating the model bind pose
|
||||
// when we are dealing with a joint offset in the model
|
||||
for (int i = 0; i < (int)hfmModel.meshes.size(); i++) {
|
||||
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
||||
std::vector<HFMCluster> dummyClustersList;
|
||||
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
std::vector<glm::mat4> bindMatrices;
|
||||
// cast into a non-const reference, so we can mutate the FBXCluster
|
||||
HFMCluster& cluster = const_cast<HFMCluster&>(mesh.clusters.at(j));
|
||||
|
||||
HFMCluster localCluster;
|
||||
localCluster.jointIndex = cluster.jointIndex;
|
||||
localCluster.inverseBindMatrix = cluster.inverseBindMatrix;
|
||||
localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix);
|
||||
|
||||
// if we have a joint offset in the fst file then multiply its inverse by the
|
||||
// model cluster inverse bind matrix
|
||||
if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) {
|
||||
AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3());
|
||||
localCluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix;
|
||||
localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix);
|
||||
}
|
||||
dummyClustersList.push_back(localCluster);
|
||||
}
|
||||
_clusterBindMatrixOriginalValues.push_back(dummyClustersList);
|
||||
}
|
||||
}
|
||||
|
||||
AnimSkeleton::AnimSkeleton(const std::vector<HFMJoint>& joints) {
|
||||
buildSkeletonFromJoints(joints);
|
||||
AnimSkeleton::AnimSkeleton(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets) {
|
||||
buildSkeletonFromJoints(joints, jointOffsets);
|
||||
}
|
||||
|
||||
int AnimSkeleton::nameToJointIndex(const QString& jointName) const {
|
||||
|
@ -166,7 +194,8 @@ void AnimSkeleton::mirrorAbsolutePoses(AnimPoseVec& poses) const {
|
|||
}
|
||||
}
|
||||
|
||||
void AnimSkeleton::buildSkeletonFromJoints(const std::vector<HFMJoint>& joints) {
|
||||
void AnimSkeleton::buildSkeletonFromJoints(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets) {
|
||||
|
||||
_joints = joints;
|
||||
_jointsSize = (int)joints.size();
|
||||
// build a cache of bind poses
|
||||
|
@ -189,7 +218,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<HFMJoint>& joints)
|
|||
// build relative and absolute default poses
|
||||
glm::mat4 relDefaultMat = glm::translate(_joints[i].translation) * preRotationTransform * glm::mat4_cast(_joints[i].rotation) * postRotationTransform;
|
||||
AnimPose relDefaultPose(relDefaultMat);
|
||||
_relativeDefaultPoses.push_back(relDefaultPose);
|
||||
|
||||
int parentIndex = getParentIndex(i);
|
||||
if (parentIndex >= 0) {
|
||||
_absoluteDefaultPoses.push_back(_absoluteDefaultPoses[parentIndex] * relDefaultPose);
|
||||
|
@ -198,6 +227,16 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<HFMJoint>& joints)
|
|||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k < _jointsSize; k++) {
|
||||
if (jointOffsets.contains(k)) {
|
||||
AnimPose localOffset(jointOffsets[k], glm::vec3());
|
||||
_absoluteDefaultPoses[k] = _absoluteDefaultPoses[k] * localOffset;
|
||||
}
|
||||
}
|
||||
// re-compute relative poses
|
||||
_relativeDefaultPoses = _absoluteDefaultPoses;
|
||||
convertAbsolutePosesToRelative(_relativeDefaultPoses);
|
||||
|
||||
for (int i = 0; i < _jointsSize; i++) {
|
||||
_jointIndicesByName[_joints[i].name] = i;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ public:
|
|||
using ConstPointer = std::shared_ptr<const AnimSkeleton>;
|
||||
|
||||
explicit AnimSkeleton(const HFMModel& hfmModel);
|
||||
explicit AnimSkeleton(const std::vector<HFMJoint>& joints);
|
||||
explicit AnimSkeleton(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets);
|
||||
|
||||
int nameToJointIndex(const QString& jointName) const;
|
||||
const QString& getJointName(int jointIndex) const;
|
||||
int getNumJoints() const;
|
||||
|
@ -62,9 +63,10 @@ public:
|
|||
void dump(const AnimPoseVec& poses) const;
|
||||
|
||||
std::vector<int> lookUpJointIndices(const std::vector<QString>& jointNames) const;
|
||||
const HFMCluster getClusterBindMatricesOriginalValues(const int meshIndex, const int clusterIndex) const { return _clusterBindMatrixOriginalValues[meshIndex][clusterIndex]; }
|
||||
|
||||
protected:
|
||||
void buildSkeletonFromJoints(const std::vector<HFMJoint>& joints);
|
||||
void buildSkeletonFromJoints(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets);
|
||||
|
||||
std::vector<HFMJoint> _joints;
|
||||
int _jointsSize { 0 };
|
||||
|
@ -76,6 +78,7 @@ protected:
|
|||
std::vector<int> _nonMirroredIndices;
|
||||
std::vector<int> _mirrorMap;
|
||||
QHash<QString, int> _jointIndicesByName;
|
||||
std::vector<std::vector<HFMCluster>> _clusterBindMatrixOriginalValues;
|
||||
|
||||
// no copies
|
||||
AnimSkeleton(const AnimSkeleton&) = delete;
|
||||
|
|
|
@ -360,8 +360,10 @@ void Rig::initJointStates(const HFMModel& hfmModel, const glm::mat4& modelOffset
|
|||
void Rig::reset(const HFMModel& hfmModel) {
|
||||
_geometryOffset = AnimPose(hfmModel.offset);
|
||||
_invGeometryOffset = _geometryOffset.inverse();
|
||||
|
||||
_animSkeleton = std::make_shared<AnimSkeleton>(hfmModel);
|
||||
|
||||
|
||||
_internalPoseSet._relativePoses.clear();
|
||||
_internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();
|
||||
|
||||
|
|
|
@ -417,6 +417,30 @@ QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) {
|
|||
return filepath.mid(filepath.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
QMap<QString, glm::quat> getJointRotationOffsets(const QVariantHash& mapping) {
|
||||
QMap<QString, glm::quat> jointRotationOffsets;
|
||||
static const QString JOINT_ROTATION_OFFSET_FIELD = "jointRotationOffset";
|
||||
if (!mapping.isEmpty() && mapping.contains(JOINT_ROTATION_OFFSET_FIELD) && mapping[JOINT_ROTATION_OFFSET_FIELD].type() == QVariant::Hash) {
|
||||
auto offsets = mapping[JOINT_ROTATION_OFFSET_FIELD].toHash();
|
||||
for (auto itr = offsets.begin(); itr != offsets.end(); itr++) {
|
||||
QString jointName = itr.key();
|
||||
QString line = itr.value().toString();
|
||||
auto quatCoords = line.split(',');
|
||||
if (quatCoords.size() == 4) {
|
||||
float quatX = quatCoords[0].mid(1).toFloat();
|
||||
float quatY = quatCoords[1].toFloat();
|
||||
float quatZ = quatCoords[2].toFloat();
|
||||
float quatW = quatCoords[3].mid(0, quatCoords[3].size() - 1).toFloat();
|
||||
if (!isNaN(quatX) && !isNaN(quatY) && !isNaN(quatZ) && !isNaN(quatW)) {
|
||||
glm::quat rotationOffset = glm::quat(quatW, quatX, quatY, quatZ);
|
||||
jointRotationOffsets.insert(jointName, rotationOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return jointRotationOffsets;
|
||||
}
|
||||
|
||||
HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& url) {
|
||||
const FBXNode& node = _rootNode;
|
||||
QMap<QString, ExtractedMesh> meshes;
|
||||
|
@ -1793,6 +1817,19 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto offsets = getJointRotationOffsets(mapping);
|
||||
hfmModel.jointRotationOffsets.clear();
|
||||
for (auto itr = offsets.begin(); itr != offsets.end(); itr++) {
|
||||
QString jointName = itr.key();
|
||||
glm::quat rotationOffset = itr.value();
|
||||
int jointIndex = hfmModel.getJointIndex(jointName);
|
||||
if (jointIndex != -1) {
|
||||
hfmModel.jointRotationOffsets.insert(jointIndex, rotationOffset);
|
||||
}
|
||||
qCDebug(modelformat) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset;
|
||||
}
|
||||
|
||||
return hfmModelPtr;
|
||||
}
|
||||
|
||||
|
|
|
@ -311,6 +311,8 @@ public:
|
|||
QString getModelNameOfMesh(int meshIndex) const;
|
||||
|
||||
QList<QString> blendshapeChannelNames;
|
||||
|
||||
QMap<int, glm::quat> jointRotationOffsets;
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -234,7 +234,7 @@ private:
|
|||
#ifdef Q_OS_ANDROID
|
||||
Setting::Handle<bool> _enableInterstitialMode{ "enableInterstitialMode", false };
|
||||
#else
|
||||
Setting::Handle<bool> _enableInterstitialMode { "enableInterstitialMode", true };
|
||||
Setting::Handle<bool> _enableInterstitialMode { "enableInterstitialMode", false };
|
||||
#endif
|
||||
|
||||
QSet<QString> _domainConnectionRefusals;
|
||||
|
|
|
@ -46,8 +46,13 @@ bool OctreeEntitiesFileParser::parseEntities(QVariantMap& parsedEntities) {
|
|||
bool gotId = false;
|
||||
bool gotVersion = false;
|
||||
|
||||
while (!(gotDataVersion && gotEntities && gotId && gotVersion)) {
|
||||
if (nextToken() != '"') {
|
||||
int token = nextToken();
|
||||
|
||||
while (true) {
|
||||
if (token == '}') {
|
||||
break;
|
||||
}
|
||||
else if (token != '"') {
|
||||
_errorString = "Incorrect key string";
|
||||
return false;
|
||||
}
|
||||
|
@ -144,15 +149,13 @@ bool OctreeEntitiesFileParser::parseEntities(QVariantMap& parsedEntities) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (gotDataVersion && gotEntities && gotId && gotVersion) {
|
||||
break;
|
||||
} else if (nextToken() != ',') {
|
||||
_errorString = "Id/value incorrectly terminated";
|
||||
return false;
|
||||
token = nextToken();
|
||||
if (token == ',') {
|
||||
token = nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
if (nextToken() != '}' || nextToken() != -1) {
|
||||
if (nextToken() != -1) {
|
||||
_errorString = "Ill-formed end of object";
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -114,18 +114,22 @@ void CauterizedModel::updateClusterMatrices() {
|
|||
for (int i = 0; i < (int)_meshStates.size(); i++) {
|
||||
Model::MeshState& state = _meshStates[i];
|
||||
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
||||
int meshIndex = i;
|
||||
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
const HFMCluster& cluster = mesh.clusters.at(j);
|
||||
int clusterIndex = j;
|
||||
|
||||
if (_useDualQuaternionSkinning) {
|
||||
auto jointPose = _rig.getJointPose(cluster.jointIndex);
|
||||
Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans());
|
||||
Transform clusterTransform;
|
||||
Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform);
|
||||
Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform);
|
||||
state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform);
|
||||
state.clusterDualQuaternions[j].setCauterizationParameters(0.0f, jointPose.trans());
|
||||
} else {
|
||||
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]);
|
||||
glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,9 +150,11 @@ void CauterizedModel::updateClusterMatrices() {
|
|||
for (int i = 0; i < _cauterizeMeshStates.size(); i++) {
|
||||
Model::MeshState& state = _cauterizeMeshStates[i];
|
||||
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
||||
int meshIndex = i;
|
||||
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
const HFMCluster& cluster = mesh.clusters.at(j);
|
||||
int clusterIndex = j;
|
||||
|
||||
if (_useDualQuaternionSkinning) {
|
||||
if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) {
|
||||
|
@ -157,7 +163,7 @@ void CauterizedModel::updateClusterMatrices() {
|
|||
} else {
|
||||
Transform jointTransform(cauterizePose.rot(), cauterizePose.scale(), cauterizePose.trans());
|
||||
Transform clusterTransform;
|
||||
Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform);
|
||||
Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform);
|
||||
state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform);
|
||||
state.clusterDualQuaternions[j].setCauterizationParameters(1.0f, cauterizePose.trans());
|
||||
}
|
||||
|
@ -166,7 +172,7 @@ void CauterizedModel::updateClusterMatrices() {
|
|||
// not cauterized so just copy the value from the non-cauterized version.
|
||||
state.clusterMatrices[j] = _meshStates[i].clusterMatrices[j];
|
||||
} else {
|
||||
glm_mat4u_mul(cauterizeMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]);
|
||||
glm_mat4u_mul(cauterizeMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1418,18 +1418,21 @@ void Model::updateClusterMatrices() {
|
|||
const HFMModel& hfmModel = getHFMModel();
|
||||
for (int i = 0; i < (int) _meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
int meshIndex = i;
|
||||
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
const HFMCluster& cluster = mesh.clusters.at(j);
|
||||
int clusterIndex = j;
|
||||
|
||||
if (_useDualQuaternionSkinning) {
|
||||
auto jointPose = _rig.getJointPose(cluster.jointIndex);
|
||||
Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans());
|
||||
Transform clusterTransform;
|
||||
Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform);
|
||||
Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform);
|
||||
state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform);
|
||||
} else {
|
||||
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]);
|
||||
glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,32 +46,25 @@ void SoftAttachmentModel::updateClusterMatrices() {
|
|||
for (int i = 0; i < (int) _meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
||||
|
||||
int meshIndex = i;
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
const HFMCluster& cluster = mesh.clusters.at(j);
|
||||
|
||||
int clusterIndex = j;
|
||||
// TODO: cache these look-ups as an optimization
|
||||
int jointIndexOverride = getJointIndexOverride(cluster.jointIndex);
|
||||
glm::mat4 jointMatrix;
|
||||
if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) {
|
||||
jointMatrix = _rigOverride.getJointTransform(jointIndexOverride);
|
||||
} else {
|
||||
jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||
}
|
||||
if (_useDualQuaternionSkinning) {
|
||||
glm::mat4 jointMatrix;
|
||||
if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) {
|
||||
jointMatrix = _rigOverride.getJointTransform(jointIndexOverride);
|
||||
} else {
|
||||
jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||
}
|
||||
|
||||
glm::mat4 m;
|
||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, m);
|
||||
glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, m);
|
||||
state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(m);
|
||||
} else {
|
||||
glm::mat4 jointMatrix;
|
||||
if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) {
|
||||
jointMatrix = _rigOverride.getJointTransform(jointIndexOverride);
|
||||
} else {
|
||||
jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||
}
|
||||
|
||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]);
|
||||
glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue