mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 19:21:16 +02:00
Threads created correctly
This commit is contained in:
parent
cc38a96bff
commit
cf8f9fa1b6
7 changed files with 129 additions and 2 deletions
|
@ -760,6 +760,109 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RayToAvatarIntersectionResult AvatarManager::findRayIntersectionOld(const PickRay& ray,
|
||||||
|
const QScriptValue& avatarIdsToInclude,
|
||||||
|
const QScriptValue& avatarIdsToDiscard) {
|
||||||
|
QVector<EntityItemID> avatarsToInclude = qVectorEntityItemIDFromScriptValue(avatarIdsToInclude);
|
||||||
|
QVector<EntityItemID> avatarsToDiscard = qVectorEntityItemIDFromScriptValue(avatarIdsToDiscard);
|
||||||
|
|
||||||
|
return findRayIntersectionVectorOld(ray, avatarsToInclude, avatarsToDiscard);
|
||||||
|
}
|
||||||
|
|
||||||
|
RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVectorOld(const PickRay& ray,
|
||||||
|
const QVector<EntityItemID>& avatarsToInclude,
|
||||||
|
const QVector<EntityItemID>& avatarsToDiscard) {
|
||||||
|
RayToAvatarIntersectionResult result;
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
BLOCKING_INVOKE_METHOD(const_cast<AvatarManager*>(this), "findRayIntersectionVector",
|
||||||
|
Q_RETURN_ARG(RayToAvatarIntersectionResult, result),
|
||||||
|
Q_ARG(const PickRay&, ray),
|
||||||
|
Q_ARG(const QVector<EntityItemID>&, avatarsToInclude),
|
||||||
|
Q_ARG(const QVector<EntityItemID>&, avatarsToDiscard));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's better to intersect the ray against the avatar's actual mesh, but this is currently difficult to
|
||||||
|
// do, because the transformed mesh data only exists over in GPU-land. As a compromise, this code
|
||||||
|
// intersects against the avatars capsule and then against the (T-pose) mesh. The end effect is that picking
|
||||||
|
// against the avatar is sort-of right, but you likely wont be able to pick against the arms.
|
||||||
|
|
||||||
|
// TODO -- find a way to extract transformed avatar mesh data from the rendering engine.
|
||||||
|
|
||||||
|
std::vector<SortedAvatar> sortedAvatars;
|
||||||
|
auto avatarHashCopy = getHashCopy();
|
||||||
|
for (auto avatarData : avatarHashCopy) {
|
||||||
|
auto avatar = std::static_pointer_cast<Avatar>(avatarData);
|
||||||
|
if ((avatarsToInclude.size() > 0 && !avatarsToInclude.contains(avatar->getID())) ||
|
||||||
|
(avatarsToDiscard.size() > 0 && avatarsToDiscard.contains(avatar->getID()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
#if 0
|
||||||
|
// if we weren't picking against the capsule, we would want to pick against the avatarBounds...
|
||||||
|
SkeletonModelPointer avatarModel = avatar->getSkeletonModel();
|
||||||
|
AABox avatarBounds = avatarModel->getRenderableMeshBound();
|
||||||
|
if (avatarBounds.contains(ray.origin)) {
|
||||||
|
distance = 0.0f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float boundDistance = FLT_MAX;
|
||||||
|
BoxFace face;
|
||||||
|
glm::vec3 surfaceNormal;
|
||||||
|
if (avatarBounds.findRayIntersection(ray.origin, ray.direction, boundDistance, face, surfaceNormal)) {
|
||||||
|
distance = boundDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
glm::vec3 start;
|
||||||
|
glm::vec3 end;
|
||||||
|
float radius;
|
||||||
|
avatar->getCapsule(start, end, radius);
|
||||||
|
findRayCapsuleIntersection(ray.origin, ray.direction, start, end, radius, distance);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (distance < FLT_MAX) {
|
||||||
|
sortedAvatars.emplace_back(distance, avatar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sortedAvatars.size() > 1) {
|
||||||
|
static auto comparator = [](const SortedAvatar& left, const SortedAvatar& right) { return left.first < right.first; };
|
||||||
|
std::sort(sortedAvatars.begin(), sortedAvatars.end(), comparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = sortedAvatars.begin(); it != sortedAvatars.end(); ++it) {
|
||||||
|
const SortedAvatar& sortedAvatar = *it;
|
||||||
|
// We can exit once avatarCapsuleDistance > bestDistance
|
||||||
|
if (sortedAvatar.first > result.distance) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
BoxFace face;
|
||||||
|
glm::vec3 surfaceNormal;
|
||||||
|
QVariantMap extraInfo;
|
||||||
|
SkeletonModelPointer avatarModel = sortedAvatar.second->getSkeletonModel();
|
||||||
|
if (avatarModel->findRayIntersectionAgainstSubMeshes(ray.origin, ray.direction, distance, face, surfaceNormal, extraInfo, true)) {
|
||||||
|
if (distance < result.distance) {
|
||||||
|
result.intersects = true;
|
||||||
|
result.avatarID = sortedAvatar.second->getID();
|
||||||
|
result.distance = distance;
|
||||||
|
result.face = face;
|
||||||
|
result.surfaceNormal = surfaceNormal;
|
||||||
|
result.extraInfo = extraInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.intersects) {
|
||||||
|
result.intersection = ray.origin + ray.direction * result.distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ParabolaToAvatarIntersectionResult AvatarManager::findParabolaIntersectionVector(const PickParabola& pick,
|
ParabolaToAvatarIntersectionResult AvatarManager::findParabolaIntersectionVector(const PickParabola& pick,
|
||||||
const QVector<EntityItemID>& avatarsToInclude,
|
const QVector<EntityItemID>& avatarsToInclude,
|
||||||
const QVector<EntityItemID>& avatarsToDiscard) {
|
const QVector<EntityItemID>& avatarsToDiscard) {
|
||||||
|
|
|
@ -157,6 +157,15 @@ public:
|
||||||
const QVector<EntityItemID>& avatarsToDiscard,
|
const QVector<EntityItemID>& avatarsToDiscard,
|
||||||
bool pickAgainstMesh);
|
bool pickAgainstMesh);
|
||||||
|
|
||||||
|
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionOld(const PickRay& ray,
|
||||||
|
const QScriptValue& avatarIdsToInclude = QScriptValue(),
|
||||||
|
const QScriptValue& avatarIdsToDiscard = QScriptValue());
|
||||||
|
|
||||||
|
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionVectorOld(const PickRay& ray,
|
||||||
|
const QVector<EntityItemID>& avatarsToInclude,
|
||||||
|
const QVector<EntityItemID>& avatarsToDiscard);
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function AvatarManager.findParabolaIntersectionVector
|
* @function AvatarManager.findParabolaIntersectionVector
|
||||||
* @param {PickParabola} pick
|
* @param {PickParabola} pick
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "IKTarget.h"
|
#include "IKTarget.h"
|
||||||
#include "PathUtils.h"
|
#include "PathUtils.h"
|
||||||
|
|
||||||
|
|
||||||
static int nextRigId = 1;
|
static int nextRigId = 1;
|
||||||
static std::map<int, Rig*> rigRegistry;
|
static std::map<int, Rig*> rigRegistry;
|
||||||
static std::mutex rigRegistryMutex;
|
static std::mutex rigRegistryMutex;
|
||||||
|
@ -1871,7 +1870,7 @@ void Rig::initAnimGraph(const QUrl& url) {
|
||||||
auto roleState = roleAnimState.second;
|
auto roleState = roleAnimState.second;
|
||||||
overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame);
|
overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame);
|
||||||
}
|
}
|
||||||
|
_flow.setRig(this);
|
||||||
emit onLoadComplete();
|
emit onLoadComplete();
|
||||||
});
|
});
|
||||||
connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) {
|
connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) {
|
||||||
|
@ -1903,6 +1902,9 @@ void Rig::initAnimGraph(const QUrl& url) {
|
||||||
connect(_networkLoader.get(), &AnimNodeLoader::error, [networkUrl](int error, QString str) {
|
connect(_networkLoader.get(), &AnimNodeLoader::error, [networkUrl](int error, QString str) {
|
||||||
qCritical(animation) << "Error loading: code = " << error << "str =" << str;
|
qCritical(animation) << "Error loading: code = " << error << "str =" << str;
|
||||||
});
|
});
|
||||||
|
connect(this, &Rig::onLoadComplete, [&]() {
|
||||||
|
_flow.calculateConstraints();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "AnimNodeLoader.h"
|
#include "AnimNodeLoader.h"
|
||||||
#include "SimpleMovingAverage.h"
|
#include "SimpleMovingAverage.h"
|
||||||
#include "AnimUtil.h"
|
#include "AnimUtil.h"
|
||||||
|
#include "Flow.h"
|
||||||
|
|
||||||
class Rig;
|
class Rig;
|
||||||
class AnimInverseKinematics;
|
class AnimInverseKinematics;
|
||||||
|
@ -233,6 +234,7 @@ public:
|
||||||
const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); }
|
const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); }
|
||||||
const AnimVariantMap& getAnimVars() const { return _lastAnimVars; }
|
const AnimVariantMap& getAnimVars() const { return _lastAnimVars; }
|
||||||
const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); }
|
const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); }
|
||||||
|
void computeFlowSkeleton() { _flow.calculateConstraints(); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void onLoadComplete();
|
void onLoadComplete();
|
||||||
|
@ -424,6 +426,7 @@ protected:
|
||||||
|
|
||||||
SnapshotBlendPoseHelper _hipsBlendHelper;
|
SnapshotBlendPoseHelper _hipsBlendHelper;
|
||||||
ControllerParameters _previousControllerParameters;
|
ControllerParameters _previousControllerParameters;
|
||||||
|
Flow _flow;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__Rig__) */
|
#endif /* defined(__hifi__Rig__) */
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "MetaModelPayload.h"
|
#include "MetaModelPayload.h"
|
||||||
#include "MultiSphereShape.h"
|
#include "MultiSphereShape.h"
|
||||||
|
#include "Flow.h"
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
||||||
|
@ -285,6 +286,8 @@ public:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE glm::quat jointToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const;
|
Q_INVOKABLE glm::quat jointToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void callFlow() { _skeletonModel->getRig().computeFlowSkeleton(); };
|
||||||
|
|
||||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
||||||
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData) override;
|
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData) override;
|
||||||
|
|
||||||
|
|
|
@ -2943,6 +2943,12 @@ int EntityTree::getJointIndex(const QUuid& entityID, const QString& name) const
|
||||||
}
|
}
|
||||||
return entity->getJointIndex(name);
|
return entity->getJointIndex(name);
|
||||||
}
|
}
|
||||||
|
void EntityTree::callFlowSkeleton(const QUuid& entityID) {
|
||||||
|
/*
|
||||||
|
EntityTree* nonConstThis = const_cast<EntityTree*>(this);
|
||||||
|
EntityItemPointer entity = nonConstThis->findEntityByEntityItemID(entityID);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
QStringList EntityTree::getJointNames(const QUuid& entityID) const {
|
QStringList EntityTree::getJointNames(const QUuid& entityID) const {
|
||||||
EntityTree* nonConstThis = const_cast<EntityTree*>(this);
|
EntityTree* nonConstThis = const_cast<EntityTree*>(this);
|
||||||
|
|
|
@ -240,6 +240,7 @@ public:
|
||||||
// these are used to call through to EntityItems
|
// these are used to call through to EntityItems
|
||||||
Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name) const;
|
Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name) const;
|
||||||
Q_INVOKABLE QStringList getJointNames(const QUuid& entityID) const;
|
Q_INVOKABLE QStringList getJointNames(const QUuid& entityID) const;
|
||||||
|
Q_INVOKABLE void callFlowSkeleton(const QUuid& entityID);
|
||||||
|
|
||||||
void knowAvatarID(QUuid avatarID) { _avatarIDs += avatarID; }
|
void knowAvatarID(QUuid avatarID) { _avatarIDs += avatarID; }
|
||||||
void forgetAvatarID(QUuid avatarID) { _avatarIDs -= avatarID; }
|
void forgetAvatarID(QUuid avatarID) { _avatarIDs -= avatarID; }
|
||||||
|
|
Loading…
Reference in a new issue