mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 17:54:00 +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;
|
||||
}
|
||||
|
||||
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,
|
||||
const QVector<EntityItemID>& avatarsToInclude,
|
||||
const QVector<EntityItemID>& avatarsToDiscard) {
|
||||
|
|
|
@ -157,6 +157,15 @@ public:
|
|||
const QVector<EntityItemID>& avatarsToDiscard,
|
||||
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
|
||||
* @function AvatarManager.findParabolaIntersectionVector
|
||||
* @param {PickParabola} pick
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "IKTarget.h"
|
||||
#include "PathUtils.h"
|
||||
|
||||
|
||||
static int nextRigId = 1;
|
||||
static std::map<int, Rig*> rigRegistry;
|
||||
static std::mutex rigRegistryMutex;
|
||||
|
@ -1871,7 +1870,7 @@ void Rig::initAnimGraph(const QUrl& url) {
|
|||
auto roleState = roleAnimState.second;
|
||||
overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame);
|
||||
}
|
||||
|
||||
_flow.setRig(this);
|
||||
emit onLoadComplete();
|
||||
});
|
||||
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) {
|
||||
qCritical(animation) << "Error loading: code = " << error << "str =" << str;
|
||||
});
|
||||
connect(this, &Rig::onLoadComplete, [&]() {
|
||||
_flow.calculateConstraints();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "AnimNodeLoader.h"
|
||||
#include "SimpleMovingAverage.h"
|
||||
#include "AnimUtil.h"
|
||||
#include "Flow.h"
|
||||
|
||||
class Rig;
|
||||
class AnimInverseKinematics;
|
||||
|
@ -233,6 +234,7 @@ public:
|
|||
const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); }
|
||||
const AnimVariantMap& getAnimVars() const { return _lastAnimVars; }
|
||||
const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); }
|
||||
void computeFlowSkeleton() { _flow.calculateConstraints(); }
|
||||
|
||||
signals:
|
||||
void onLoadComplete();
|
||||
|
@ -424,6 +426,7 @@ protected:
|
|||
|
||||
SnapshotBlendPoseHelper _hipsBlendHelper;
|
||||
ControllerParameters _previousControllerParameters;
|
||||
Flow _flow;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__Rig__) */
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "MetaModelPayload.h"
|
||||
#include "MultiSphereShape.h"
|
||||
#include "Flow.h"
|
||||
|
||||
namespace render {
|
||||
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 void callFlow() { _skeletonModel->getRig().computeFlowSkeleton(); };
|
||||
|
||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) 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);
|
||||
}
|
||||
void EntityTree::callFlowSkeleton(const QUuid& entityID) {
|
||||
/*
|
||||
EntityTree* nonConstThis = const_cast<EntityTree*>(this);
|
||||
EntityItemPointer entity = nonConstThis->findEntityByEntityItemID(entityID);
|
||||
*/
|
||||
}
|
||||
|
||||
QStringList EntityTree::getJointNames(const QUuid& entityID) const {
|
||||
EntityTree* nonConstThis = const_cast<EntityTree*>(this);
|
||||
|
|
|
@ -240,6 +240,7 @@ public:
|
|||
// these are used to call through to EntityItems
|
||||
Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name) const;
|
||||
Q_INVOKABLE QStringList getJointNames(const QUuid& entityID) const;
|
||||
Q_INVOKABLE void callFlowSkeleton(const QUuid& entityID);
|
||||
|
||||
void knowAvatarID(QUuid avatarID) { _avatarIDs += avatarID; }
|
||||
void forgetAvatarID(QUuid avatarID) { _avatarIDs -= avatarID; }
|
||||
|
|
Loading…
Reference in a new issue