123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- #pragma once
- #include <Mathematics/Logger.h>
- #include <Mathematics/ContPointInPolygon2.h>
- #include <Mathematics/IntrRay3Plane3.h>
- #include <Mathematics/IntrRay3Triangle3.h>
- #include <vector>
- namespace WwiseGTE
- {
- template <typename Real>
- class PointInPolyhedron3
- {
- public:
-
- class TriangleFace
- {
- public:
-
-
-
- std::array<int, 3> indices;
-
-
- Plane3<Real> plane;
- };
-
- PointInPolyhedron3(int numPoints, Vector3<Real> const* points,
- int numFaces, TriangleFace const* faces, int numRays,
- Vector3<Real> const* directions)
- :
- mNumPoints(numPoints),
- mPoints(points),
- mNumFaces(numFaces),
- mTFaces(faces),
- mCFaces(nullptr),
- mSFaces(nullptr),
- mMethod(0),
- mNumRays(numRays),
- mDirections(directions)
- {
- }
-
- class ConvexFace
- {
- public:
-
-
-
- std::vector<int> indices;
-
-
- Plane3<Real> plane;
- };
-
-
-
-
-
-
-
-
-
-
-
- PointInPolyhedron3(int numPoints, Vector3<Real> const* points,
- int numFaces, ConvexFace const* faces, int numRays,
- Vector3<Real> const* directions, unsigned int method)
- :
- mNumPoints(numPoints),
- mPoints(points),
- mNumFaces(numFaces),
- mTFaces(nullptr),
- mCFaces(faces),
- mSFaces(nullptr),
- mMethod(method),
- mNumRays(numRays),
- mDirections(directions)
- {
- }
-
-
- class SimpleFace
- {
- public:
-
-
-
- std::vector<int> indices;
-
-
- Plane3<Real> plane;
-
-
-
- std::vector<int> triangles;
- };
-
-
-
-
-
-
-
-
-
-
-
- PointInPolyhedron3(int numPoints, Vector3<Real> const* points,
- int numFaces, SimpleFace const* faces, int numRays,
- Vector3<Real> const* directions, unsigned int method)
- :
- mNumPoints(numPoints),
- mPoints(points),
- mNumFaces(numFaces),
- mTFaces(nullptr),
- mCFaces(nullptr),
- mSFaces(faces),
- mMethod(method),
- mNumRays(numRays),
- mDirections(directions)
- {
- }
-
-
- bool Contains(Vector3<Real> const& p) const
- {
- if (mTFaces)
- {
- return ContainsT0(p);
- }
- if (mCFaces)
- {
- if (mMethod == 0)
- {
- return ContainsC0(p);
- }
- return ContainsC1C2(p, mMethod);
- }
- if (mSFaces)
- {
- if (mMethod == 0)
- {
- return ContainsS0(p);
- }
- if (mMethod == 1)
- {
- return ContainsS1(p);
- }
- }
- return false;
- }
- private:
-
-
-
-
-
- static bool FastNoIntersect(Ray3<Real> const& ray, Plane3<Real> const& plane)
- {
- Real planeDistance = Dot(plane.normal, ray.origin) - plane.constant;
- Real planeAngle = Dot(plane.normal, ray.direction);
- if (planeDistance < (Real)0)
- {
-
- if (planeAngle <= (Real)0)
- {
-
- return true;
- }
- }
- if (planeDistance > (Real)0)
- {
-
- if (planeAngle >= (Real)0)
- {
-
- return true;
- }
- }
- return false;
- }
-
- bool ContainsT0(Vector3<Real> const& p) const
- {
- int insideCount = 0;
- TIQuery<Real, Ray3<Real>, Triangle3<Real>> rtQuery;
- Triangle3<Real> triangle;
- Ray3<Real> ray;
- ray.origin = p;
- for (int j = 0; j < mNumRays; ++j)
- {
- ray.direction = mDirections[j];
-
- bool odd = false;
- TriangleFace const* face = mTFaces;
- for (int i = 0; i < mNumFaces; ++i, ++face)
- {
-
- if (FastNoIntersect(ray, face->plane))
- {
- continue;
- }
-
- for (int k = 0; k < 3; ++k)
- {
- triangle.v[k] = mPoints[face->indices[k]];
- }
-
- if (rtQuery(ray, triangle).intersect)
- {
-
- odd = !odd;
- }
- }
- if (odd)
- {
- insideCount++;
- }
- }
- return insideCount > mNumRays / 2;
- }
-
- bool ContainsC0(Vector3<Real> const& p) const
- {
- int insideCount = 0;
- TIQuery<Real, Ray3<Real>, Triangle3<Real>> rtQuery;
- Triangle3<Real> triangle;
- Ray3<Real> ray;
- ray.origin = p;
- for (int j = 0; j < mNumRays; ++j)
- {
- ray.direction = mDirections[j];
-
- bool odd = false;
- ConvexFace const* face = mCFaces;
- for (int i = 0; i < mNumFaces; ++i, ++face)
- {
-
- if (FastNoIntersect(ray, face->plane))
- {
- continue;
- }
-
- size_t numVerticesM1 = face->indices.size() - 1;
- triangle.v[0] = mPoints[face->indices[0]];
- for (size_t k = 1; k < numVerticesM1; ++k)
- {
- triangle.v[1] = mPoints[face->indices[k]];
- triangle.v[2] = mPoints[face->indices[k + 1]];
- if (rtQuery(ray, triangle).intersect)
- {
-
- odd = !odd;
- }
- }
- }
- if (odd)
- {
- insideCount++;
- }
- }
- return insideCount > mNumRays / 2;
- }
- bool ContainsC1C2(Vector3<Real> const& p, unsigned int method) const
- {
- int insideCount = 0;
- FIQuery<Real, Ray3<Real>, Plane3<Real>> rpQuery;
- Ray3<Real> ray;
- ray.origin = p;
- for (int j = 0; j < mNumRays; ++j)
- {
- ray.direction = mDirections[j];
-
- bool odd = false;
- ConvexFace const* face = mCFaces;
- for (int i = 0; i < mNumFaces; ++i, ++face)
- {
-
- if (FastNoIntersect(ray, face->plane))
- {
- continue;
- }
-
- auto result = rpQuery(ray, face->plane);
-
-
-
- LogAssert(result.intersect, "Unexpected condition.");
-
-
- Vector3<Real> const& V0 = mPoints[face->indices[0]];
- Vector3<Real> basis[3];
- basis[0] = face->plane.normal;
- ComputeOrthogonalComplement(1, basis);
-
- Vector3<Real> diff = result.point - V0;
- Vector2<Real> projIntersect{ Dot(basis[1], diff), Dot(basis[2], diff) };
-
- if (face->indices.size() > mProjVertices.size())
- {
- mProjVertices.resize(face->indices.size());
- }
-
-
- size_t numIndices = face->indices.size();
- mProjVertices[0] = Vector2<Real>::Zero();
- for (size_t k = 1; k < numIndices; ++k)
- {
- diff = mPoints[face->indices[k]] - V0;
- mProjVertices[k][0] = Dot(basis[1], diff);
- mProjVertices[k][1] = Dot(basis[2], diff);
- }
-
-
- PointInPolygon2<Real> PIP(static_cast<int>(mProjVertices.size()),
- &mProjVertices[0]);
- if (method == 1)
- {
- if (PIP.ContainsConvexOrderN(projIntersect))
- {
-
- odd = !odd;
- }
- }
- else
- {
- if (PIP.ContainsConvexOrderLogN(projIntersect))
- {
-
- odd = !odd;
- }
- }
- }
- if (odd)
- {
- insideCount++;
- }
- }
- return insideCount > mNumRays / 2;
- }
-
- bool ContainsS0(Vector3<Real> const& p) const
- {
- int insideCount = 0;
- TIQuery<Real, Ray3<Real>, Triangle3<Real>> rtQuery;
- Triangle3<Real> triangle;
- Ray3<Real> ray;
- ray.origin = p;
- for (int j = 0; j < mNumRays; ++j)
- {
- ray.direction = mDirections[j];
-
- bool odd = false;
- SimpleFace const* face = mSFaces;
- for (int i = 0; i < mNumFaces; ++i, ++face)
- {
-
- if (FastNoIntersect(ray, face->plane))
- {
- continue;
- }
-
- size_t numTriangles = face->triangles.size() / 3;
- LogAssert(numTriangles > 0, "Triangulation must exist.");
-
- int const* currIndex = &face->triangles[0];
- for (size_t t = 0; t < numTriangles; ++t)
- {
-
- for (int k = 0; k < 3; ++k)
- {
- triangle.v[k] = mPoints[*currIndex++];
- }
-
- if (rtQuery(ray, triangle).intersect)
- {
-
- odd = !odd;
- }
- }
- }
- if (odd)
- {
- insideCount++;
- }
- }
- return insideCount > mNumRays / 2;
- }
- bool ContainsS1(Vector3<Real> const& p) const
- {
- int insideCount = 0;
- FIQuery<Real, Ray3<Real>, Plane3<Real>> rpQuery;
- Ray3<Real> ray;
- ray.origin = p;
- for (int j = 0; j < mNumRays; ++j)
- {
- ray.direction = mDirections[j];
-
- bool odd = false;
- SimpleFace const* face = mSFaces;
- for (int i = 0; i < mNumFaces; ++i, ++face)
- {
-
- if (FastNoIntersect(ray, face->plane))
- {
- continue;
- }
-
- auto result = rpQuery(ray, face->plane);
-
-
-
- LogAssert(result.intersect, "Unexpected condition.");
-
-
- Vector3<Real> const& V0 = mPoints[face->indices[0]];
- Vector3<Real> basis[3];
- basis[0] = face->plane.normal;
- ComputeOrthogonalComplement(1, basis);
-
- Vector3<Real> diff = result.point - V0;
- Vector2<Real> projIntersect{ Dot(basis[1], diff), Dot(basis[2], diff) };
-
- if (face->indices.size() > mProjVertices.size())
- {
- mProjVertices.resize(face->indices.size());
- }
-
-
- size_t numIndices = face->indices.size();
- mProjVertices[0] = Vector2<Real>::Zero();
- for (size_t k = 1; k < numIndices; ++k)
- {
- diff = mPoints[face->indices[k]] - V0;
- mProjVertices[k][0] = Dot(basis[1], diff);
- mProjVertices[k][1] = Dot(basis[2], diff);
- }
-
-
- PointInPolygon2<Real> PIP(static_cast<int>(mProjVertices.size()),
- &mProjVertices[0]);
- if (PIP.Contains(projIntersect))
- {
-
- odd = !odd;
- }
- }
- if (odd)
- {
- insideCount++;
- }
- }
- return insideCount > mNumRays / 2;
- }
- int mNumPoints;
- Vector3<Real> const* mPoints;
- int mNumFaces;
- TriangleFace const* mTFaces;
- ConvexFace const* mCFaces;
- SimpleFace const* mSFaces;
- unsigned int mMethod;
- int mNumRays;
- Vector3<Real> const* mDirections;
-
-
-
- mutable std::vector<Vector2<Real>> mProjVertices;
- };
- }
|