2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
5 This file is part of Lugaru.
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
21 #include "Math/XYZ.hpp"
23 bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3)
25 static float u0, u1, u2;
26 static float v0, v1, v2;
30 static bool bInter = 0;
31 static float pointv[3];
35 static float normalv[3];
56 normalv[0] = normal.x;
57 normalv[1] = normal.y;
58 normalv[2] = normal.z;
60 #define ABS(X) (((X)<0.f)?-(X):(X) )
61 #define MAX(A, B) (((A)<(B))?(B):(A))
62 max = MAX(MAX(ABS(normalv[0]), ABS(normalv[1])), ABS(normalv[2]));
64 if (max == ABS(normalv[0])) {
68 if (max == ABS(normalv[1])) {
72 if (max == ABS(normalv[2])) {
78 u0 = pointv[i] - p1v[i];
79 v0 = pointv[j] - p1v[j];
85 if (u1 > -1.0e-05f && u1 < 1.0e-05f) { // == 0.0f)
87 if (0.0f <= b && b <= 1.0f) {
88 a = (v0 - b * v2) / v1;
89 if ((a >= 0.0f) && (( a + b ) <= 1.0f))
93 b = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
94 if (0.0f <= b && b <= 1.0f) {
95 a = (u0 - b * u2) / u1;
96 if ((a >= 0.0f) && (( a + b ) <= 1.0f ))
104 bool LineFacet(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ *p)
107 static float denom, mu;
110 //Calculate the parameters for the plane
111 n.x = (pb.y - pa.y) * (pc.z - pa.z) - (pb.z - pa.z) * (pc.y - pa.y);
112 n.y = (pb.z - pa.z) * (pc.x - pa.x) - (pb.x - pa.x) * (pc.z - pa.z);
113 n.z = (pb.x - pa.x) * (pc.y - pa.y) - (pb.y - pa.y) * (pc.x - pa.x);
115 d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
117 //Calculate the position on the line that intersects the plane
118 denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
119 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
121 mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
122 p->x = p1.x + mu * (p2.x - p1.x);
123 p->y = p1.y + mu * (p2.y - p1.y);
124 p->z = p1.z + mu * (p2.z - p1.z);
125 if (mu < 0 || mu > 1) // Intersection not along line segment
128 if (!PointInTriangle( p, n, &pa, &pb, &pc)) {
135 float LineFacetd(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ *p)
138 static float denom, mu;
141 //Calculate the parameters for the plane
142 n.x = (pb.y - pa.y) * (pc.z - pa.z) - (pb.z - pa.z) * (pc.y - pa.y);
143 n.y = (pb.z - pa.z) * (pc.x - pa.x) - (pb.x - pa.x) * (pc.z - pa.z);
144 n.z = (pb.x - pa.x) * (pc.y - pa.y) - (pb.y - pa.y) * (pc.x - pa.x);
146 d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
148 //Calculate the position on the line that intersects the plane
149 denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
150 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
152 mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
153 p->x = p1.x + mu * (p2.x - p1.x);
154 p->y = p1.y + mu * (p2.y - p1.y);
155 p->z = p1.z + mu * (p2.z - p1.z);
156 if (mu < 0 || mu > 1) // Intersection not along line segment
159 if (!PointInTriangle( p, n, &pa, &pb, &pc)) {
166 float LineFacetd(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ n, XYZ *p)
169 static float denom, mu;
171 //Calculate the parameters for the plane
172 d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
174 //Calculate the position on the line that intersects the plane
175 denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
176 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
178 mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
179 p->x = p1.x + mu * (p2.x - p1.x);
180 p->y = p1.y + mu * (p2.y - p1.y);
181 p->z = p1.z + mu * (p2.z - p1.z);
182 if (mu < 0 || mu > 1) // Intersection not along line segment
185 if (!PointInTriangle( p, n, &pa, &pb, &pc)) {
191 float LineFacetd(XYZ *p1, XYZ *p2, XYZ *pa, XYZ *pb, XYZ *pc, XYZ *p)
194 static float denom, mu;
197 //Calculate the parameters for the plane
198 n.x = (pb->y - pa->y) * (pc->z - pa->z) - (pb->z - pa->z) * (pc->y - pa->y);
199 n.y = (pb->z - pa->z) * (pc->x - pa->x) - (pb->x - pa->x) * (pc->z - pa->z);
200 n.z = (pb->x - pa->x) * (pc->y - pa->y) - (pb->y - pa->y) * (pc->x - pa->x);
202 d = - n.x * pa->x - n.y * pa->y - n.z * pa->z;
205 //Calculate the position on the line that intersects the plane
206 denom = n.x * (p2->x - p1->x) + n.y * (p2->y - p1->y) + n.z * (p2->z - p1->z);
207 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
209 mu = - (d + n.x * p1->x + n.y * p1->y + n.z * p1->z) / denom;
210 p->x = p1->x + mu * (p2->x - p1->x);
211 p->y = p1->y + mu * (p2->y - p1->y);
212 p->z = p1->z + mu * (p2->z - p1->z);
213 if (mu < 0 || mu > 1) // Intersection not along line segment
216 if (!PointInTriangle( p, n, pa, pb, pc)) {
222 float LineFacetd(XYZ *p1, XYZ *p2, XYZ *pa, XYZ *pb, XYZ *pc, XYZ *n, XYZ *p)
225 static float denom, mu;
227 //Calculate the parameters for the plane
228 d = - n->x * pa->x - n->y * pa->y - n->z * pa->z;
230 //Calculate the position on the line that intersects the plane
231 denom = n->x * (p2->x - p1->x) + n->y * (p2->y - p1->y) + n->z * (p2->z - p1->z);
232 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
234 mu = - (d + n->x * p1->x + n->y * p1->y + n->z * p1->z) / denom;
235 p->x = p1->x + mu * (p2->x - p1->x);
236 p->y = p1->y + mu * (p2->y - p1->y);
237 p->z = p1->z + mu * (p2->z - p1->z);
238 if (mu < 0 || mu > 1) // Intersection not along line segment
241 if (!PointInTriangle( p, *n, pa, pb, pc)) {