mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge pull request #13949 from sabrina-shanman/stt_parenting_scale
Scale Collision Pick to match parent
This commit is contained in:
commit
405e2da91e
13 changed files with 189 additions and 49 deletions
|
@ -16,8 +16,9 @@ Transform MyAvatarHeadTransformNode::getTransform() {
|
|||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
|
||||
glm::vec3 pos = myAvatar->getHeadPosition();
|
||||
glm::vec3 scale = glm::vec3(myAvatar->scaleForChildren());
|
||||
glm::quat headOri = myAvatar->getHeadOrientation();
|
||||
glm::quat ori = headOri * glm::angleAxis(-PI / 2.0f, Vectors::RIGHT);
|
||||
|
||||
return Transform(ori, glm::vec3(1.0f), pos);
|
||||
return Transform(ori, scale, pos);
|
||||
}
|
|
@ -86,23 +86,23 @@ bool CollisionPick::isLoaded() const {
|
|||
return !_mathPick.shouldComputeShapeInfo() || (_cachedResource && _cachedResource->isLoaded());
|
||||
}
|
||||
|
||||
bool CollisionPick::getShapeInfoReady() {
|
||||
bool CollisionPick::getShapeInfoReady(const CollisionRegion& pick) {
|
||||
if (_mathPick.shouldComputeShapeInfo()) {
|
||||
if (_cachedResource && _cachedResource->isLoaded()) {
|
||||
computeShapeInfo(_mathPick, *_mathPick.shapeInfo, _cachedResource);
|
||||
computeShapeInfo(pick, *_mathPick.shapeInfo, _cachedResource);
|
||||
_mathPick.loaded = true;
|
||||
} else {
|
||||
_mathPick.loaded = false;
|
||||
}
|
||||
} else {
|
||||
computeShapeInfoDimensionsOnly(_mathPick, *_mathPick.shapeInfo, _cachedResource);
|
||||
computeShapeInfoDimensionsOnly(pick, *_mathPick.shapeInfo, _cachedResource);
|
||||
_mathPick.loaded = true;
|
||||
}
|
||||
|
||||
return _mathPick.loaded;
|
||||
}
|
||||
|
||||
void CollisionPick::computeShapeInfoDimensionsOnly(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource) {
|
||||
void CollisionPick::computeShapeInfoDimensionsOnly(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource) {
|
||||
ShapeType type = shapeInfo.getType();
|
||||
glm::vec3 dimensions = pick.transform.getScale();
|
||||
QString modelURL = (resource ? resource->getURL().toString() : "");
|
||||
|
@ -115,7 +115,7 @@ void CollisionPick::computeShapeInfoDimensionsOnly(CollisionRegion& pick, ShapeI
|
|||
}
|
||||
}
|
||||
|
||||
void CollisionPick::computeShapeInfo(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource) {
|
||||
void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource) {
|
||||
// This code was copied and modified from RenderableModelEntityItem::computeShapeInfo
|
||||
// TODO: Move to some shared code area (in entities-renderer? model-networking?)
|
||||
// after we verify this is working and do a diff comparison with RenderableModelEntityItem::computeShapeInfo
|
||||
|
@ -357,12 +357,14 @@ CollisionPick::CollisionPick(const PickFilter& filter, float maxDistance, bool e
|
|||
CollisionRegion CollisionPick::getMathematicalPick() const {
|
||||
CollisionRegion mathPick = _mathPick;
|
||||
mathPick.loaded = isLoaded();
|
||||
if (!parentTransform) {
|
||||
return mathPick;
|
||||
} else {
|
||||
mathPick.transform = parentTransform->getTransform().worldTransform(mathPick.transform);
|
||||
return mathPick;
|
||||
if (parentTransform) {
|
||||
Transform parentTransformValue = parentTransform->getTransform();
|
||||
mathPick.transform = parentTransformValue.worldTransform(mathPick.transform);
|
||||
glm::vec3 scale = parentTransformValue.getScale();
|
||||
float largestDimension = glm::max(glm::max(scale.x, scale.y), scale.z);
|
||||
mathPick.threshold *= largestDimension;
|
||||
}
|
||||
return mathPick;
|
||||
}
|
||||
|
||||
void CollisionPick::filterIntersections(std::vector<ContactTestResult>& intersections) const {
|
||||
|
@ -393,9 +395,9 @@ PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pi
|
|||
// Cannot compute result
|
||||
return std::make_shared<CollisionPickResult>(pick.toVariantMap(), std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
|
||||
}
|
||||
getShapeInfoReady();
|
||||
getShapeInfoReady(pick);
|
||||
|
||||
auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
||||
auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *_mathPick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
||||
filterIntersections(entityIntersections);
|
||||
return std::make_shared<CollisionPickResult>(pick, entityIntersections, std::vector<ContactTestResult>());
|
||||
}
|
||||
|
@ -409,9 +411,9 @@ PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pi
|
|||
// Cannot compute result
|
||||
return std::make_shared<CollisionPickResult>(pick, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
|
||||
}
|
||||
getShapeInfoReady();
|
||||
getShapeInfoReady(pick);
|
||||
|
||||
auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
||||
auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *_mathPick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
||||
filterIntersections(avatarIntersections);
|
||||
return std::make_shared<CollisionPickResult>(pick, std::vector<ContactTestResult>(), avatarIntersections);
|
||||
}
|
||||
|
|
|
@ -62,9 +62,9 @@ protected:
|
|||
// Returns true if the resource for _mathPick.shapeInfo is loaded or if a resource is not needed.
|
||||
bool isLoaded() const;
|
||||
// Returns true if _mathPick.shapeInfo is valid. Otherwise, attempts to get the _mathPick ready for use.
|
||||
bool getShapeInfoReady();
|
||||
void computeShapeInfo(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
|
||||
void computeShapeInfoDimensionsOnly(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
|
||||
bool getShapeInfoReady(const CollisionRegion& pick);
|
||||
void computeShapeInfo(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
|
||||
void computeShapeInfoDimensionsOnly(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
|
||||
void filterIntersections(std::vector<ContactTestResult>& intersections) const;
|
||||
|
||||
CollisionRegion _mathPick;
|
||||
|
|
|
@ -24,11 +24,14 @@
|
|||
#include "CollisionPick.h"
|
||||
|
||||
#include "SpatialParentFinder.h"
|
||||
#include "NestableTransformNode.h"
|
||||
#include "PickTransformNode.h"
|
||||
#include "MouseTransformNode.h"
|
||||
#include "avatar/MyAvatarHeadTransformNode.h"
|
||||
#include "avatar/AvatarManager.h"
|
||||
#include "NestableTransformNode.h"
|
||||
#include "avatars-renderer/AvatarTransformNode.h"
|
||||
#include "ui/overlays/OverlayTransformNode.h"
|
||||
#include "EntityTransformNode.h"
|
||||
|
||||
#include <ScriptEngine.h>
|
||||
|
||||
|
@ -260,9 +263,16 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
|
|||
* A set of properties that can be passed to {@link Picks.createPick} to create a new Collision Pick.
|
||||
|
||||
* @typedef {object} Picks.CollisionPickProperties
|
||||
* @property {Shape} shape - The information about the collision region's size and shape.
|
||||
* @property {Vec3} position - The position of the collision region.
|
||||
* @property {Quat} orientation - The orientation of the collision region.
|
||||
* @property {boolean} [enabled=false] If this Pick should start enabled or not. Disabled Picks do not updated their pick results.
|
||||
* @property {number} [filter=Picks.PICK_NOTHING] The filter for this Pick to use, constructed using filter flags combined using bitwise OR.
|
||||
* @property {Shape} shape - The information about the collision region's size and shape. Dimensions are in world space, but will scale with the parent if defined.
|
||||
* @property {Vec3} position - The position of the collision region, relative to a parent if defined.
|
||||
* @property {Quat} orientation - The orientation of the collision region, relative to a parent if defined.
|
||||
* @property {float} threshold - The approximate minimum penetration depth for a test object to be considered in contact with the collision region.
|
||||
* The depth is measured in world space, but will scale with the parent if defined.
|
||||
* @property {Uuid} parentID - The ID of the parent, either an avatar, an entity, or an overlay.
|
||||
* @property {number} parentJointIndex - The joint of the parent to parent to, for example, the joints on the model of an avatar. (default = 0, no joint)
|
||||
* @property {string} joint - If "Mouse," parents the pick to the mouse. If "Avatar," parents the pick to MyAvatar's head. Otherwise, parents to the joint of the given name on MyAvatar.
|
||||
*/
|
||||
unsigned int PickScriptingInterface::createCollisionPick(const QVariant& properties) {
|
||||
QVariantMap propMap = properties.toMap();
|
||||
|
@ -375,7 +385,16 @@ std::shared_ptr<TransformNode> PickScriptingInterface::createTransformNode(const
|
|||
}
|
||||
auto sharedNestablePointer = nestablePointer.lock();
|
||||
if (success && sharedNestablePointer) {
|
||||
return std::make_shared<NestableTransformNode>(nestablePointer, parentJointIndex);
|
||||
NestableType nestableType = sharedNestablePointer->getNestableType();
|
||||
if (nestableType == NestableType::Avatar) {
|
||||
return std::make_shared<AvatarTransformNode>(std::static_pointer_cast<Avatar>(sharedNestablePointer), parentJointIndex);
|
||||
} else if (nestableType == NestableType::Overlay) {
|
||||
return std::make_shared<OverlayTransformNode>(std::static_pointer_cast<Base3DOverlay>(sharedNestablePointer), parentJointIndex);
|
||||
} else if (nestableType == NestableType::Entity) {
|
||||
return std::make_shared<EntityTransformNode>(std::static_pointer_cast<EntityItem>(sharedNestablePointer), parentJointIndex);
|
||||
} else {
|
||||
return std::make_shared<NestableTransformNode>(nestablePointer, parentJointIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,7 +413,7 @@ std::shared_ptr<TransformNode> PickScriptingInterface::createTransformNode(const
|
|||
} else if (!joint.isNull()) {
|
||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
int jointIndex = myAvatar->getJointIndex(joint);
|
||||
return std::make_shared<NestableTransformNode>(myAvatar, jointIndex);
|
||||
return std::make_shared<AvatarTransformNode>(myAvatar, jointIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
13
interface/src/ui/overlays/OverlayTransformNode.cpp
Normal file
13
interface/src/ui/overlays/OverlayTransformNode.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// Created by Sabrina Shanman 9/5/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "OverlayTransformNode.h"
|
||||
|
||||
template<>
|
||||
glm::vec3 BaseNestableTransformNode<Base3DOverlay>::getActualScale(const std::shared_ptr<Base3DOverlay>& nestablePointer) const {
|
||||
return nestablePointer->getBounds().getScale();
|
||||
}
|
21
interface/src/ui/overlays/OverlayTransformNode.h
Normal file
21
interface/src/ui/overlays/OverlayTransformNode.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// Created by Sabrina Shanman 9/5/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_OverlayTransformNode_h
|
||||
#define hifi_OverlayTransformNode_h
|
||||
|
||||
#include "NestableTransformNode.h"
|
||||
|
||||
#include "Base3DOverlay.h"
|
||||
|
||||
// For 3D overlays only
|
||||
class OverlayTransformNode : public BaseNestableTransformNode<Base3DOverlay> {
|
||||
public:
|
||||
OverlayTransformNode(std::weak_ptr<Base3DOverlay> spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
|
||||
};
|
||||
|
||||
#endif // hifi_OverlayTransformNode_h
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// Created by Sabrina Shanman 9/5/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "AvatarTransformNode.h"
|
||||
|
||||
template<>
|
||||
glm::vec3 BaseNestableTransformNode<Avatar>::getActualScale(const std::shared_ptr<Avatar>& nestablePointer) const {
|
||||
return nestablePointer->scaleForChildren();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// Created by Sabrina Shanman 9/5/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_AvatarTransformNode_h
|
||||
#define hifi_AvatarTransformNode_h
|
||||
|
||||
#include "NestableTransformNode.h"
|
||||
|
||||
#include "Avatar.h"
|
||||
|
||||
class AvatarTransformNode : public BaseNestableTransformNode<Avatar> {
|
||||
public:
|
||||
AvatarTransformNode(std::weak_ptr<Avatar> spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
|
||||
};
|
||||
|
||||
#endif // hifi_AvatarTransformNode_h
|
13
libraries/entities/src/EntityTransformNode.cpp
Normal file
13
libraries/entities/src/EntityTransformNode.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// Created by Sabrina Shanman 9/5/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "EntityTransformNode.h"
|
||||
|
||||
template<>
|
||||
glm::vec3 BaseNestableTransformNode<EntityItem>::getActualScale(const std::shared_ptr<EntityItem>& nestablePointer) const {
|
||||
return nestablePointer->getScaledDimensions();
|
||||
}
|
20
libraries/entities/src/EntityTransformNode.h
Normal file
20
libraries/entities/src/EntityTransformNode.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// Created by Sabrina Shanman 9/5/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_EntityTransformNode_h
|
||||
#define hifi_EntityTransformNode_h
|
||||
|
||||
#include "NestableTransformNode.h"
|
||||
|
||||
#include "EntityItem.h"
|
||||
|
||||
class EntityTransformNode : public BaseNestableTransformNode<EntityItem> {
|
||||
public:
|
||||
EntityTransformNode(std::weak_ptr<EntityItem> spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
|
||||
};
|
||||
|
||||
#endif // hifi_EntityTransformNode_h
|
|
@ -8,24 +8,7 @@
|
|||
|
||||
#include "NestableTransformNode.h"
|
||||
|
||||
NestableTransformNode::NestableTransformNode(SpatiallyNestableWeakPointer spatiallyNestable, int jointIndex) :
|
||||
_spatiallyNestable(spatiallyNestable),
|
||||
_jointIndex(jointIndex)
|
||||
{
|
||||
}
|
||||
|
||||
Transform NestableTransformNode::getTransform() {
|
||||
auto nestable = _spatiallyNestable.lock();
|
||||
if (!nestable) {
|
||||
return Transform();
|
||||
}
|
||||
|
||||
bool success;
|
||||
Transform jointWorldTransform = nestable->getTransform(_jointIndex, success);
|
||||
|
||||
if (success) {
|
||||
return jointWorldTransform;
|
||||
} else {
|
||||
return Transform();
|
||||
}
|
||||
template<>
|
||||
glm::vec3 BaseNestableTransformNode<SpatiallyNestable>::getActualScale(const std::shared_ptr<SpatiallyNestable>& nestablePointer) const {
|
||||
return nestablePointer->getAbsoluteJointScaleInObjectFrame(_jointIndex);
|
||||
}
|
|
@ -12,14 +12,48 @@
|
|||
|
||||
#include "SpatiallyNestable.h"
|
||||
|
||||
class NestableTransformNode : public TransformNode {
|
||||
template <typename T>
|
||||
class BaseNestableTransformNode : public TransformNode {
|
||||
public:
|
||||
NestableTransformNode(SpatiallyNestableWeakPointer spatiallyNestable, int jointIndex);
|
||||
Transform getTransform() override;
|
||||
BaseNestableTransformNode(std::weak_ptr<T> spatiallyNestable, int jointIndex) :
|
||||
_spatiallyNestable(spatiallyNestable),
|
||||
_jointIndex(jointIndex) {
|
||||
auto nestablePointer = _spatiallyNestable.lock();
|
||||
if (nestablePointer) {
|
||||
glm::vec3 nestableDimensions = getActualScale(nestablePointer);
|
||||
_baseScale = glm::max(glm::vec3(0.001f), nestableDimensions);
|
||||
}
|
||||
}
|
||||
|
||||
Transform getTransform() override {
|
||||
std::shared_ptr<T> nestable = _spatiallyNestable.lock();
|
||||
if (!nestable) {
|
||||
return Transform();
|
||||
}
|
||||
|
||||
bool success;
|
||||
Transform jointWorldTransform = nestable->getTransform(_jointIndex, success);
|
||||
|
||||
if (!success) {
|
||||
return Transform();
|
||||
}
|
||||
|
||||
jointWorldTransform.setScale(getActualScale(nestable) / _baseScale);
|
||||
|
||||
return jointWorldTransform;
|
||||
}
|
||||
|
||||
glm::vec3 getActualScale(const std::shared_ptr<T>& nestablePointer) const;
|
||||
|
||||
protected:
|
||||
SpatiallyNestableWeakPointer _spatiallyNestable;
|
||||
std::weak_ptr<T> _spatiallyNestable;
|
||||
int _jointIndex;
|
||||
glm::vec3 _baseScale { 1.0f };
|
||||
};
|
||||
|
||||
class NestableTransformNode : public BaseNestableTransformNode<SpatiallyNestable> {
|
||||
public:
|
||||
NestableTransformNode(std::weak_ptr<SpatiallyNestable> spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
|
||||
};
|
||||
|
||||
#endif // hifi_NestableTransformNode_h
|
|
@ -259,10 +259,11 @@ public:
|
|||
* A CollisionRegion defines a volume for checking collisions in the physics simulation.
|
||||
|
||||
* @typedef {object} CollisionRegion
|
||||
* @property {Shape} shape - The information about the collision region's size and shape.
|
||||
* @property {Shape} shape - The information about the collision region's size and shape. Dimensions are in world space, but will scale with the parent if defined.
|
||||
* @property {Vec3} position - The position of the collision region, relative to a parent if defined.
|
||||
* @property {Quat} orientation - The orientation of the collision region, relative to a parent if defined.
|
||||
* @property {float} threshold - The approximate minimum penetration depth for a test object to be considered in contact with the collision region.
|
||||
* The depth is measured in world space, but will scale with the parent if defined.
|
||||
* @property {Uuid} parentID - The ID of the parent, either an avatar, an entity, or an overlay.
|
||||
* @property {number} parentJointIndex - The joint of the parent to parent to, for example, the joints on the model of an avatar. (default = 0, no joint)
|
||||
* @property {string} joint - If "Mouse," parents the pick to the mouse. If "Avatar," parents the pick to MyAvatar's head. Otherwise, parents to the joint of the given name on MyAvatar.
|
||||
|
|
Loading…
Reference in a new issue