X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;ds=sidebyside;f=Source%2FMath%2FXYZ.cpp;fp=Source%2FMath%2FXYZ.cpp;h=ad145ae99f6a19c60b5ba485cbed09159483ca9e;hb=03fbcc5b5e18dbf62c48849fc8d02cd250aa744e;hp=0000000000000000000000000000000000000000;hpb=542e48a5f43e0169f98fca72bdd13aa66517f203;p=lugaru.git diff --git a/Source/Math/XYZ.cpp b/Source/Math/XYZ.cpp new file mode 100644 index 0000000..ad145ae --- /dev/null +++ b/Source/Math/XYZ.cpp @@ -0,0 +1,247 @@ +/* +Copyright (C) 2003, 2010 - Wolfire Games +Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) + +This file is part of Lugaru. + +Lugaru is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Lugaru is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Lugaru. If not, see . +*/ + +#include "Math/XYZ.hpp" + +bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3) +{ + static float u0, u1, u2; + static float v0, v1, v2; + static float a, b; + static float max; + static int i, j; + static bool bInter = 0; + static float pointv[3]; + static float p1v[3]; + static float p2v[3]; + static float p3v[3]; + static float normalv[3]; + + bInter = 0; + + pointv[0] = p->x; + pointv[1] = p->y; + pointv[2] = p->z; + + + p1v[0] = p1->x; + p1v[1] = p1->y; + p1v[2] = p1->z; + + p2v[0] = p2->x; + p2v[1] = p2->y; + p2v[2] = p2->z; + + p3v[0] = p3->x; + p3v[1] = p3->y; + p3v[2] = p3->z; + + normalv[0] = normal.x; + normalv[1] = normal.y; + normalv[2] = normal.z; + +#define ABS(X) (((X)<0.f)?-(X):(X) ) +#define MAX(A, B) (((A)<(B))?(B):(A)) + max = MAX(MAX(ABS(normalv[0]), ABS(normalv[1])), ABS(normalv[2])); +#undef MAX + if (max == ABS(normalv[0])) { + i = 1; // y, z + j = 2; + } + if (max == ABS(normalv[1])) { + i = 0; // x, z + j = 2; + } + if (max == ABS(normalv[2])) { + i = 0; // x, y + j = 1; + } +#undef ABS + + u0 = pointv[i] - p1v[i]; + v0 = pointv[j] - p1v[j]; + u1 = p2v[i] - p1v[i]; + v1 = p2v[j] - p1v[j]; + u2 = p3v[i] - p1v[i]; + v2 = p3v[j] - p1v[j]; + + if (u1 > -1.0e-05f && u1 < 1.0e-05f) { // == 0.0f) + b = u0 / u2; + if (0.0f <= b && b <= 1.0f) { + a = (v0 - b * v2) / v1; + if ((a >= 0.0f) && (( a + b ) <= 1.0f)) + bInter = 1; + } + } else { + b = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1); + if (0.0f <= b && b <= 1.0f) { + a = (u0 - b * u2) / u1; + if ((a >= 0.0f) && (( a + b ) <= 1.0f )) + bInter = 1; + } + } + + return bInter; +} + +bool LineFacet(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ *p) +{ + static float d; + static float denom, mu; + static XYZ n; + + //Calculate the parameters for the plane + n.x = (pb.y - pa.y) * (pc.z - pa.z) - (pb.z - pa.z) * (pc.y - pa.y); + n.y = (pb.z - pa.z) * (pc.x - pa.x) - (pb.x - pa.x) * (pc.z - pa.z); + n.z = (pb.x - pa.x) * (pc.y - pa.y) - (pb.y - pa.y) * (pc.x - pa.x); + Normalise(&n); + d = - n.x * pa.x - n.y * pa.y - n.z * pa.z; + + //Calculate the position on the line that intersects the plane + denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z); + if (fabs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom; + p->x = p1.x + mu * (p2.x - p1.x); + p->y = p1.y + mu * (p2.y - p1.y); + p->z = p1.z + mu * (p2.z - p1.z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if (!PointInTriangle( p, n, &pa, &pb, &pc)) { + return 0; + } + + return 1; +} + +float LineFacetd(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ *p) +{ + static float d; + static float denom, mu; + static XYZ n; + + //Calculate the parameters for the plane + n.x = (pb.y - pa.y) * (pc.z - pa.z) - (pb.z - pa.z) * (pc.y - pa.y); + n.y = (pb.z - pa.z) * (pc.x - pa.x) - (pb.x - pa.x) * (pc.z - pa.z); + n.z = (pb.x - pa.x) * (pc.y - pa.y) - (pb.y - pa.y) * (pc.x - pa.x); + Normalise(&n); + d = - n.x * pa.x - n.y * pa.y - n.z * pa.z; + + //Calculate the position on the line that intersects the plane + denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z); + if (fabs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom; + p->x = p1.x + mu * (p2.x - p1.x); + p->y = p1.y + mu * (p2.y - p1.y); + p->z = p1.z + mu * (p2.z - p1.z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if (!PointInTriangle( p, n, &pa, &pb, &pc)) { + return 0; + } + + return 1; +} + +float LineFacetd(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ n, XYZ *p) +{ + static float d; + static float denom, mu; + + //Calculate the parameters for the plane + d = - n.x * pa.x - n.y * pa.y - n.z * pa.z; + + //Calculate the position on the line that intersects the plane + denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z); + if (fabs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom; + p->x = p1.x + mu * (p2.x - p1.x); + p->y = p1.y + mu * (p2.y - p1.y); + p->z = p1.z + mu * (p2.z - p1.z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if (!PointInTriangle( p, n, &pa, &pb, &pc)) { + return 0; + } + return 1; +} + +float LineFacetd(XYZ *p1, XYZ *p2, XYZ *pa, XYZ *pb, XYZ *pc, XYZ *p) +{ + static float d; + static float denom, mu; + static XYZ n; + + //Calculate the parameters for the plane + n.x = (pb->y - pa->y) * (pc->z - pa->z) - (pb->z - pa->z) * (pc->y - pa->y); + n.y = (pb->z - pa->z) * (pc->x - pa->x) - (pb->x - pa->x) * (pc->z - pa->z); + n.z = (pb->x - pa->x) * (pc->y - pa->y) - (pb->y - pa->y) * (pc->x - pa->x); + Normalise(&n); + d = - n.x * pa->x - n.y * pa->y - n.z * pa->z; + + + //Calculate the position on the line that intersects the plane + denom = n.x * (p2->x - p1->x) + n.y * (p2->y - p1->y) + n.z * (p2->z - p1->z); + if (fabs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n.x * p1->x + n.y * p1->y + n.z * p1->z) / denom; + p->x = p1->x + mu * (p2->x - p1->x); + p->y = p1->y + mu * (p2->y - p1->y); + p->z = p1->z + mu * (p2->z - p1->z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if (!PointInTriangle( p, n, pa, pb, pc)) { + return 0; + } + return 1; +} + +float LineFacetd(XYZ *p1, XYZ *p2, XYZ *pa, XYZ *pb, XYZ *pc, XYZ *n, XYZ *p) +{ + static float d; + static float denom, mu; + + //Calculate the parameters for the plane + d = - n->x * pa->x - n->y * pa->y - n->z * pa->z; + + //Calculate the position on the line that intersects the plane + denom = n->x * (p2->x - p1->x) + n->y * (p2->y - p1->y) + n->z * (p2->z - p1->z); + if (fabs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n->x * p1->x + n->y * p1->y + n->z * p1->z) / denom; + p->x = p1->x + mu * (p2->x - p1->x); + p->y = p1->y + mu * (p2->y - p1->y); + p->z = p1->z + mu * (p2->z - p1->z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if (!PointInTriangle( p, *n, pa, pb, pc)) { + return 0; + } + return 1; +} + +