mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 06:57:37 +02:00
js call to ray-pick against avatars
This commit is contained in:
parent
cecd871c66
commit
4e70e8ed42
7 changed files with 101 additions and 0 deletions
|
@ -1085,6 +1085,15 @@ void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
shapeInfo.setOffset(uniformScale * _skeletonModel->getBoundingCapsuleOffset());
|
shapeInfo.setOffset(uniformScale * _skeletonModel->getBoundingCapsuleOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Avatar::getCapsule(glm::vec3& start, glm::vec3& end, float& radius) {
|
||||||
|
ShapeInfo shapeInfo;
|
||||||
|
computeShapeInfo(shapeInfo);
|
||||||
|
glm::vec3 halfExtents = shapeInfo.getHalfExtents(); // x = radius, y = halfHeight
|
||||||
|
start = getPosition() - glm::vec3(0, halfExtents.y, 0);
|
||||||
|
end = getPosition() + glm::vec3(0, halfExtents.y, 0);
|
||||||
|
radius = halfExtents.x;
|
||||||
|
}
|
||||||
|
|
||||||
void Avatar::setMotionState(AvatarMotionState* motionState) {
|
void Avatar::setMotionState(AvatarMotionState* motionState) {
|
||||||
_motionState = motionState;
|
_motionState = motionState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,7 @@ public:
|
||||||
virtual void rebuildCollisionShape();
|
virtual void rebuildCollisionShape();
|
||||||
|
|
||||||
virtual void computeShapeInfo(ShapeInfo& shapeInfo);
|
virtual void computeShapeInfo(ShapeInfo& shapeInfo);
|
||||||
|
void getCapsule(glm::vec3& start, glm::vec3& end, float& radius);
|
||||||
|
|
||||||
AvatarMotionState* getMotionState() { return _motionState; }
|
AvatarMotionState* getMotionState() { return _motionState; }
|
||||||
|
|
||||||
|
|
|
@ -398,3 +398,51 @@ AvatarSharedPointer AvatarManager::getAvatarBySessionID(const QUuid& sessionID)
|
||||||
|
|
||||||
return findAvatar(sessionID);
|
return findAvatar(sessionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RayToAvatarIntersectionResult AvatarManager::findRayIntersection(const PickRay& ray,
|
||||||
|
const QScriptValue& avatarIdsToInclude,
|
||||||
|
const QScriptValue& avatarIdsToDiscard) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
RayToAvatarIntersectionResult result;
|
||||||
|
QMetaObject::invokeMethod(const_cast<AvatarManager*>(this), "findRayIntersection", Qt::BlockingQueuedConnection,
|
||||||
|
Q_ARG(const QScriptValue&, avatarIdsToInclude),
|
||||||
|
Q_ARG(const QScriptValue&, avatarIdsToDiscard),
|
||||||
|
Q_RETURN_ARG(RayToAvatarIntersectionResult, result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
RayToAvatarIntersectionResult result;
|
||||||
|
|
||||||
|
QVector<EntityItemID> avatarsToInclude = qVectorEntityItemIDFromScriptValue(avatarIdsToInclude);
|
||||||
|
QVector<EntityItemID> avatarsToDiscard = qVectorEntityItemIDFromScriptValue(avatarIdsToDiscard);
|
||||||
|
|
||||||
|
glm::vec3 normDirection = glm::normalize(ray.direction);
|
||||||
|
|
||||||
|
for (auto avatarData : _avatarHash) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
glm::vec3 start;
|
||||||
|
glm::vec3 end;
|
||||||
|
float radius;
|
||||||
|
avatar->getCapsule(start, end, radius);
|
||||||
|
|
||||||
|
bool intersects = findRayCapsuleIntersection(ray.origin, normDirection, start, end, radius, distance);
|
||||||
|
if (intersects && (!result.intersects || distance < result.distance)) {
|
||||||
|
result.intersects = true;
|
||||||
|
result.avatarID = avatar->getID();
|
||||||
|
result.distance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.intersects) {
|
||||||
|
result.intersection = ray.origin + normDirection * result.distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -70,6 +70,10 @@ public:
|
||||||
|
|
||||||
void addAvatarToSimulation(Avatar* avatar);
|
void addAvatarToSimulation(Avatar* avatar);
|
||||||
|
|
||||||
|
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersection(const PickRay& ray,
|
||||||
|
const QScriptValue& avatarIdsToInclude = QScriptValue(),
|
||||||
|
const QScriptValue& avatarIdsToDiscard = QScriptValue());
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
|
void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
|
||||||
void updateAvatarRenderStatus(bool shouldRenderAvatars);
|
void updateAvatarRenderStatus(bool shouldRenderAvatars);
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <StreamUtils.h>
|
#include <StreamUtils.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
#include <shared/JSONHelpers.h>
|
#include <shared/JSONHelpers.h>
|
||||||
|
#include <ShapeInfo.h>
|
||||||
|
|
||||||
#include "AvatarLogging.h"
|
#include "AvatarLogging.h"
|
||||||
|
|
||||||
|
@ -1681,3 +1682,25 @@ AvatarEntityIDs AvatarData::getAndClearRecentlyDetachedIDs() {
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue RayToAvatarIntersectionResultToScriptValue(QScriptEngine* engine, const RayToAvatarIntersectionResult& value) {
|
||||||
|
QScriptValue obj = engine->newObject();
|
||||||
|
obj.setProperty("intersects", value.intersects);
|
||||||
|
QScriptValue avatarIDValue = quuidToScriptValue(engine, value.avatarID);
|
||||||
|
obj.setProperty("avatarID", avatarIDValue);
|
||||||
|
obj.setProperty("distance", value.distance);
|
||||||
|
QScriptValue intersection = vec3toScriptValue(engine, value.intersection);
|
||||||
|
obj.setProperty("intersection", intersection);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RayToAvatarIntersectionResultFromScriptValue(const QScriptValue& object, RayToAvatarIntersectionResult& value) {
|
||||||
|
value.intersects = object.property("intersects").toVariant().toBool();
|
||||||
|
QScriptValue avatarIDValue = object.property("avatarID");
|
||||||
|
quuidFromScriptValue(avatarIDValue, value.avatarID);
|
||||||
|
value.distance = object.property("distance").toVariant().toFloat();
|
||||||
|
QScriptValue intersection = object.property("intersection");
|
||||||
|
if (intersection.isValid()) {
|
||||||
|
vec3FromScriptValue(intersection, value.intersection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -495,4 +495,19 @@ public:
|
||||||
|
|
||||||
void registerAvatarTypes(QScriptEngine* engine);
|
void registerAvatarTypes(QScriptEngine* engine);
|
||||||
|
|
||||||
|
class RayToAvatarIntersectionResult {
|
||||||
|
public:
|
||||||
|
RayToAvatarIntersectionResult() : intersects(false), avatarID(), distance(0) {}
|
||||||
|
bool intersects;
|
||||||
|
QUuid avatarID;
|
||||||
|
float distance;
|
||||||
|
glm::vec3 intersection;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(RayToAvatarIntersectionResult)
|
||||||
|
|
||||||
|
QScriptValue RayToAvatarIntersectionResultToScriptValue(QScriptEngine* engine, const RayToAvatarIntersectionResult& results);
|
||||||
|
void RayToAvatarIntersectionResultFromScriptValue(const QScriptValue& object, RayToAvatarIntersectionResult& results);
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_AvatarData_h
|
#endif // hifi_AvatarData_h
|
||||||
|
|
|
@ -465,6 +465,7 @@ void ScriptEngine::init() {
|
||||||
qScriptRegisterMetaType(this, EntityItemPropertiesToScriptValue, EntityItemPropertiesFromScriptValueHonorReadOnly);
|
qScriptRegisterMetaType(this, EntityItemPropertiesToScriptValue, EntityItemPropertiesFromScriptValueHonorReadOnly);
|
||||||
qScriptRegisterMetaType(this, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
|
qScriptRegisterMetaType(this, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
|
||||||
qScriptRegisterMetaType(this, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
|
qScriptRegisterMetaType(this, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
|
||||||
|
qScriptRegisterMetaType(this, RayToAvatarIntersectionResultToScriptValue, RayToAvatarIntersectionResultFromScriptValue);
|
||||||
qScriptRegisterSequenceMetaType<QVector<QUuid>>(this);
|
qScriptRegisterSequenceMetaType<QVector<QUuid>>(this);
|
||||||
qScriptRegisterSequenceMetaType<QVector<EntityItemID>>(this);
|
qScriptRegisterSequenceMetaType<QVector<EntityItemID>>(this);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue