mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
faster aabox ray intersection and pre-computed inverse direction
This commit is contained in:
parent
3d048c77ba
commit
aae06e8f49
15 changed files with 69 additions and 91 deletions
|
@ -180,7 +180,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
|
||||||
float distance;
|
float distance;
|
||||||
BoxFace face;
|
BoxFace face;
|
||||||
glm::vec3 normal;
|
glm::vec3 normal;
|
||||||
boundingBox.findRayIntersection(cameraPosition, direction, distance, face, normal);
|
boundingBox.findRayIntersection(cameraPosition, direction, 1.0f / direction, distance, face, normal);
|
||||||
float offsetAngle = -CONTEXT_OVERLAY_OFFSET_ANGLE;
|
float offsetAngle = -CONTEXT_OVERLAY_OFFSET_ANGLE;
|
||||||
if (event.getID() == 1) { // "1" is left hand
|
if (event.getID() == 1) { // "1" is left hand
|
||||||
offsetAngle *= -1.0f;
|
offsetAngle *= -1.0f;
|
||||||
|
|
|
@ -88,7 +88,7 @@ bool Volume3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve
|
||||||
|
|
||||||
// we can use the AABox's ray intersection by mapping our origin and direction into the overlays frame
|
// we can use the AABox's ray intersection by mapping our origin and direction into the overlays frame
|
||||||
// and testing intersection there.
|
// and testing intersection there.
|
||||||
bool hit = _localBoundingBox.findRayIntersection(overlayFrameOrigin, overlayFrameDirection, distance, face, surfaceNormal);
|
bool hit = _localBoundingBox.findRayIntersection(overlayFrameOrigin, overlayFrameDirection, 1.0f / overlayFrameDirection, distance, face, surfaceNormal);
|
||||||
|
|
||||||
if (hit) {
|
if (hit) {
|
||||||
surfaceNormal = transform.getRotation() * surfaceNormal;
|
surfaceNormal = transform.getRotation() * surfaceNormal;
|
||||||
|
|
|
@ -596,8 +596,8 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
|
||||||
voxelBox += result3 - Vectors::HALF;
|
voxelBox += result3 - Vectors::HALF;
|
||||||
voxelBox += result3 + Vectors::HALF;
|
voxelBox += result3 + Vectors::HALF;
|
||||||
|
|
||||||
glm::vec4 directionInVoxel = wtvMatrix * glm::vec4(direction, 0.0f);
|
glm::vec3 directionInVoxel = vec3(wtvMatrix * glm::vec4(direction, 0.0f));
|
||||||
return voxelBox.findRayIntersection(glm::vec3(originInVoxel), glm::vec3(directionInVoxel),
|
return voxelBox.findRayIntersection(glm::vec3(originInVoxel), directionInVoxel, 1.0f / directionInVoxel,
|
||||||
distance, face, surfaceNormal);
|
distance, face, surfaceNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
// Inputs
|
// Inputs
|
||||||
glm::vec3 origin;
|
glm::vec3 origin;
|
||||||
glm::vec3 direction;
|
glm::vec3 direction;
|
||||||
|
glm::vec3 invDirection;
|
||||||
const QVector<EntityItemID>& entityIdsToInclude;
|
const QVector<EntityItemID>& entityIdsToInclude;
|
||||||
const QVector<EntityItemID>& entityIdsToDiscard;
|
const QVector<EntityItemID>& entityIdsToDiscard;
|
||||||
bool visibleOnly;
|
bool visibleOnly;
|
||||||
|
@ -847,7 +848,7 @@ float findRayIntersectionSortingOp(const OctreeElementPointer& element, void* ex
|
||||||
float boundDistance = FLT_MAX;
|
float boundDistance = FLT_MAX;
|
||||||
BoxFace face;
|
BoxFace face;
|
||||||
glm::vec3 surfaceNormal;
|
glm::vec3 surfaceNormal;
|
||||||
if (entityTreeElementPointer->getAACube().findRayIntersection(args->origin, args->direction, boundDistance, face, surfaceNormal)) {
|
if (entityTreeElementPointer->getAACube().findRayIntersection(args->origin, args->direction, args->invDirection, boundDistance, face, surfaceNormal)) {
|
||||||
// Don't add this cell if it's already farther than our best distance so far
|
// Don't add this cell if it's already farther than our best distance so far
|
||||||
if (boundDistance < args->distance) {
|
if (boundDistance < args->distance) {
|
||||||
distance = boundDistance;
|
distance = boundDistance;
|
||||||
|
@ -863,7 +864,7 @@ EntityItemID EntityTree::findRayIntersection(const glm::vec3& origin, const glm:
|
||||||
OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo,
|
BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo,
|
||||||
Octree::lockType lockType, bool* accurateResult) {
|
Octree::lockType lockType, bool* accurateResult) {
|
||||||
RayArgs args = { origin, direction, entityIdsToInclude, entityIdsToDiscard,
|
RayArgs args = { origin, direction, 1.0f / direction, entityIdsToInclude, entityIdsToDiscard,
|
||||||
visibleOnly, collidableOnly, precisionPicking, element, distance, face, surfaceNormal, extraInfo, EntityItemID() };
|
visibleOnly, collidableOnly, precisionPicking, element, distance, face, surfaceNormal, extraInfo, EntityItemID() };
|
||||||
distance = FLT_MAX;
|
distance = FLT_MAX;
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,7 @@ EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& ori
|
||||||
float localDistance;
|
float localDistance;
|
||||||
BoxFace localFace;
|
BoxFace localFace;
|
||||||
glm::vec3 localSurfaceNormal;
|
glm::vec3 localSurfaceNormal;
|
||||||
if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, localDistance,
|
if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, 1.0f / entityFrameDirection, localDistance,
|
||||||
localFace, localSurfaceNormal)) {
|
localFace, localSurfaceNormal)) {
|
||||||
if (entityFrameBox.contains(entityFrameOrigin) || localDistance < distance) {
|
if (entityFrameBox.contains(entityFrameOrigin) || localDistance < distance) {
|
||||||
// now ask the entity if we actually intersect
|
// now ask the entity if we actually intersect
|
||||||
|
|
|
@ -376,7 +376,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
||||||
|
|
||||||
// we can use the AABox's intersection by mapping our origin and direction into the model frame
|
// we can use the AABox's intersection by mapping our origin and direction into the model frame
|
||||||
// and testing intersection there.
|
// and testing intersection there.
|
||||||
if (modelFrameBox.findRayIntersection(modelFrameOrigin, modelFrameDirection, distance, face, surfaceNormal)) {
|
if (modelFrameBox.findRayIntersection(modelFrameOrigin, modelFrameDirection, 1.0f / modelFrameDirection, distance, face, surfaceNormal)) {
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
|
|
||||||
float bestDistance = FLT_MAX;
|
float bestDistance = FLT_MAX;
|
||||||
|
@ -400,6 +400,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
||||||
|
|
||||||
glm::vec3 meshFrameOrigin = glm::vec3(worldToMeshMatrix * glm::vec4(origin, 1.0f));
|
glm::vec3 meshFrameOrigin = glm::vec3(worldToMeshMatrix * glm::vec4(origin, 1.0f));
|
||||||
glm::vec3 meshFrameDirection = glm::vec3(worldToMeshMatrix * glm::vec4(direction, 0.0f));
|
glm::vec3 meshFrameDirection = glm::vec3(worldToMeshMatrix * glm::vec4(direction, 0.0f));
|
||||||
|
glm::vec3 meshFrameInvDirection = 1.0f / meshFrameDirection;
|
||||||
|
|
||||||
int shapeID = 0;
|
int shapeID = 0;
|
||||||
int subMeshIndex = 0;
|
int subMeshIndex = 0;
|
||||||
|
@ -415,8 +416,8 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
||||||
float partBoundDistance = FLT_MAX;
|
float partBoundDistance = FLT_MAX;
|
||||||
BoxFace partBoundFace;
|
BoxFace partBoundFace;
|
||||||
glm::vec3 partBoundNormal;
|
glm::vec3 partBoundNormal;
|
||||||
if (partTriangleSet.getBounds().findRayIntersection(meshFrameOrigin, meshFrameDirection, partBoundDistance,
|
if (partTriangleSet.getBounds().findRayIntersection(meshFrameOrigin, meshFrameDirection, meshFrameInvDirection,
|
||||||
partBoundFace, partBoundNormal)) {
|
partBoundDistance, partBoundFace, partBoundNormal)) {
|
||||||
priority = partBoundDistance;
|
priority = partBoundDistance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -444,7 +445,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
||||||
float triangleSetDistance = FLT_MAX;
|
float triangleSetDistance = FLT_MAX;
|
||||||
BoxFace triangleSetFace;
|
BoxFace triangleSetFace;
|
||||||
Triangle triangleSetTriangle;
|
Triangle triangleSetTriangle;
|
||||||
if (sortedTriangleSet.triangleSet->findRayIntersection(meshFrameOrigin, meshFrameDirection, triangleSetDistance, triangleSetFace,
|
if (sortedTriangleSet.triangleSet->findRayIntersection(meshFrameOrigin, meshFrameDirection, meshFrameInvDirection, triangleSetDistance, triangleSetFace,
|
||||||
triangleSetTriangle, pickAgainstTriangles, allowBackface)) {
|
triangleSetTriangle, pickAgainstTriangles, allowBackface)) {
|
||||||
if (triangleSetDistance < bestDistance) {
|
if (triangleSetDistance < bestDistance) {
|
||||||
bestDistance = triangleSetDistance;
|
bestDistance = triangleSetDistance;
|
||||||
|
|
|
@ -33,6 +33,7 @@ void PickItemsJob::run(const render::RenderContextPointer& renderContext, const
|
||||||
render::ItemBound PickItemsJob::findNearestItem(const render::RenderContextPointer& renderContext, const render::ItemBounds& inputs, float& minIsectDistance) const {
|
render::ItemBound PickItemsJob::findNearestItem(const render::RenderContextPointer& renderContext, const render::ItemBounds& inputs, float& minIsectDistance) const {
|
||||||
const glm::vec3 rayOrigin = renderContext->args->getViewFrustum().getPosition();
|
const glm::vec3 rayOrigin = renderContext->args->getViewFrustum().getPosition();
|
||||||
const glm::vec3 rayDirection = renderContext->args->getViewFrustum().getDirection();
|
const glm::vec3 rayDirection = renderContext->args->getViewFrustum().getDirection();
|
||||||
|
const glm::vec3 rayInvDirection = 1.0f / rayDirection;
|
||||||
BoxFace face;
|
BoxFace face;
|
||||||
glm::vec3 normal;
|
glm::vec3 normal;
|
||||||
float isectDistance;
|
float isectDistance;
|
||||||
|
@ -42,7 +43,7 @@ render::ItemBound PickItemsJob::findNearestItem(const render::RenderContextPoint
|
||||||
render::ItemKey itemKey;
|
render::ItemKey itemKey;
|
||||||
|
|
||||||
for (const auto& itemBound : inputs) {
|
for (const auto& itemBound : inputs) {
|
||||||
if (!itemBound.bound.contains(rayOrigin) && itemBound.bound.findRayIntersection(rayOrigin, rayDirection, isectDistance, face, normal)) {
|
if (!itemBound.bound.contains(rayOrigin) && itemBound.bound.findRayIntersection(rayOrigin, rayDirection, rayInvDirection, isectDistance, face, normal)) {
|
||||||
auto& item = renderContext->_scene->getItem(itemBound.id);
|
auto& item = renderContext->_scene->getItem(itemBound.id);
|
||||||
itemKey = item.getKey();
|
itemKey = item.getKey();
|
||||||
if (itemKey.isWorldSpace() && isectDistance>minDistance && isectDistance < minIsectDistance && isectDistance<maxDistance
|
if (itemKey.isWorldSpace() && isectDistance>minDistance && isectDistance < minIsectDistance && isectDistance<maxDistance
|
||||||
|
|
|
@ -192,9 +192,9 @@ bool AABox::expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& e
|
||||||
isWithin(start.x + axisDistance*direction.x, expandedCorner.x, expandedSize.x));
|
isWithin(start.x + axisDistance*direction.x, expandedCorner.x, expandedSize.x));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal) const {
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal) const {
|
||||||
return findRayAABoxIntersection(origin, direction, _corner, _scale, distance, face, surfaceNormal);
|
return findRayAABoxIntersection(origin, direction, invDirection, _corner, _scale, distance, face, surfaceNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AABox::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
bool AABox::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
||||||
|
|
|
@ -69,7 +69,7 @@ public:
|
||||||
|
|
||||||
bool expandedContains(const glm::vec3& point, float expansion) const;
|
bool expandedContains(const glm::vec3& point, float expansion) const;
|
||||||
bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const;
|
bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const;
|
||||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal) const;
|
BoxFace& face, glm::vec3& surfaceNormal) const;
|
||||||
bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
||||||
float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal) const;
|
float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal) const;
|
||||||
|
|
|
@ -187,9 +187,9 @@ bool AACube::expandedIntersectsSegment(const glm::vec3& start, const glm::vec3&
|
||||||
isWithin(start.x + axisDistance*direction.x, expandedCorner.x, expandedSize.x));
|
isWithin(start.x + axisDistance*direction.x, expandedCorner.x, expandedSize.x));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AACube::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
bool AACube::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal) const {
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal) const {
|
||||||
return findRayAABoxIntersection(origin, direction, _corner, glm::vec3(_scale), distance, face, surfaceNormal);
|
return findRayAABoxIntersection(origin, direction, invDirection, _corner, glm::vec3(_scale), distance, face, surfaceNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AACube::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
bool AACube::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
||||||
|
|
|
@ -56,10 +56,10 @@ public:
|
||||||
bool touches(const AABox& otherBox) const;
|
bool touches(const AABox& otherBox) const;
|
||||||
bool expandedContains(const glm::vec3& point, float expansion) const;
|
bool expandedContains(const glm::vec3& point, float expansion) const;
|
||||||
bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const;
|
bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const;
|
||||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal) const;
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal) const;
|
||||||
bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
||||||
float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal) const;
|
float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal) const;
|
||||||
bool touchesSphere(const glm::vec3& center, float radius) const;
|
bool touchesSphere(const glm::vec3& center, float radius) const;
|
||||||
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const;
|
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const;
|
||||||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) const;
|
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) const;
|
||||||
|
|
|
@ -214,65 +214,40 @@ bool findInsideOutIntersection(float origin, float direction, float corner, floa
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findRayAABoxIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& corner, const glm::vec3& scale, float& distance,
|
// https://tavianator.com/fast-branchless-raybounding-box-intersections/
|
||||||
BoxFace& face, glm::vec3& surfaceNormal) {
|
bool findRayAABoxIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection,
|
||||||
// handle the trivial case where the box contains the origin
|
const glm::vec3& corner, const glm::vec3& scale, float& distance, BoxFace& face, glm::vec3& surfaceNormal) {
|
||||||
if (aaBoxContains(origin, corner, scale)) {
|
float t1, t2, newTmin, newTmax, tmin = -INFINITY, tmax = INFINITY;
|
||||||
// We still want to calculate the distance from the origin to the inside out plane
|
int minAxis = -1, maxAxis = -1;
|
||||||
float axisDistance;
|
|
||||||
if ((findInsideOutIntersection(origin.x, direction.x, corner.x, scale.x, axisDistance) && axisDistance >= 0 &&
|
for (int i = 0; i < 3; ++i) {
|
||||||
isWithin(origin.y + axisDistance * direction.y, corner.y, scale.y) &&
|
t1 = (corner[i] - origin[i]) * invDirection[i];
|
||||||
isWithin(origin.z + axisDistance * direction.z, corner.z, scale.z))) {
|
t2 = (corner[i] + scale[i] - origin[i]) * invDirection[i];
|
||||||
distance = axisDistance;
|
|
||||||
face = direction.x > 0 ? MAX_X_FACE : MIN_X_FACE;
|
newTmin = glm::min(t1, t2);
|
||||||
surfaceNormal = glm::vec3(direction.x > 0 ? 1.0f : -1.0f, 0.0f, 0.0f);
|
newTmax = glm::max(t1, t2);
|
||||||
return true;
|
|
||||||
}
|
minAxis = newTmin > tmin ? i : minAxis;
|
||||||
if ((findInsideOutIntersection(origin.y, direction.y, corner.y, scale.y, axisDistance) && axisDistance >= 0 &&
|
tmin = glm::max(tmin, newTmin);
|
||||||
isWithin(origin.x + axisDistance * direction.x, corner.x, scale.x) &&
|
maxAxis = newTmax < tmax ? i : maxAxis;
|
||||||
isWithin(origin.z + axisDistance * direction.z, corner.z, scale.z))) {
|
tmax = glm::min(tmax, newTmax);
|
||||||
distance = axisDistance;
|
|
||||||
face = direction.y > 0 ? MAX_Y_FACE : MIN_Y_FACE;
|
|
||||||
surfaceNormal = glm::vec3(0.0f, direction.y > 0 ? 1.0f : -1.0f, 0.0f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ((findInsideOutIntersection(origin.z, direction.z, corner.z, scale.z, axisDistance) && axisDistance >= 0 &&
|
|
||||||
isWithin(origin.y + axisDistance * direction.y, corner.y, scale.y) &&
|
|
||||||
isWithin(origin.x + axisDistance * direction.x, corner.x, scale.x))) {
|
|
||||||
distance = axisDistance;
|
|
||||||
face = direction.z > 0 ? MAX_Z_FACE : MIN_Z_FACE;
|
|
||||||
surfaceNormal = glm::vec3(0.0f, 0.0f, direction.z > 0 ? 1.0f : -1.0f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// This case is unexpected, but mimics the previous behavior for inside out intersections
|
|
||||||
distance = 0;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check each axis
|
bool inside = tmin < 0.0f;
|
||||||
float axisDistance;
|
if (tmax >= glm::max(tmin, 0.0f)) {
|
||||||
if ((findIntersection(origin.x, direction.x, corner.x, scale.x, axisDistance) && axisDistance >= 0 &&
|
if (inside) {
|
||||||
isWithin(origin.y + axisDistance * direction.y, corner.y, scale.y) &&
|
distance = tmax;
|
||||||
isWithin(origin.z + axisDistance * direction.z, corner.z, scale.z))) {
|
bool positiveDirection = direction[maxAxis] > 0.0f;
|
||||||
distance = axisDistance;
|
surfaceNormal = glm::vec3(0.0f);
|
||||||
face = direction.x > 0 ? MIN_X_FACE : MAX_X_FACE;
|
surfaceNormal[maxAxis] = positiveDirection ? -1.0f : 1.0f;
|
||||||
surfaceNormal = glm::vec3(direction.x > 0 ? -1.0f : 1.0f, 0.0f, 0.0f);
|
face = positiveDirection ? BoxFace(2 * maxAxis + 1) : BoxFace(2 * maxAxis);
|
||||||
return true;
|
} else {
|
||||||
}
|
distance = tmin;
|
||||||
if ((findIntersection(origin.y, direction.y, corner.y, scale.y, axisDistance) && axisDistance >= 0 &&
|
bool positiveDirection = direction[minAxis] > 0.0f;
|
||||||
isWithin(origin.x + axisDistance * direction.x, corner.x, scale.x) &&
|
surfaceNormal = glm::vec3(0.0f);
|
||||||
isWithin(origin.z + axisDistance * direction.z, corner.z, scale.z))) {
|
surfaceNormal[minAxis] = positiveDirection ? -1.0f : 1.0f;
|
||||||
distance = axisDistance;
|
face = positiveDirection ? BoxFace(2 * minAxis) : BoxFace(2 * minAxis + 1);
|
||||||
face = direction.y > 0 ? MIN_Y_FACE : MAX_Y_FACE;
|
}
|
||||||
surfaceNormal = glm::vec3(0.0f, direction.y > 0 ? -1.0f : 1.0f, 0.0f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ((findIntersection(origin.z, direction.z, corner.z, scale.z, axisDistance) && axisDistance >= 0 &&
|
|
||||||
isWithin(origin.y + axisDistance * direction.y, corner.y, scale.y) &&
|
|
||||||
isWithin(origin.x + axisDistance * direction.x, corner.x, scale.x))) {
|
|
||||||
distance = axisDistance;
|
|
||||||
face = direction.z > 0 ? MIN_Z_FACE : MAX_Z_FACE;
|
|
||||||
surfaceNormal = glm::vec3(0.0f, 0.0f, direction.z > 0 ? -1.0f : 1.0f);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -76,8 +76,8 @@ glm::vec3 addPenetrations(const glm::vec3& currentPenetration, const glm::vec3&
|
||||||
|
|
||||||
bool findIntersection(float origin, float direction, float corner, float size, float& distance);
|
bool findIntersection(float origin, float direction, float corner, float size, float& distance);
|
||||||
bool findInsideOutIntersection(float origin, float direction, float corner, float size, float& distance);
|
bool findInsideOutIntersection(float origin, float direction, float corner, float size, float& distance);
|
||||||
bool findRayAABoxIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& corner, const glm::vec3& scale, float& distance,
|
bool findRayAABoxIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal);
|
const glm::vec3& corner, const glm::vec3& scale, float& distance, BoxFace& face, glm::vec3& surfaceNormal);
|
||||||
|
|
||||||
bool findRaySphereIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool findRaySphereIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
const glm::vec3& center, float radius, float& distance);
|
const glm::vec3& center, float radius, float& distance);
|
||||||
|
|
|
@ -176,7 +176,7 @@ void TriangleSet::TriangleTreeCell::insert(size_t triangleIndex) {
|
||||||
_triangleIndices.push_back(triangleIndex);
|
_triangleIndices.push_back(triangleIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection, float& distance,
|
||||||
BoxFace& face, Triangle& triangle, bool precision, bool allowBackface) {
|
BoxFace& face, Triangle& triangle, bool precision, bool allowBackface) {
|
||||||
if (!_isBalanced) {
|
if (!_isBalanced) {
|
||||||
balanceTree();
|
balanceTree();
|
||||||
|
@ -184,7 +184,7 @@ bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3&
|
||||||
|
|
||||||
float localDistance = distance;
|
float localDistance = distance;
|
||||||
int trianglesTouched = 0;
|
int trianglesTouched = 0;
|
||||||
bool hit = _triangleTree.findRayIntersection(origin, direction, localDistance, face, triangle, precision, trianglesTouched, allowBackface);
|
bool hit = _triangleTree.findRayIntersection(origin, direction, invDirection, localDistance, face, triangle, precision, trianglesTouched, allowBackface);
|
||||||
if (hit) {
|
if (hit) {
|
||||||
distance = localDistance;
|
distance = localDistance;
|
||||||
}
|
}
|
||||||
|
@ -232,9 +232,9 @@ bool TriangleSet::TriangleTreeCell::findRayIntersectionInternal(const glm::vec3&
|
||||||
return intersectedSomething;
|
return intersectedSomething;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TriangleSet::TriangleTreeCell::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
bool TriangleSet::TriangleTreeCell::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection,
|
||||||
BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched,
|
float& distance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched,
|
||||||
bool allowBackface) {
|
bool allowBackface) {
|
||||||
if (_population < 1) {
|
if (_population < 1) {
|
||||||
return false; // no triangles below here, so we can't intersect
|
return false; // no triangles below here, so we can't intersect
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ bool TriangleSet::TriangleTreeCell::findRayIntersection(const glm::vec3& origin,
|
||||||
float childBoundDistance = FLT_MAX;
|
float childBoundDistance = FLT_MAX;
|
||||||
BoxFace childBoundFace;
|
BoxFace childBoundFace;
|
||||||
glm::vec3 childBoundNormal;
|
glm::vec3 childBoundNormal;
|
||||||
if (child->getBounds().findRayIntersection(origin, direction, childBoundDistance, childBoundFace, childBoundNormal)) {
|
if (child->getBounds().findRayIntersection(origin, direction, invDirection, childBoundDistance, childBoundFace, childBoundNormal)) {
|
||||||
// We only need to add this cell if it's closer than the local triangle set intersection (if there was one)
|
// We only need to add this cell if it's closer than the local triangle set intersection (if there was one)
|
||||||
if (childBoundDistance < bestLocalDistance) {
|
if (childBoundDistance < bestLocalDistance) {
|
||||||
priority = childBoundDistance;
|
priority = childBoundDistance;
|
||||||
|
@ -301,11 +301,11 @@ bool TriangleSet::TriangleTreeCell::findRayIntersection(const glm::vec3& origin,
|
||||||
if (!precision && childDistance < EPSILON) {
|
if (!precision && childDistance < EPSILON) {
|
||||||
BoxFace childBoundFace;
|
BoxFace childBoundFace;
|
||||||
glm::vec3 childBoundNormal;
|
glm::vec3 childBoundNormal;
|
||||||
sortedTriangleCell.second->getBounds().findRayIntersection(origin, direction, childDistance, childBoundFace, childBoundNormal);
|
sortedTriangleCell.second->getBounds().findRayIntersection(origin, direction, invDirection, childDistance, childBoundFace, childBoundNormal);
|
||||||
}
|
}
|
||||||
BoxFace childFace;
|
BoxFace childFace;
|
||||||
Triangle childTriangle;
|
Triangle childTriangle;
|
||||||
if (sortedTriangleCell.second->findRayIntersection(origin, direction, childDistance, childFace, childTriangle, precision, trianglesTouched)) {
|
if (sortedTriangleCell.second->findRayIntersection(origin, direction, invDirection, childDistance, childFace, childTriangle, precision, trianglesTouched)) {
|
||||||
if (childDistance < bestLocalDistance) {
|
if (childDistance < bestLocalDistance) {
|
||||||
bestLocalDistance = childDistance;
|
bestLocalDistance = childDistance;
|
||||||
bestLocalFace = childFace;
|
bestLocalFace = childFace;
|
||||||
|
|
|
@ -28,7 +28,7 @@ class TriangleSet {
|
||||||
void reset(const AABox& bounds, int depth = 0);
|
void reset(const AABox& bounds, int depth = 0);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection,
|
||||||
float& distance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched,
|
float& distance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched,
|
||||||
bool allowBackface = false);
|
bool allowBackface = false);
|
||||||
bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
||||||
|
@ -69,7 +69,7 @@ public:
|
||||||
|
|
||||||
void insert(const Triangle& t);
|
void insert(const Triangle& t);
|
||||||
|
|
||||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection,
|
||||||
float& distance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface = false);
|
float& distance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface = false);
|
||||||
bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
||||||
float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface = false);
|
float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface = false);
|
||||||
|
|
Loading…
Reference in a new issue