123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- #pragma once
- #include <Mathematics/TIQuery.h>
- #include <Mathematics/AlignedBox.h>
- #include <Mathematics/LCPSolver.h>
- #include <Mathematics/Cylinder3.h>
- #include <Mathematics/Matrix3x3.h>
- namespace WwiseGTE
- {
- template <typename Real>
- class TIQuery<Real, AlignedBox3<Real>, Cylinder3<Real>>
- {
- public:
- struct Result
- {
-
- typename LCPSolverShared<Real>::Result outcome;
- bool intersect;
-
-
- int numLCPIterations;
- };
-
-
-
- void SetMaxLCPIterations(int maxLCPIterations)
- {
- mLCP.SetMaxIterations(maxLCPIterations);
- }
- Result operator()(AlignedBox3<Real> const& box, Cylinder3<Real> const& cylinder)
- {
- Result result;
-
-
- Vector3<Real> corner = box.max - box.min;
- Vector3<Real> origin = cylinder.axis.origin - box.min;
- Vector3<Real> direction = cylinder.axis.direction;
-
- Real halfHeight = cylinder.height * (Real)0.5;
- Matrix3x3<Real> P = (Matrix3x3<Real>::Identity() - OuterProduct(direction, direction));
- Vector3<Real> C = -(P * origin);
- Real originDotDirection = Dot(origin, direction);
- Matrix<5, 3, Real> A;
- A.SetRow(0, { (Real)-1, (Real)0, (Real)0 });
- A.SetRow(1, { (Real)0, (Real)-1, (Real)0 });
- A.SetRow(2, { (Real)0, (Real)0, (Real)-1 });
- A.SetRow(3, direction);
- A.SetRow(4, -direction);
- Vector<5, Real> B =
- {
- -corner[0],
- -corner[1],
- -corner[2],
- originDotDirection - halfHeight,
- -originDotDirection - halfHeight
- };
- std::array<std::array<Real, 8>, 8> M;
- for (int r = 0; r < 3; ++r)
- {
- for (int c = 0; c < 3; ++c)
- {
- M[r][c] = P(r, c);
- }
- for (int c = 3, i = 0; c < 8; ++c, ++i)
- {
- M[r][c] = -A(i, r);
- }
- }
- for (int r = 3, i = 0; r < 8; ++r, ++i)
- {
- for (int c = 0; c < 3; ++c)
- {
- M[r][c] = A(i, c);
- }
- for (int c = 3; c < 8; ++c)
- {
- M[r][c] = (Real)0;
- }
- }
- std::array<Real, 8> q;
- for (int r = 0; r < 3; ++r)
- {
- q[r] = C[r];
- }
- for (int r = 3, i = 0; r < 8; ++r, ++i)
- {
- q[r] = -B[i];
- }
- std::array<Real, 8> w, z;
- if (mLCP.Solve(q, M, w, z, &result.outcome))
- {
- Vector3<Real> zSolution{ z[0], z[1], z[2] };
- Vector3<Real> diff = zSolution - origin;
- Real qform = Dot(diff, P * diff);
- result.intersect = (qform <= cylinder.radius * cylinder.radius);
- }
- else
- {
-
-
-
-
-
- result.intersect = false;
- }
- result.numLCPIterations = mLCP.GetNumIterations();
- return result;
- }
- private:
- LCPSolver<Real, 8> mLCP;
- };
- }
|