Add 2d variant of bounding box

This commit is contained in:
Georg Hagen
2025-01-06 00:28:10 +01:00
parent ceee3ef12e
commit 7ef6503a78
5 changed files with 92 additions and 79 deletions

View File

@@ -53,7 +53,7 @@ namespace OpenVulkano::Scene
[[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; }
[[nodiscard]] Math::Vector3f& GetPosition() { return m_position; }
[[nodiscard]] bool IsBillboard() const { return m_settings.isBillboard; }
[[nodiscard]] const Math::AABB& GetBoundingBox() const { return m_bbox; }
[[nodiscard]] const Math::AABB2f& GetBoundingBox() const { return m_bbox; }
std::optional<RayHit> Intersect(const Ray& ray) const override;
private:
@@ -63,6 +63,6 @@ namespace OpenVulkano::Scene
LabelDrawableSettings m_settings;
LabelUniformData m_labelData;
Math::Vector3f m_position = { 0, 0, 0 };
Math::AABB m_bbox;
Math::AABB2f m_bbox;
};
}

View File

@@ -92,6 +92,12 @@ namespace OpenVulkano::Scene
return {};
}
std::optional<RayHit> Ray::IntersectAABB(const Math::AABB2f& bbox) const
{
//TODO impl that skips z checks
return IntersectAABB(Math::AABB({bbox.GetMin(), 0}, {bbox.GetMax(), 0}));
}
std::optional<RayHit> Ray::IntersectAABB(const Math::AABB& bbox) const
{
RayHit h1, h2;
@@ -108,69 +114,63 @@ namespace OpenVulkano::Scene
int Ray::IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const
{
const auto tmin = (bbox.min - m_origin) / m_dir;
const auto tmax = (bbox.max - m_origin) / m_dir;
float txmin = tmin.x;
float txmax = tmax.x;
float tymin = tmin.y;
float tymax = tmax.y;
float tzmin = tmin.z;
float tzmax = tmax.z;
auto tmin = (bbox.min - m_origin) / m_dir;
auto tmax = (bbox.max - m_origin) / m_dir;
if (txmin > txmax)
if (tmin.x > tmax.x)
{
std::swap(txmin, txmax);
std::swap(tmin.x, tmax.x);
}
if (tymin > tymax)
if (tmin.y > tmax.y)
{
std::swap(tymin, tymax);
std::swap(tmin.y, tmax.y);
}
if ((txmin > tymax) || (tymin > txmax))
if ((tmin.x > tmax.y) || (tmin.y > tmax.x))
{
return 0;
}
if (tymin > txmin)
if (tmin.y > tmin.x)
{
txmin = tymin;
tmin.x = tmin.y;
}
if (tymax < txmax)
if (tmax.y < tmax.x)
{
txmax = tymax;
tmax.x = tmax.y;
}
if (tzmin > tzmax)
if (tmin.z > tmax.z)
{
std::swap(tzmin, tzmax);
std::swap(tmin.z, tmax.z);
}
if ((txmin > tzmax) || (tzmin > txmax))
if ((tmin.x > tmax.z) || (tmin.z > tmax.x))
{
return 0;
}
if (tzmin > txmin)
if (tmin.z > tmin.x)
{
txmin = tzmin;
tmin.x = tmin.z;
}
if (tzmax < txmax)
if (tmax.z < tmax.x)
{
txmax = tzmax;
tmax.x = tmax.z;
}
int intersections = 2;
if (txmin < 0)
if (tmin.x < 0)
{
if (txmax < 0)
if (tmax.x < 0)
{
return 0;
}
intersections--;
txmin = txmax;
tmin.x = tmax.x;
}
p1.point = m_origin + txmin * m_dir;
p2.point = m_origin + txmax * m_dir;
p1.point = m_origin + tmin.x * m_dir;
p2.point = m_origin + tmax.x * m_dir;
p1.distance2 = distance2(m_origin, p1.point);
p2.distance2 = distance2(m_origin, p2.point);
p1.normal = p2.normal = Math::Vector3f(0);
@@ -179,15 +179,11 @@ namespace OpenVulkano::Scene
std::optional<RayHit> Ray::IntersectPlane(const Math::Vector3f& pOrigin, const Math::Vector3f& pNorm) const
{
RayHit hit;
Math::Vector3f norm = normalize(pNorm);
float d;
if (intersectRayPlane(m_origin, m_dir, pOrigin, pNorm, d))
{
hit.SetDistance(d);
hit.point = m_origin + m_dir * d;
hit.normal = norm;
return hit;
return {{ m_origin + m_dir * d, norm, d, d * d }};
}
return {};
}

View File

@@ -20,21 +20,32 @@ namespace OpenVulkano::Scene
Math::Vector3f point;
Math::Vector3f normal;
float distance2;
RayHit() : distance2(0), distance(-1) {}
RayHit(Math::Vector3f point, Math::Vector3f normal, float distance2)
: point(point), normal(normal), distance2(distance2)
{}
RayHit(Math::Vector3f point, Math::Vector3f normal, float distance, float distance2)
: point(point), normal(normal), distance2(distance2), distance(distance)
{}
[[nodiscard]] float GetDistance() const
{
if (distance == -1)
{
distance = std::sqrt(distance2);
}
if (distance == -1) distance = std::sqrt(distance2);
return distance;
}
void SetDistance(float d)
{
this->distance = d;
this->distance2 = d * d;
}
bool operator==(const RayHit& other) const;
bool operator!=(const RayHit& other) const;
private:
mutable float distance = -1;
};
@@ -66,6 +77,7 @@ namespace OpenVulkano::Scene
const Math::Vector3f& n1, const Math::Vector3f& n2) const;
[[nodiscard]] std::optional<RayHit> IntersectQuad(const Math::Vector3f& v0, const Math::Vector3f& v1,
const Math::Vector3f& v2, const Math::Vector3f& v3) const;
[[nodiscard]] std::optional<RayHit> IntersectAABB(const Math::AABB2f& bbox) const;
[[nodiscard]] std::optional<RayHit> IntersectAABB(const Math::AABB& bbox) const;
int IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const;
[[nodiscard]] std::optional<RayHit> IntersectPlane(const Math::Vector3f& pOrigin,

View File

@@ -34,7 +34,7 @@ namespace OpenVulkano::Scene
{
VertexBuffer m_vertexBuffer;
std::shared_ptr<AtlasData> m_atlasData;
Math::AABB m_bbox;
Math::AABB2f m_bbox;
std::string m_text;
size_t m_symbolCount = 0;
TextConfig m_cfg;
@@ -51,7 +51,7 @@ namespace OpenVulkano::Scene
void GenerateText(const std::string& text, const Math::Vector2f& pos = Math::Vector2f(0.f));
void SetConfig(const TextConfig& cfg) { m_cfg = cfg; }
void SetAtlasData(const std::shared_ptr<AtlasData>& atlasData);
[[nodiscard]] Math::AABB& GetBoundingBox() { return m_bbox; }
[[nodiscard]] Math::AABB2f& GetBoundingBox() { return m_bbox; }
[[nodiscard]] TextConfig& GetConfig() { return m_cfg; }
[[nodiscard]] const std::string& GetText() const { return m_text; }
[[nodiscard]] const std::shared_ptr<AtlasData>& GetAtlasData() { return m_atlasData; }