mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 16:26:17 +02:00
implement proper ray picking against ellipsoids
Conflicts: libraries/entities/src/SphereEntityItem.cpp
This commit is contained in:
parent
2bf93bd9f0
commit
b08d5b87ca
2 changed files with 19 additions and 11 deletions
|
@ -10,9 +10,12 @@
|
|||
//
|
||||
|
||||
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <ByteCountCoding.h>
|
||||
#include <GeometryUtil.h>
|
||||
|
||||
#include "EntityTree.h"
|
||||
#include "EntityTreeElement.h"
|
||||
|
@ -97,18 +100,21 @@ void SphereEntityItem::recalculateCollisionShape() {
|
|||
bool SphereEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject) const {
|
||||
|
||||
// NOTE: origin and direction are in tree units. But our _sphereShape is in meters, so we need to
|
||||
// do a little math to make these match each other.
|
||||
RayIntersectionInfo rayInfo;
|
||||
rayInfo._rayStart = origin * (float)TREE_SCALE;
|
||||
rayInfo._rayDirection = direction;
|
||||
// determine the ray in the frame of the entity transformed from a unit sphere
|
||||
glm::mat4 translation = glm::translate(getPosition());
|
||||
glm::mat4 rotation = glm::mat4_cast(getRotation());
|
||||
glm::mat4 scale = glm::scale(getDimensions());
|
||||
glm::mat4 registration = glm::translate(glm::vec3(0.5f,0.5f,0.5f) - getRegistrationPoint());
|
||||
glm::mat4 entityToWorldMatrix = translation * rotation * scale * registration;
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
||||
glm::vec3 entityFrameDirection = glm::normalize(glm::vec3(worldToEntityMatrix * glm::vec4(direction, 1.0f)));
|
||||
|
||||
// TODO: Note this is really doing ray intersections against a sphere, which is fine except in cases
|
||||
// where our dimensions actually make us an ellipsoid. But we'll live with this for now until we
|
||||
// get a more full fledged physics library
|
||||
if (_sphereShape.findRayIntersection(rayInfo)) {
|
||||
distance = rayInfo._hitDistance / (float)TREE_SCALE;
|
||||
float localDistance;
|
||||
if (findRaySphereIntersection(entityFrameOrigin, entityFrameDirection, glm::vec3(0.0f), 0.5f, localDistance)) {
|
||||
glm::vec3 entityFrameHitAt = entityFrameOrigin + (entityFrameDirection * localDistance);
|
||||
glm::vec3 hitAt = glm::vec3(entityToWorldMatrix * glm::vec4(entityFrameHitAt, 1.0f));
|
||||
distance = glm::distance(origin,hitAt);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -61,6 +61,8 @@ public:
|
|||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject) const;
|
||||
|
||||
bool isCircle() const { return false && _dimensions.x == _dimensions.y && _dimensions.y == _dimensions.z; }
|
||||
|
||||
protected:
|
||||
virtual void recalculateCollisionShape();
|
||||
|
||||
|
|
Loading…
Reference in a new issue