]> git.jsancho.org Git - lugaru.git/blob - Source/Math/XYZ.cpp
ad145ae99f6a19c60b5ba485cbed09159483ca9e
[lugaru.git] / Source / Math / XYZ.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
4
5 This file is part of Lugaru.
6
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.
11
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.
16
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/>.
19 */
20
21 #include "Math/XYZ.hpp"
22
23 bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3)
24 {
25     static float u0, u1, u2;
26     static float v0, v1, v2;
27     static float a, b;
28     static float max;
29     static int i, j;
30     static bool bInter = 0;
31     static float pointv[3];
32     static float p1v[3];
33     static float p2v[3];
34     static float p3v[3];
35     static float normalv[3];
36
37     bInter = 0;
38
39     pointv[0] = p->x;
40     pointv[1] = p->y;
41     pointv[2] = p->z;
42
43
44     p1v[0] = p1->x;
45     p1v[1] = p1->y;
46     p1v[2] = p1->z;
47
48     p2v[0] = p2->x;
49     p2v[1] = p2->y;
50     p2v[2] = p2->z;
51
52     p3v[0] = p3->x;
53     p3v[1] = p3->y;
54     p3v[2] = p3->z;
55
56     normalv[0] = normal.x;
57     normalv[1] = normal.y;
58     normalv[2] = normal.z;
59
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]));
63 #undef MAX
64     if (max == ABS(normalv[0])) {
65         i = 1;    // y, z
66         j = 2;
67     }
68     if (max == ABS(normalv[1])) {
69         i = 0;    // x, z
70         j = 2;
71     }
72     if (max == ABS(normalv[2])) {
73         i = 0;    // x, y
74         j = 1;
75     }
76 #undef ABS
77
78     u0 = pointv[i] - p1v[i];
79     v0 = pointv[j] - p1v[j];
80     u1 = p2v[i] - p1v[i];
81     v1 = p2v[j] - p1v[j];
82     u2 = p3v[i] - p1v[i];
83     v2 = p3v[j] - p1v[j];
84
85     if (u1 > -1.0e-05f && u1 < 1.0e-05f) { // == 0.0f)
86         b = u0 / u2;
87         if (0.0f <= b && b <= 1.0f) {
88             a = (v0 - b * v2) / v1;
89             if ((a >= 0.0f) && (( a + b ) <= 1.0f))
90                 bInter = 1;
91         }
92     } else {
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 ))
97                 bInter = 1;
98         }
99     }
100
101     return bInter;
102 }
103
104 bool LineFacet(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ *p)
105 {
106     static float d;
107     static float denom, mu;
108     static XYZ n;
109
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);
114     Normalise(&n);
115     d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
116
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
120         return 0;
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
126         return 0;
127
128     if (!PointInTriangle( p, n, &pa, &pb, &pc)) {
129         return 0;
130     }
131
132     return 1;
133 }
134
135 float LineFacetd(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ *p)
136 {
137     static float d;
138     static float denom, mu;
139     static XYZ n;
140
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);
145     Normalise(&n);
146     d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
147
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
151         return 0;
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
157         return 0;
158
159     if (!PointInTriangle( p, n, &pa, &pb, &pc)) {
160         return 0;
161     }
162
163     return 1;
164 }
165
166 float LineFacetd(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ n, XYZ *p)
167 {
168     static float d;
169     static float denom, mu;
170
171     //Calculate the parameters for the plane
172     d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
173
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
177         return 0;
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
183         return 0;
184
185     if (!PointInTriangle( p, n, &pa, &pb, &pc)) {
186         return 0;
187     }
188     return 1;
189 }
190
191 float LineFacetd(XYZ *p1, XYZ *p2, XYZ *pa, XYZ *pb, XYZ *pc, XYZ *p)
192 {
193     static float d;
194     static float denom, mu;
195     static XYZ n;
196
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);
201     Normalise(&n);
202     d = - n.x * pa->x - n.y * pa->y - n.z * pa->z;
203
204
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
208         return 0;
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
214         return 0;
215
216     if (!PointInTriangle( p, n, pa, pb, pc)) {
217         return 0;
218     }
219     return 1;
220 }
221
222 float LineFacetd(XYZ *p1, XYZ *p2, XYZ *pa, XYZ *pb, XYZ *pc, XYZ *n, XYZ *p)
223 {
224     static float d;
225     static float denom, mu;
226
227     //Calculate the parameters for the plane
228     d = - n->x * pa->x - n->y * pa->y - n->z * pa->z;
229
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
233         return 0;
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
239         return 0;
240
241     if (!PointInTriangle( p, *n, pa, pb, pc)) {
242         return 0;
243     }
244     return 1;
245 }
246
247