Handle registration point in transforms

This commit is contained in:
Atlante45 2015-04-23 17:48:29 +02:00
parent bda72025af
commit f494f86ee5
5 changed files with 37 additions and 24 deletions

View file

@ -419,9 +419,7 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
if (EntityItem::contains(point) && _model && _model->getCollisionGeometry()) {
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
const FBXGeometry& collisionGeometry = collisionNetworkGeometry->getFBXGeometry();
glm::vec3 transformedPoint = (glm::inverse(getRotation()) * (point - getPosition())) / (getDimensions() / 2.0f);
return collisionGeometry.convexHullContains(transformedPoint);
return collisionGeometry.convexHullContains(worldToEntity(point));
}
return false;

View file

@ -49,9 +49,8 @@ bool RenderableZoneEntityItem::contains(const glm::vec3& point) const {
if (EntityItem::contains(point) && _compoundShapeModel && _compoundShapeModel->isLoaded()) {
const FBXGeometry& geometry = _compoundShapeModel->getFBXGeometry();
glm::vec3 transformedPoint = (glm::inverse(getRotation()) * (point - getPosition())) / (getDimensions() / 2.0f);
return geometry.convexHullContains(transformedPoint);
glm::vec3 meshDimensions = geometry.getUnscaledMeshExtents().maximum - geometry.getUnscaledMeshExtents().minimum;
return geometry.convexHullContains(worldToEntity(point) * meshDimensions);
}
return false;

View file

@ -11,6 +11,8 @@
#include <QtCore/QObject>
#include <glm/gtx/transform.hpp>
#include <ByteCountCoding.h>
#include <GLMHelpers.h>
#include <Octree.h>
@ -843,7 +845,27 @@ bool EntityItem::isMoving() const {
return hasVelocity() || hasAngularVelocity();
}
bool EntityItem::lifetimeHasExpired() const {
glm::mat4 EntityItem::getEntityToWorldMatrix() const {
glm::mat4 translation = glm::translate(getPosition());
glm::mat4 rotation = glm::mat4_cast(getRotation());
glm::mat4 scale = glm::scale(getDimensions());
glm::mat4 registration = glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
return translation * rotation * scale * registration;
}
glm::mat4 EntityItem::getWorldToEntityMatrix() const {
return glm::inverse(getEntityToWorldMatrix());
}
glm::vec3 EntityItem::entityToWorld(const glm::vec3 point) const {
return glm::vec3(getEntityToWorldMatrix() * glm::vec4(point, 1.0f));
}
glm::vec3 EntityItem::worldToEntity(const glm::vec3 point) const {
return glm::vec3(getWorldToEntityMatrix() * glm::vec4(point, 1.0f));
}
bool EntityItem::lifetimeHasExpired() const {
return isMortal() && (getAge() > getLifetime());
}
@ -1062,18 +1084,11 @@ float EntityItem::getRadius() const {
bool EntityItem::contains(const glm::vec3& point) const {
switch (getShapeType()) {
case SHAPE_TYPE_BOX: {
// Transform point to be in a space where the box is a 1m cube centered on the origin.
glm::vec3 transformedPoint = (glm::inverse(getRotation()) * (point - getPosition())) / (getDimensions() / 2.0f);
return AABox(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f).contains(transformedPoint);
}
case SHAPE_TYPE_BOX:
return AABox(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f).contains(worldToEntity(point));
case SHAPE_TYPE_SPHERE:
case SHAPE_TYPE_ELLIPSOID: {
// Transform point to be in a space where the elipsoide is a perfect sphere centered on the origin.
glm::vec3 transformedPoint = (glm::inverse(getRotation()) * (point - getPosition())) / (getDimensions() / 2.0f);
// Return whether said point is inside the sphere.
return glm::length(transformedPoint) <= 1.0f;
}
case SHAPE_TYPE_ELLIPSOID:
return glm::length(worldToEntity(point)) <= 0.5f;
default:
return getAABox().contains(point);
}

View file

@ -297,6 +297,11 @@ public:
static void setSendPhysicsUpdates(bool value) { _sendPhysicsUpdates = value; }
static bool getSendPhysicsUpdates() { return _sendPhysicsUpdates; }
glm::mat4 getEntityToWorldMatrix() const;
glm::mat4 getWorldToEntityMatrix() const;
glm::vec3 worldToEntity(const glm::vec3 point) const;
glm::vec3 entityToWorld(const glm::vec3 point) const;
protected:
static bool _sendPhysicsUpdates;

View file

@ -96,11 +96,7 @@ bool SphereEntityItem::findDetailedRayIntersection(const glm::vec3& origin, cons
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
void** intersectedObject, bool precisionPicking) const {
// 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 entityToWorldMatrix = getEntityToWorldMatrix();
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, 0.0f)));
@ -112,7 +108,7 @@ bool SphereEntityItem::findDetailedRayIntersection(const glm::vec3& origin, cons
glm::vec3 entityFrameHitAt = entityFrameOrigin + (entityFrameDirection * localDistance);
// then translate back to work coordinates
glm::vec3 hitAt = glm::vec3(entityToWorldMatrix * glm::vec4(entityFrameHitAt, 1.0f));
distance = glm::distance(origin,hitAt);
distance = glm::distance(origin, hitAt);
return true;
}
return false;