better picking against billboarded shapes other than spheres

This commit is contained in:
HifiExperiments 2021-01-10 16:48:44 -08:00
parent bef0c79b67
commit 6d1667df5a

View file

@ -276,10 +276,6 @@ bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
OctreeElementPointer& element, OctreeElementPointer& element,
float& distance, BoxFace& face, glm::vec3& surfaceNormal, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const { QVariantMap& extraInfo, bool precisionPicking) const {
if (getShape() != entity::Sphere) {
return true;
}
glm::vec3 dimensions = getScaledDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::quat rotation = getWorldOrientation(); glm::quat rotation = getWorldOrientation();
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
@ -291,18 +287,22 @@ bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f)); glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
glm::vec3 entityFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f)); glm::vec3 entityFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f));
// NOTE: unit sphere has center of 0,0,0 and radius of 0.5 if (getShape() == entity::Sphere) {
if (findRaySphereIntersection(entityFrameOrigin, entityFrameDirection, glm::vec3(0.0f), 0.5f, distance)) { // NOTE: unit sphere has center of 0,0,0 and radius of 0.5
bool success; if (findRaySphereIntersection(entityFrameOrigin, entityFrameDirection, glm::vec3(0.0f), 0.5f, distance)) {
glm::vec3 center = getCenterPosition(success); bool success;
if (success) { glm::vec3 center = getCenterPosition(success);
// FIXME: this is only correct for uniformly scaled spheres if (success) {
// determine where on the unit sphere the hit point occured // FIXME: this is only correct for uniformly scaled spheres
glm::vec3 hitAt = origin + (direction * distance); // determine where on the unit sphere the hit point occured
surfaceNormal = glm::normalize(hitAt - center); glm::vec3 hitAt = origin + (direction * distance);
} else { surfaceNormal = glm::normalize(hitAt - center);
return false; } else {
return false;
}
return true;
} }
} else if (findRayAABoxIntersection(entityFrameOrigin, entityFrameDirection, 1.0f / entityFrameDirection, glm::vec3(-0.5f), glm::vec3(1.0f), distance, face, surfaceNormal)) {
return true; return true;
} }
return false; return false;
@ -312,10 +312,6 @@ bool ShapeEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin,
OctreeElementPointer& element, float& parabolicDistance, OctreeElementPointer& element, float& parabolicDistance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const { QVariantMap& extraInfo, bool precisionPicking) const {
if (getShape() != entity::Sphere) {
return true;
}
glm::vec3 dimensions = getScaledDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::quat rotation = getWorldOrientation(); glm::quat rotation = getWorldOrientation();
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
@ -328,16 +324,20 @@ bool ShapeEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin,
glm::vec3 entityFrameVelocity = glm::vec3(worldToEntityMatrix * glm::vec4(velocity, 0.0f)); glm::vec3 entityFrameVelocity = glm::vec3(worldToEntityMatrix * glm::vec4(velocity, 0.0f));
glm::vec3 entityFrameAcceleration = glm::vec3(worldToEntityMatrix * glm::vec4(acceleration, 0.0f)); glm::vec3 entityFrameAcceleration = glm::vec3(worldToEntityMatrix * glm::vec4(acceleration, 0.0f));
// NOTE: unit sphere has center of 0,0,0 and radius of 0.5 if (getShape() == entity::Sphere) {
if (findParabolaSphereIntersection(entityFrameOrigin, entityFrameVelocity, entityFrameAcceleration, glm::vec3(0.0f), 0.5f, parabolicDistance)) { // NOTE: unit sphere has center of 0,0,0 and radius of 0.5
bool success; if (findParabolaSphereIntersection(entityFrameOrigin, entityFrameVelocity, entityFrameAcceleration, glm::vec3(0.0f), 0.5f, parabolicDistance)) {
glm::vec3 center = getCenterPosition(success); bool success;
if (success) { glm::vec3 center = getCenterPosition(success);
// FIXME: this is only correct for uniformly scaled spheres if (success) {
surfaceNormal = glm::normalize((origin + velocity * parabolicDistance + 0.5f * acceleration * parabolicDistance * parabolicDistance) - center); // FIXME: this is only correct for uniformly scaled spheres
} else { surfaceNormal = glm::normalize((origin + velocity * parabolicDistance + 0.5f * acceleration * parabolicDistance * parabolicDistance) - center);
return false; } else {
return false;
}
return true;
} }
} else if (findParabolaAABoxIntersection(entityFrameOrigin, entityFrameVelocity, entityFrameAcceleration, glm::vec3(-0.5f), glm::vec3(1.0f), parabolicDistance, face, surfaceNormal)) {
return true; return true;
} }
return false; return false;