common: add shrink and clip poly funcs
This commit is contained in:
parent
7300aacdff
commit
3a20d5410b
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <common/cmdlib.hh>
|
||||
#include <common/mathlib.hh>
|
||||
#include <common/polylib.hh>
|
||||
#include <assert.h>
|
||||
|
||||
#include <tuple>
|
||||
|
|
@ -482,3 +483,58 @@ std::pair<bool, glm::vec3> GLM_InterpolateNormal(const std::vector<glm::vec3> &p
|
|||
|
||||
return make_pair(false, vec3(0));
|
||||
}
|
||||
|
||||
static winding_t *glm_to_winding(const std::vector<glm::vec3> &poly)
|
||||
{
|
||||
const int N = poly.size();
|
||||
winding_t *winding = AllocWinding(N);
|
||||
for (int i=0; i<N; i++) {
|
||||
glm_to_vec3_t(poly.at(i), winding->p[i]);
|
||||
}
|
||||
winding->numpoints = N;
|
||||
return winding;
|
||||
}
|
||||
|
||||
static std::vector<glm::vec3> winding_to_glm(const winding_t *w)
|
||||
{
|
||||
if (w == nullptr)
|
||||
return {};
|
||||
std::vector<glm::vec3> res;
|
||||
for (int i=0; i<w->numpoints; i++) {
|
||||
res.push_back(vec3_t_to_glm(w->p[i]));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Returns (front part, back part)
|
||||
std::pair<std::vector<glm::vec3>,std::vector<glm::vec3>> GLM_ClipPoly(const std::vector<glm::vec3> &poly, const glm::vec4 &plane)
|
||||
{
|
||||
vec3_t normal;
|
||||
winding_t *front = nullptr;
|
||||
winding_t *back = nullptr;
|
||||
|
||||
if (poly.empty())
|
||||
return make_pair(vector<vec3>(),vector<vec3>());
|
||||
|
||||
winding_t *w = glm_to_winding(poly);
|
||||
glm_to_vec3_t(vec3(plane), normal);
|
||||
ClipWinding(w, normal, plane.w, &front, &back);
|
||||
|
||||
const auto res = make_pair(winding_to_glm(front), winding_to_glm(back));
|
||||
free(front);
|
||||
free(back);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<glm::vec3> GLM_ShrinkPoly(const std::vector<glm::vec3> &poly, const float amount) {
|
||||
const vector<vec4> edgeplanes = GLM_MakeInwardFacingEdgePlanes(poly);
|
||||
|
||||
vector<vec3> clipped = poly;
|
||||
|
||||
for (const vec4 &edge : edgeplanes) {
|
||||
const vec4 shrunkEdgePlane(vec3(edge), edge.w + 1);
|
||||
clipped = GLM_ClipPoly(clipped, shrunkEdgePlane).first;
|
||||
}
|
||||
|
||||
return clipped;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -332,4 +332,8 @@ std::pair<int, glm::vec3> GLM_ClosestPointOnPolyBoundary(const std::vector<glm::
|
|||
std::pair<bool, glm::vec3> GLM_InterpolateNormal(const std::vector<glm::vec3> &points,
|
||||
const std::vector<glm::vec3> &normals,
|
||||
const glm::vec3 &point);
|
||||
std::vector<glm::vec3> GLM_ShrinkPoly(const std::vector<glm::vec3> &poly, const float amount);
|
||||
/// Returns (front part, back part)
|
||||
std::pair<std::vector<glm::vec3>,std::vector<glm::vec3>> GLM_ClipPoly(const std::vector<glm::vec3> &poly, const glm::vec4 &plane);
|
||||
|
||||
#endif /* __COMMON_MATHLIB_H__ */
|
||||
|
|
|
|||
|
|
@ -411,3 +411,83 @@ TEST(mathlib, InterpolateNormals) {
|
|||
// Outside poly
|
||||
EXPECT_FALSE(GLM_InterpolateNormal(poly, normals, vec3(-0.1, 0, 0)).first);
|
||||
}
|
||||
|
||||
static bool pointsEqualEpsilon(const vec3 &a, const vec3 &b) {
|
||||
return all(epsilonEqual(a, b, vec3(POINT_EQUAL_EPSILON)));
|
||||
}
|
||||
|
||||
static bool polysEqual(const vector<vec3> &p1, const vector<vec3> &p2) {
|
||||
if (p1.size() != p2.size())
|
||||
return false;
|
||||
for (int i=0; i<p1.size(); i++) {
|
||||
if (!pointsEqualEpsilon(p1[i], p2[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(mathlib, ClipPoly1) {
|
||||
const vector<vec3> poly {
|
||||
{ 0,0,0 },
|
||||
{ 0,64,0 },
|
||||
{ 64,64,0 },
|
||||
{ 64,0,0 }
|
||||
};
|
||||
|
||||
const vector<vec3> frontRes {
|
||||
{ 0,0,0 },
|
||||
{ 0,64,0 },
|
||||
{ 32,64,0 },
|
||||
{ 32,0,0 }
|
||||
};
|
||||
|
||||
const vector<vec3> backRes {
|
||||
{ 32,64,0 },
|
||||
{ 64,64,0 },
|
||||
{ 64,0,0 },
|
||||
{ 32,0,0 }
|
||||
};
|
||||
|
||||
auto clipRes = GLM_ClipPoly(poly, vec4(-1,0,0,-32));
|
||||
|
||||
EXPECT_TRUE(polysEqual(frontRes, clipRes.first));
|
||||
EXPECT_TRUE(polysEqual(backRes, clipRes.second));
|
||||
}
|
||||
|
||||
TEST(mathlib, ShrinkPoly1) {
|
||||
const vector<vec3> poly {
|
||||
{ 0,0,0 },
|
||||
{ 0,64,0 },
|
||||
{ 64,64,0 },
|
||||
{ 64,0,0 }
|
||||
};
|
||||
|
||||
const vector<vec3> shrunkPoly {
|
||||
{ 1,1,0 },
|
||||
{ 1,63,0 },
|
||||
{ 63,63,0 },
|
||||
{ 63,1,0 }
|
||||
};
|
||||
|
||||
const auto actualShrunk = GLM_ShrinkPoly(poly, 1.0f);
|
||||
|
||||
EXPECT_TRUE(polysEqual(shrunkPoly, actualShrunk));
|
||||
}
|
||||
|
||||
TEST(mathlib, ShrinkPoly2) {
|
||||
const vector<vec3> poly {
|
||||
{ 0,0,0 },
|
||||
{ 64,64,0 },
|
||||
{ 64,0,0 }
|
||||
};
|
||||
|
||||
const vector<vec3> shrunkPoly {
|
||||
{ 1.0f + sqrtf(2.0f), 1.0f, 0.0f },
|
||||
{ 63.0f, 63.0f - sqrtf(2.0f), 0.0f },
|
||||
{ 63,1,0 },
|
||||
};
|
||||
|
||||
const auto actualShrunk = GLM_ShrinkPoly(poly, 1.0f);
|
||||
|
||||
EXPECT_TRUE(polysEqual(shrunkPoly, actualShrunk));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue