Move load state flag from CollisionPickResult to CollisionRegion and make it a boolean

This commit is contained in:
sabrina-shanman 2018-08-29 16:12:58 -07:00
parent 2d73b7845e
commit 686f9fb18a
4 changed files with 41 additions and 36 deletions

View file

@ -32,9 +32,6 @@ PickResultPointer CollisionPickResult::compareAndProcessNewResult(const PickResu
}
intersects = entityIntersections.size() || avatarIntersections.size();
if (newCollisionResult->loadState == LOAD_STATE_NOT_LOADED || loadState == LOAD_STATE_UNKNOWN) {
loadState = (LoadState)newCollisionResult->loadState;
}
return std::make_shared<CollisionPickResult>(*this);
}
@ -80,24 +77,29 @@ QVariantMap CollisionPickResult::toVariantMap() const {
}
variantMap["intersectingObjects"] = qIntersectingObjects;
variantMap["loaded"] = (loadState == LOAD_STATE_LOADED);
variantMap["collisionRegion"] = pickVariant;
return variantMap;
}
bool CollisionPick::isLoaded() const {
return !_mathPick.shouldComputeShapeInfo() || (_cachedResource && _cachedResource->isLoaded());
}
bool CollisionPick::getShapeInfoReady() {
if (_mathPick.shouldComputeShapeInfo()) {
if (_cachedResource && _cachedResource->isLoaded()) {
computeShapeInfo(_mathPick, *_mathPick.shapeInfo, _cachedResource);
return true;
_mathPick.loaded = true;
} else {
_mathPick.loaded = false;
}
return false;
} else {
computeShapeInfoDimensionsOnly(_mathPick, *_mathPick.shapeInfo, _cachedResource);
return true;
_mathPick.loaded = true;
}
return _mathPick.loaded;
}
void CollisionPick::computeShapeInfoDimensionsOnly(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource) {
@ -349,15 +351,19 @@ CollisionPick::CollisionPick(const PickFilter& filter, float maxDistance, bool e
if (collisionRegion.shouldComputeShapeInfo()) {
_cachedResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(collisionRegion.modelURL);
}
_mathPick.loaded = isLoaded();
}
CollisionRegion CollisionPick::getMathematicalPick() const {
CollisionRegion mathPick = _mathPick;
if (!mathPick.loaded) {
mathPick.loaded = isLoaded();
}
if (!parentTransform) {
return _mathPick;
return mathPick;
} else {
CollisionRegion transformedMathPick = _mathPick;
transformedMathPick.transform = parentTransform->getTransform().worldTransform(_mathPick.transform);
return transformedMathPick;
mathPick.transform = parentTransform->getTransform().worldTransform(mathPick.transform);
return mathPick;
}
}
@ -385,33 +391,35 @@ void CollisionPick::filterIntersections(std::vector<ContactTestResult>& intersec
}
PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pick) {
if (!getShapeInfoReady()) {
if (!pick.loaded) {
// Cannot compute result
return std::make_shared<CollisionPickResult>(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
return std::make_shared<CollisionPickResult>(pick.toVariantMap(), std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
}
getShapeInfoReady();
auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
filterIntersections(entityIntersections);
return std::make_shared<CollisionPickResult>(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::vector<ContactTestResult>());
return std::make_shared<CollisionPickResult>(pick, entityIntersections, std::vector<ContactTestResult>());
}
PickResultPointer CollisionPick::getOverlayIntersection(const CollisionRegion& pick) {
return std::make_shared<CollisionPickResult>(pick, getShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
return std::make_shared<CollisionPickResult>(pick, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
}
PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pick) {
if (!getShapeInfoReady()) {
if (!pick.loaded) {
// Cannot compute result
return std::make_shared<CollisionPickResult>(pick, CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
return std::make_shared<CollisionPickResult>(pick, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
}
getShapeInfoReady();
auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
filterIntersections(avatarIntersections);
return std::make_shared<CollisionPickResult>(pick, CollisionPickResult::LOAD_STATE_LOADED, std::vector<ContactTestResult>(), avatarIntersections);
return std::make_shared<CollisionPickResult>(pick, std::vector<ContactTestResult>(), avatarIntersections);
}
PickResultPointer CollisionPick::getHUDIntersection(const CollisionRegion& pick) {
return std::make_shared<CollisionPickResult>(pick.toVariantMap(), getShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
return std::make_shared<CollisionPickResult>(pick.toVariantMap(), std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
}
Transform CollisionPick::getResultTransform() const {

View file

@ -16,18 +16,11 @@
class CollisionPickResult : public PickResult {
public:
enum LoadState {
LOAD_STATE_UNKNOWN,
LOAD_STATE_NOT_LOADED,
LOAD_STATE_LOADED
};
CollisionPickResult() {}
CollisionPickResult(const QVariantMap& pickVariant) : PickResult(pickVariant) {}
CollisionPickResult(const CollisionRegion& searchRegion, LoadState loadState, const std::vector<ContactTestResult>& entityIntersections, const std::vector<ContactTestResult>& avatarIntersections) :
CollisionPickResult(const CollisionRegion& searchRegion, const std::vector<ContactTestResult>& entityIntersections, const std::vector<ContactTestResult>& avatarIntersections) :
PickResult(searchRegion.toVariantMap()),
loadState(loadState),
intersects(entityIntersections.size() || avatarIntersections.size()),
entityIntersections(entityIntersections),
avatarIntersections(avatarIntersections)
@ -38,10 +31,8 @@ public:
avatarIntersections = collisionPickResult.avatarIntersections;
entityIntersections = collisionPickResult.entityIntersections;
intersects = collisionPickResult.intersects;
loadState = collisionPickResult.loadState;
}
LoadState loadState { LOAD_STATE_UNKNOWN };
bool intersects { false };
std::vector<ContactTestResult> entityIntersections;
std::vector<ContactTestResult> avatarIntersections;
@ -61,7 +52,7 @@ public:
CollisionRegion getMathematicalPick() const override;
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override {
return std::make_shared<CollisionPickResult>(pickVariant, CollisionPickResult::LOAD_STATE_UNKNOWN, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
return std::make_shared<CollisionPickResult>(pickVariant, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
}
PickResultPointer getEntityIntersection(const CollisionRegion& pick) override;
PickResultPointer getOverlayIntersection(const CollisionRegion& pick) override;
@ -69,7 +60,9 @@ public:
PickResultPointer getHUDIntersection(const CollisionRegion& pick) override;
Transform getResultTransform() const override;
protected:
// Returns true if pick.shapeInfo is valid. Otherwise, attempts to get the shapeInfo ready for use.
// 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);

View file

@ -152,9 +152,6 @@ public:
* @property {CollisionRegion} collisionRegion The CollisionRegion that was used. Valid even if there was no intersection.
*/
// TODO: Add this to the CollisionPickResult jsdoc once model collision picks are working
//* @property {boolean} loaded If the CollisionRegion was successfully loaded (may be false if a model was used)
/**jsdoc
* Information about the Collision Pick's intersection with an object
*

View file

@ -253,6 +253,8 @@ public:
}
};
// TODO: Add "loaded" to CollisionRegion jsdoc once model collision picks are supported.
/**jsdoc
* A CollisionRegion defines a volume for checking collisions in the physics simulation.
@ -270,6 +272,7 @@ public:
CollisionRegion() { }
CollisionRegion(const CollisionRegion& collisionRegion) :
loaded(collisionRegion.loaded),
modelURL(collisionRegion.modelURL),
shapeInfo(std::make_shared<ShapeInfo>()),
transform(collisionRegion.transform),
@ -279,6 +282,7 @@ public:
}
CollisionRegion(const QVariantMap& pickVariant) {
// "loaded" is not deserialized here because there is no way to know if the shape is actually loaded
if (pickVariant["shape"].isValid()) {
auto shape = pickVariant["shape"].toMap();
if (!shape.empty()) {
@ -322,6 +326,7 @@ public:
shape["dimensions"] = vec3toVariant(transform.getScale());
collisionRegion["shape"] = shape;
collisionRegion["loaded"] = loaded;
collisionRegion["threshold"] = threshold;
@ -339,7 +344,8 @@ public:
}
bool operator==(const CollisionRegion& other) const {
return threshold == other.threshold &&
return loaded == other.loaded &&
threshold == other.threshold &&
glm::all(glm::equal(transform.getTranslation(), other.transform.getTranslation())) &&
glm::all(glm::equal(transform.getRotation(), other.transform.getRotation())) &&
glm::all(glm::equal(transform.getScale(), other.transform.getScale())) &&
@ -359,6 +365,7 @@ public:
}
// We can't load the model here because it would create a circular dependency, so we delegate that responsibility to the owning CollisionPick
bool loaded = false;
QUrl modelURL;
// We can't compute the shapeInfo here without loading the model first, so we delegate that responsibility to the owning CollisionPick