1 /*
2 Copyright (c) 2013-2021 Timur Gafarov
3 
4 Boost Software License - Version 1.0 - August 17th, 2003
5 
6 Permission is hereby granted, free of charge, to any person or organization
7 obtaining a copy of the software and accompanying documentation covered by
8 this license (the "Software") to use, reproduce, display, distribute,
9 execute, and transmit the Software, and to prepare derivative works of the
10 Software, and to permit third-parties to whom the Software is furnished to
11 do so, all subject to the following:
12 
13 The copyright notices in the Software and this entire statement, including
14 the above license grant, this restriction and the following disclaimer,
15 must be included in all copies of the Software, in whole or in part, and
16 all derivative works of the Software, unless such copies or derivative
17 works are solely in the form of machine-executable object code generated by
18 a source language processor.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
23 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
24 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 DEALINGS IN THE SOFTWARE.
27 */
28 
29 /**
30  * Copyright: Timur Gafarov 2013-2021.
31  * License: $(LINK2 boost.org/LICENSE_1_0.txt, Boost License 1.0).
32  * Authors: Timur Gafarov
33  */
34 module dlib.geometry.triangle;
35 
36 private
37 {
38     import std.math;
39     import dlib.math.vector;
40     import dlib.geometry.aabb;
41 }
42 
43 /// Triangle object
44 struct Triangle
45 {
46     public:
47     Vector3f[3] v;
48     Vector3f[3] n;
49     Vector2f[3] t1;
50     Vector2f[3] t2;
51     Vector4f[3] tg;
52 
53     Vector3f[3] edges;
54     Vector3f normal;
55     Vector3f barycenter;
56     float d;
57 
58     int materialIndex;
59 
60     int isPointInside(Vector3f point)
61     {
62         //select coordinate
63         int dim0, dim1, plane;
64         float clockness; // 1.0 counter clockwise, -1.0 clockwise
65 
66         if (abs(normal[1]) > abs(normal[2]))
67         {
68             if (abs(normal[1]) > abs(normal[0])) //use y plane
69             {
70                 plane = 1;
71                 dim0 = 2; //0;
72                 dim1 = 0; //2;
73             }
74             else //use x plane
75             {
76                 plane = 0;
77                 dim0 = 1;
78                 dim1 = 2;
79             }
80         }
81         else if (abs(normal[2]) > abs(normal[0])) //use z plane
82         {
83             plane = 2;
84             dim0 = 0;
85             dim1 = 1;
86         }
87         else //use x plane
88         {
89             plane = 0;
90             dim0 = 1;
91             dim1 = 2;
92         }
93 
94         clockness = (normal[plane] > 0.0f)? 1.0f : -1.0f;
95 
96         float det0, det1, det2;
97 
98         det0 = (point[dim0] - v[0][dim0]) * (v[0][dim1] - v[1][dim1]) +
99                (v[0][dim1] - point[dim1]) * (v[0][dim0] - v[1][dim0]);
100 
101         det1 = (point[dim0] - v[1][dim0]) * (v[1][dim1] - v[2][dim1]) +
102                (v[1][dim1] - point[dim1]) * (v[1][dim0] - v[2][dim0]);
103 
104         det2 = (point[dim0] - v[2][dim0]) * (v[2][dim1] - v[0][dim1]) +
105                (v[2][dim1] - point[dim1]) * (v[2][dim0] - v[0][dim0]);
106 
107         int ret;
108 
109         if (det0 > 0.0f)
110         {
111             if (det1 > 0.0f)
112             {
113                 if (det2 > 0.0f)
114                     ret = -1; // inside
115                 else
116                     ret = 5; // outside edge 2
117             }
118             else
119             {
120                 if (det2 > 0.0f)
121                     ret = 3; // outside edge 1
122                 else
123                     ret = 4; // outside vertex 2
124             }
125         }
126         else
127         {
128             if (det1 > 0.0f)
129             {
130                 if (det2 > 0.0f)
131                     ret = 1; // outside edge 0
132                 else
133                     ret = 0; // outside vertex 0
134             }
135             else
136             {
137                 if (det2 > 0.0f)
138                     ret = 2; // outside vertex 1
139                 else
140                     ret = -1; // inside
141             }
142         }
143 
144         if (ret == -1)
145             return ret;
146 
147         if (clockness == -1.0f)
148             ret = (ret + 3) % 6;
149 
150         return ret;
151     }
152 
153     AABB boundingBox()
154     {
155         Vector3f pmin = v[0];
156         Vector3f pmax = pmin;
157 
158         void adjustMinPoint(Vector3f p)
159         {
160             if (p.x < pmin.x) pmin.x = p.x;
161             if (p.y < pmin.y) pmin.y = p.y;
162             if (p.z < pmin.z) pmin.z = p.z;
163         }
164 
165         void adjustMaxPoint(Vector3f p)
166         {
167             if (p.x > pmax.x) pmax.x = p.x;
168             if (p.y > pmax.y) pmax.y = p.y;
169             if (p.z > pmax.z) pmax.z = p.z;
170         }
171 
172         foreach(vertex; v)
173         {
174             adjustMinPoint(vertex);
175             adjustMaxPoint(vertex);
176         }
177 
178         return boxFromMinMaxPoints(pmin - 0.5f, pmax + 0.5f);
179     }
180 }