From 8fb0365e24e6f1c021f952c6f55c9c5523dde65a Mon Sep 17 00:00:00 2001 From: codereader Date: Fri, 14 Jan 2022 17:23:34 +0100 Subject: [PATCH] #5584: Add getSurfaceBounds() method to IModelSurface interface --- include/imodelsurface.h | 3 +++ radiantcore/model/StaticModelSurface.cpp | 5 +++++ radiantcore/model/StaticModelSurface.h | 2 ++ radiantcore/model/export/PatchSurface.cpp | 13 +++++++++++++ radiantcore/model/export/PatchSurface.h | 3 +++ radiantcore/model/md5/MD5Surface.cpp | 5 +++++ radiantcore/model/md5/MD5Surface.h | 2 ++ test/ModelExport.cpp | 13 +++++++++++++ 8 files changed, 46 insertions(+) diff --git a/include/imodelsurface.h b/include/imodelsurface.h index 2c723fc456..75e5fe0e8e 100644 --- a/include/imodelsurface.h +++ b/include/imodelsurface.h @@ -46,6 +46,9 @@ class IModelSurface * respecting the applied skin. */ virtual const std::string& getActiveMaterial() const = 0; + + // Returns the local bounds of this surface + virtual const AABB& getSurfaceBounds() = 0; }; /** diff --git a/radiantcore/model/StaticModelSurface.cpp b/radiantcore/model/StaticModelSurface.cpp index 76b27ef5b7..6b7f4494dc 100644 --- a/radiantcore/model/StaticModelSurface.cpp +++ b/radiantcore/model/StaticModelSurface.cpp @@ -256,6 +256,11 @@ void StaticModelSurface::setActiveMaterial(const std::string& activeMaterial) _activeMaterial = activeMaterial; } +const AABB& StaticModelSurface::getSurfaceBounds() +{ + return getAABB(); +} + bool StaticModelSurface::getIntersection(const Ray& ray, Vector3& intersection, const Matrix4& localToWorld) { Vector3 bestIntersection = ray.origin; diff --git a/radiantcore/model/StaticModelSurface.h b/radiantcore/model/StaticModelSurface.h index bba1aab2df..0fe8eeb7e1 100644 --- a/radiantcore/model/StaticModelSurface.h +++ b/radiantcore/model/StaticModelSurface.h @@ -109,6 +109,8 @@ class StaticModelSurface : const std::string& getActiveMaterial() const override; void setActiveMaterial(const std::string& activeMaterial); + const AABB& getSurfaceBounds() override; + // Returns true if the given ray intersects this surface geometry and fills in // the exact point in the given Vector3, returns false if no intersection was found. bool getIntersection(const Ray& ray, Vector3& intersection, const Matrix4& localToWorld); diff --git a/radiantcore/model/export/PatchSurface.cpp b/radiantcore/model/export/PatchSurface.cpp index c8f3314174..394e443b26 100644 --- a/radiantcore/model/export/PatchSurface.cpp +++ b/radiantcore/model/export/PatchSurface.cpp @@ -27,6 +27,14 @@ PatchSurface::PatchSurface(const std::string& materialName, PatchMesh& mesh) : std::transform(mesh.vertices.begin(), mesh.vertices.end(), std::back_inserter(_vertices), convertPatchVertex); + _bounds = AABB(); + + // Accumulate the bounds + for (const auto& vertex : _vertices) + { + _bounds.includePoint(vertex); + } + // Generate the indices to define the triangles in clockwise order for (std::size_t h = 0; h < mesh.height - 1; ++h) { @@ -94,4 +102,9 @@ const std::vector& PatchSurface::getIndexArray() const return _indices; } +const AABB& PatchSurface::getSurfaceBounds() +{ + return _bounds; +} + } diff --git a/radiantcore/model/export/PatchSurface.h b/radiantcore/model/export/PatchSurface.h index c9ac4d7780..c26c0c23ff 100644 --- a/radiantcore/model/export/PatchSurface.h +++ b/radiantcore/model/export/PatchSurface.h @@ -19,6 +19,7 @@ class PatchSurface : std::vector _vertices; std::vector _indices; std::string _materialName; + AABB _bounds; public: PatchSurface(const std::string& materialName, PatchMesh& mesh); @@ -34,6 +35,8 @@ class PatchSurface : const std::vector& getVertexArray() const override; const std::vector& getIndexArray() const override; + + const AABB& getSurfaceBounds() override; }; } diff --git a/radiantcore/model/md5/MD5Surface.cpp b/radiantcore/model/md5/MD5Surface.cpp index 6e777222af..a80b5e7af5 100644 --- a/radiantcore/model/md5/MD5Surface.cpp +++ b/radiantcore/model/md5/MD5Surface.cpp @@ -277,6 +277,11 @@ void MD5Surface::setActiveMaterial(const std::string& activeMaterial) _activeMaterial = activeMaterial; } +const AABB& MD5Surface::getSurfaceBounds() +{ + return _aabb_local; +} + void MD5Surface::updateToDefaultPose(const MD5Joints& joints) { if (_vertices.size() != _mesh->vertices.size()) diff --git a/radiantcore/model/md5/MD5Surface.h b/radiantcore/model/md5/MD5Surface.h index 13e392a21d..40546361ef 100644 --- a/radiantcore/model/md5/MD5Surface.h +++ b/radiantcore/model/md5/MD5Surface.h @@ -120,6 +120,8 @@ class MD5Surface : const std::string& getActiveMaterial() const override; void setActiveMaterial(const std::string& activeMaterial); + const AABB& getSurfaceBounds() override; + void parseFromTokens(parser::DefTokeniser& tok); // Rebuild the render index array - usually needs to be called only once diff --git a/test/ModelExport.cpp b/test/ModelExport.cpp index 073ea496d1..d9db04dd67 100644 --- a/test/ModelExport.cpp +++ b/test/ModelExport.cpp @@ -254,6 +254,19 @@ class TestModelSurface : { return indices; } + + const AABB& getSurfaceBounds() override + { + static AABB aabb; + aabb = AABB(); + + for (const auto& vertex : vertices) + { + aabb.includePoint(vertex); + } + + return aabb; + } }; TEST_F(ModelExportTest, LwoVertexColoursAddedBySurface)