mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:03:55 +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());
|
||||
}
|
||||
|
||||
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) {
|
||||
_motionState = motionState;
|
||||
}
|
||||
|
|
|
@ -154,6 +154,7 @@ public:
|
|||
virtual void rebuildCollisionShape();
|
||||
|
||||
virtual void computeShapeInfo(ShapeInfo& shapeInfo);
|
||||
void getCapsule(glm::vec3& start, glm::vec3& end, float& radius);
|
||||
|
||||
AvatarMotionState* getMotionState() { return _motionState; }
|
||||
|
||||
|
|
|
@ -398,3 +398,51 @@ AvatarSharedPointer AvatarManager::getAvatarBySessionID(const QUuid& 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);
|
||||
|
||||
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersection(const PickRay& ray,
|
||||
const QScriptValue& avatarIdsToInclude = QScriptValue(),
|
||||
const QScriptValue& avatarIdsToDiscard = QScriptValue());
|
||||
|
||||
public slots:
|
||||
void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
|
||||
void updateAvatarRenderStatus(bool shouldRenderAvatars);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <StreamUtils.h>
|
||||
#include <UUID.h>
|
||||
#include <shared/JSONHelpers.h>
|
||||
#include <ShapeInfo.h>
|
||||
|
||||
#include "AvatarLogging.h"
|
||||
|
||||
|
@ -1681,3 +1682,25 @@ AvatarEntityIDs AvatarData::getAndClearRecentlyDetachedIDs() {
|
|||
});
|
||||
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);
|
||||
|
||||
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
|
||||
|
|
|
@ -465,6 +465,7 @@ void ScriptEngine::init() {
|
|||
qScriptRegisterMetaType(this, EntityItemPropertiesToScriptValue, EntityItemPropertiesFromScriptValueHonorReadOnly);
|
||||
qScriptRegisterMetaType(this, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
|
||||
qScriptRegisterMetaType(this, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
|
||||
qScriptRegisterMetaType(this, RayToAvatarIntersectionResultToScriptValue, RayToAvatarIntersectionResultFromScriptValue);
|
||||
qScriptRegisterSequenceMetaType<QVector<QUuid>>(this);
|
||||
qScriptRegisterSequenceMetaType<QVector<EntityItemID>>(this);
|
||||
|
||||
|
|
Loading…
Reference in a new issue