mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 02:31:13 +02:00
Merge pull request #4334 from huffman/edit-ray-improvement
Fix BillboardOverlay::findRayIntersection
This commit is contained in:
commit
0f4e098a61
4 changed files with 56 additions and 34 deletions
|
@ -10,6 +10,8 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
#include "GeometryUtil.h"
|
||||||
|
#include "PlaneShape.h"
|
||||||
|
|
||||||
#include "BillboardOverlay.h"
|
#include "BillboardOverlay.h"
|
||||||
|
|
||||||
|
@ -191,19 +193,25 @@ bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::v
|
||||||
float& distance, BoxFace& face) {
|
float& distance, BoxFace& face) {
|
||||||
|
|
||||||
if (_texture) {
|
if (_texture) {
|
||||||
|
glm::quat rotation;
|
||||||
|
if (_isFacingAvatar) {
|
||||||
|
// rotate about vertical to face the camera
|
||||||
|
rotation = Application::getInstance()->getCamera()->getRotation();
|
||||||
|
rotation *= glm::angleAxis(glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
} else {
|
||||||
|
rotation = _rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Produce the dimensions of the billboard based on the image's aspect ratio and the overlay's scale.
|
||||||
bool isNull = _fromImage.isNull();
|
bool isNull = _fromImage.isNull();
|
||||||
float width = isNull ? _texture->getWidth() : _fromImage.width();
|
float width = isNull ? _texture->getWidth() : _fromImage.width();
|
||||||
float height = isNull ? _texture->getHeight() : _fromImage.height();
|
float height = isNull ? _texture->getHeight() : _fromImage.height();
|
||||||
|
|
||||||
float maxSize = glm::max(width, height);
|
float maxSize = glm::max(width, height);
|
||||||
float x = width / (2.0f * maxSize);
|
glm::vec2 dimensions = _scale * glm::vec2(width / maxSize, height / maxSize);
|
||||||
float y = -height / (2.0f * maxSize);
|
|
||||||
float maxDimension = glm::max(x,y);
|
return findRayRectangleIntersection(origin, direction, rotation, _position, dimensions);
|
||||||
float scaledDimension = maxDimension * _scale;
|
|
||||||
glm::vec3 corner = getCenter() - glm::vec3(scaledDimension, scaledDimension, scaledDimension) ;
|
|
||||||
AACube myCube(corner, scaledDimension * 2.0f);
|
|
||||||
return myCube.findRayIntersection(origin, direction, distance, face);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <StreamUtils.h>
|
#include <StreamUtils.h>
|
||||||
|
|
||||||
|
#include "GeometryUtil.h"
|
||||||
|
|
||||||
#include "Planar3DOverlay.h"
|
#include "Planar3DOverlay.h"
|
||||||
|
|
||||||
const float DEFAULT_SIZE = 1.0f;
|
const float DEFAULT_SIZE = 1.0f;
|
||||||
|
@ -93,29 +95,5 @@ QScriptValue Planar3DOverlay::getProperty(const QString& property) {
|
||||||
|
|
||||||
bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
float& distance, BoxFace& face) {
|
float& distance, BoxFace& face) {
|
||||||
RayIntersectionInfo rayInfo;
|
return findRayRectangleIntersection(origin, direction, _rotation, _position, _dimensions);
|
||||||
rayInfo._rayStart = origin;
|
|
||||||
rayInfo._rayDirection = direction;
|
|
||||||
rayInfo._rayLength = std::numeric_limits<float>::max();
|
|
||||||
|
|
||||||
PlaneShape plane;
|
|
||||||
|
|
||||||
const glm::vec3 UNROTATED_NORMAL(0.0f, 0.0f, -1.0f);
|
|
||||||
glm::vec3 normal = _rotation * UNROTATED_NORMAL;
|
|
||||||
plane.setNormal(normal);
|
|
||||||
plane.setPoint(_position); // the position is definitely a point on our plane
|
|
||||||
|
|
||||||
bool intersects = plane.findRayIntersection(rayInfo);
|
|
||||||
|
|
||||||
if (intersects) {
|
|
||||||
distance = rayInfo._hitDistance;
|
|
||||||
|
|
||||||
glm::vec3 hitPosition = origin + (distance * direction);
|
|
||||||
glm::vec3 localHitPosition = glm::inverse(_rotation) * (hitPosition - _position);
|
|
||||||
glm::vec2 halfDimensions = _dimensions / 2.0f;
|
|
||||||
|
|
||||||
intersects = -halfDimensions.x <= localHitPosition.x && localHitPosition.x <= halfDimensions.x
|
|
||||||
&& -halfDimensions.y <= localHitPosition.y && localHitPosition.y <= halfDimensions.y;
|
|
||||||
}
|
|
||||||
return intersects;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "SharedUtil.h"
|
|
||||||
#include "GeometryUtil.h"
|
#include "GeometryUtil.h"
|
||||||
|
#include "PlaneShape.h"
|
||||||
|
#include "RayIntersectionInfo.h"
|
||||||
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) {
|
glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) {
|
||||||
// compute the projection of the point vector onto the segment vector
|
// compute the projection of the point vector onto the segment vector
|
||||||
|
@ -491,3 +493,34 @@ void PolygonClip::copyCleanArray(int& lengthA, glm::vec2* vertexArrayA, int& len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool findRayRectangleIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
|
const glm::quat& rotation, const glm::vec3& position, const glm::vec2& dimensions) {
|
||||||
|
RayIntersectionInfo rayInfo;
|
||||||
|
rayInfo._rayStart = origin;
|
||||||
|
rayInfo._rayDirection = direction;
|
||||||
|
rayInfo._rayLength = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
|
PlaneShape plane;
|
||||||
|
|
||||||
|
const glm::vec3 UNROTATED_NORMAL(0.0f, 0.0f, -1.0f);
|
||||||
|
glm::vec3 normal = rotation * UNROTATED_NORMAL;
|
||||||
|
plane.setNormal(normal);
|
||||||
|
plane.setPoint(position); // the position is definitely a point on our plane
|
||||||
|
|
||||||
|
bool intersects = plane.findRayIntersection(rayInfo);
|
||||||
|
|
||||||
|
if (intersects) {
|
||||||
|
float distance = rayInfo._hitDistance;
|
||||||
|
|
||||||
|
glm::vec3 hitPosition = origin + (distance * direction);
|
||||||
|
glm::vec3 localHitPosition = glm::inverse(rotation) * (hitPosition - position);
|
||||||
|
|
||||||
|
glm::vec2 halfDimensions = 0.5f * dimensions;
|
||||||
|
|
||||||
|
intersects = -halfDimensions.x <= localHitPosition.x && localHitPosition.x <= halfDimensions.x
|
||||||
|
&& -halfDimensions.y <= localHitPosition.y && localHitPosition.y <= halfDimensions.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return intersects;
|
||||||
|
}
|
||||||
|
|
|
@ -76,6 +76,9 @@ bool findRaySphereIntersection(const glm::vec3& origin, const glm::vec3& directi
|
||||||
bool findRayCapsuleIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool findRayCapsuleIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
const glm::vec3& start, const glm::vec3& end, float radius, float& distance);
|
const glm::vec3& start, const glm::vec3& end, float radius, float& distance);
|
||||||
|
|
||||||
|
bool findRayRectangleIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
|
const glm::quat& rotation, const glm::vec3& position, const glm::vec2& dimensions);
|
||||||
|
|
||||||
bool findRayTriangleIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool findRayTriangleIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, float& distance);
|
const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, float& distance);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue