]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/DPlane.cpp
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / contrib / bobtoolz / DPlane.cpp
1 /*\r
2 BobToolz plugin for GtkRadiant\r
3 Copyright (C) 2001 Gordon Biggans\r
4 \r
5 This library is free software; you can redistribute it and/or\r
6 modify it under the terms of the GNU Lesser General Public\r
7 License as published by the Free Software Foundation; either\r
8 version 2.1 of the License, or (at your option) any later version.\r
9 \r
10 This library is distributed in the hope that it will be useful,\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
13 Lesser General Public License for more details.\r
14 \r
15 You should have received a copy of the GNU Lesser General Public\r
16 License along with this library; if not, write to the Free Software\r
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
18 */\r
19 \r
20 // DPlane.cpp: implementation of the DPlane class.\r
21 //\r
22 //////////////////////////////////////////////////////////////////////\r
23 \r
24 #include "StdAfx.h"\r
25 #include "DPlane.h"\r
26 #include "DWinding.h"\r
27 #include "misc.h"\r
28 \r
29 //////////////////////////////////////////////////////////////////////\r
30 // Construction/Destruction\r
31 //////////////////////////////////////////////////////////////////////\r
32 \r
33 DPlane::DPlane(vec3_t va, vec3_t vb, vec3_t vc, _QERFaceData* texData)\r
34 {\r
35         MakeNormal( va, vb, vc, normal );\r
36         if(VectorNormalize(normal, normal) == 0)        // normalizes and returns length\r
37                 Sys_ERROR("DPlane::DPlane: Bad Normal.\n");\r
38 \r
39         _d = (normal[0]*va[0]) + (normal[1]*va[1]) + (normal[2]*va[2]);\r
40 \r
41         VectorCopy(va, points[0]);\r
42         VectorCopy(vb, points[1]);\r
43         VectorCopy(vc, points[2]);\r
44 \r
45         m_bChkOk = TRUE;\r
46 \r
47         if(texData)\r
48                 memcpy(&texInfo, texData, sizeof(_QERFaceData));\r
49         else\r
50                 FillDefaultTexture(&texInfo, points[0], points[1], points[2], "textures/common/caulk");\r
51 }\r
52 \r
53 DPlane::~DPlane()\r
54 {\r
55 \r
56 }\r
57 \r
58 //////////////////////////////////////////////////////////////////////\r
59 // Implementation\r
60 //////////////////////////////////////////////////////////////////////\r
61 \r
62 vec_t DPlane::DistanceToPoint(vec3_t pnt)\r
63 {\r
64         vec3_t tmp;\r
65         VectorSubtract(pnt, points[0], tmp);\r
66         return DotProduct(tmp, normal);\r
67 }\r
68 \r
69 bool DPlane::PlaneIntersection(DPlane *pl1, DPlane *pl2, vec3_t out)\r
70 {\r
71         float a1, a2, a3;\r
72         float b1, b2, b3;\r
73         float c1, c2, c3;\r
74         \r
75         a1 = normal[0];                 a2 = normal[1];                 a3 = normal[2];\r
76         b1 = pl1->normal[0];    b2 = pl1->normal[1];    b3 = pl1->normal[2];\r
77         c1 = pl2->normal[0];    c2 = pl2->normal[1];    c3 = pl2->normal[2];\r
78 \r
79         float d = Determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);\r
80 \r
81         if(d == 0)\r
82                 return FALSE;\r
83         \r
84         float v1 = _d;\r
85         float v2 = pl1->_d;\r
86         float v3 = pl2->_d;\r
87 \r
88         float d1 = Determinant3x3(v1, a2, a3, v2, b2, b3, v3, c2, c3);\r
89         float d2 = Determinant3x3(a1, v1, a3, b1, v2, b3, c1, v3, c3);\r
90         float d3 = Determinant3x3(a1, a2, v1, b1, b2, v2, c1, c2, v3);\r
91 \r
92         out[0] = d1/d;  \r
93         out[1] = d2/d;  \r
94         out[2] = d3/d;  \r
95 \r
96         return TRUE;\r
97 }\r
98 \r
99 bool DPlane::IsRedundant(list<DPoint*>& pointList)\r
100 {\r
101         int cnt = 0;\r
102 \r
103         //list<DPoint *>::const_iterator point=pointList.begin();\r
104         for(list<DPoint *>::const_iterator point=pointList.begin(); point!=pointList.end(); point++)\r
105         {\r
106                  if(fabs(DistanceToPoint((*point)->_pnt)) < MAX_ROUND_ERROR)\r
107                          cnt++;\r
108 \r
109                  if(cnt == 3)\r
110                          return FALSE;\r
111         }\r
112         return TRUE;\r
113 }\r
114 \r
115 bool DPlane::operator == (DPlane& other)\r
116 {\r
117         vec3_t chk;\r
118         VectorSubtract(other.normal, normal, chk);\r
119         if(fabs(VectorLength(chk)) > MAX_ROUND_ERROR)\r
120                 return FALSE;\r
121 \r
122         if(fabs(other._d - _d) > MAX_ROUND_ERROR)\r
123                 return FALSE;\r
124 \r
125         return TRUE;\r
126 }\r
127 \r
128 bool DPlane::operator != (DPlane& other)\r
129 {\r
130         vec3_t chk;\r
131         VectorAdd(other.normal, normal, chk);\r
132         if(fabs(VectorLength(chk)) > MAX_ROUND_ERROR)\r
133                 return FALSE;\r
134 \r
135         return TRUE;\r
136 }\r
137 \r
138 DWinding* DPlane::BaseWindingForPlane()\r
139 {\r
140         int             i, x;\r
141         vec_t   max, v;\r
142         vec3_t  org, vright, vup;\r
143         \r
144 // find the major axis\r
145 \r
146         max = -131072;\r
147         x = -1;\r
148         for (i=0 ; i<3; i++)\r
149         {\r
150                 v = (float)fabs(normal[i]);\r
151                 if (v > max)\r
152                 {\r
153                         x = i;\r
154                         max = v;\r
155                 }\r
156         }\r
157         if (x==-1)\r
158                 Sys_Printf ("BaseWindingForPlane: no axis found");\r
159                 \r
160         VectorCopy (vec3_origin, vup);  \r
161         switch (x)\r
162         {\r
163         case 0:\r
164         case 1:\r
165                 vup[2] = 1;\r
166                 break;          \r
167         case 2:\r
168                 vup[0] = 1;\r
169                 break;          \r
170         }\r
171 \r
172         v = DotProduct (vup, normal);\r
173         VectorMA (vup, -v, normal, vup);\r
174         VectorNormalize (vup, vup);\r
175                 \r
176         VectorScale (normal, _d, org);\r
177         \r
178         CrossProduct (vup, normal, vright);\r
179         \r
180         VectorScale (vup, 131072, vup);\r
181         VectorScale (vright, 131072, vright);\r
182 \r
183 // project a really big axis aligned box onto the plane\r
184         DWinding* w = new DWinding;\r
185         w->AllocWinding(4);\r
186         \r
187         VectorSubtract (org, vright, w->p[0]);\r
188         VectorAdd (w->p[0], vup, w->p[0]);\r
189         \r
190         VectorAdd (org, vright, w->p[1]);\r
191         VectorAdd (w->p[1], vup, w->p[1]);\r
192         \r
193         VectorAdd (org, vright, w->p[2]);\r
194         VectorSubtract (w->p[2], vup, w->p[2]);\r
195         \r
196         VectorSubtract (org, vright, w->p[3]);\r
197         VectorSubtract (w->p[3], vup, w->p[3]);\r
198                 \r
199         return w;       \r
200 }\r
201 \r
202 void DPlane::Rebuild()\r
203 {\r
204         vec3_t v1, v2;\r
205         VectorSubtract(points[0], points[1], v1);\r
206         VectorSubtract(points[2], points[1], v2);\r
207         CrossProduct(v1, v2, normal);\r
208 \r
209         if(VectorNormalize(normal, normal) == 0)        // normalizes and returns length\r
210                 Sys_ERROR("DPlane::Rebuild: Bad Normal.\n");\r
211 \r
212         _d = (normal[0]*points[0][0]) + (normal[1]*points[0][1]) + (normal[2]*points[0][2]);\r
213 \r
214         VectorCopy(points[0], texInfo.m_v1);\r
215         VectorCopy(points[1], texInfo.m_v2);\r
216         VectorCopy(points[2], texInfo.m_v3);\r
217 }\r
218 \r
219 bool DPlane::AddToBrush_t(brush_t *brush)\r
220 {\r
221         if(m_bChkOk || !strcmp(texInfo.m_TextureName, "textures/common/caulk"))\r
222         {\r
223                 g_FuncTable.m_pfnAddFaceData(brush, &texInfo);\r
224                 return FALSE;\r
225         }\r
226 \r
227         strcpy(texInfo.m_TextureName, "textures/common/caulk");\r
228         g_FuncTable.m_pfnAddFaceData(brush, &texInfo);\r
229         return TRUE;\r
230 }\r
231 \r
232 void DPlane::ScaleTexture()\r
233 { }\r
234 \r
235 DPlane::DPlane(vec3_t va, vec3_t vb, vec3_t vc, const char* textureName, bool bDetail)\r
236 {\r
237         vec3_t v1, v2;\r
238         VectorSubtract(va, vb, v1);\r
239         VectorSubtract(vc, vb, v2);\r
240         CrossProduct(v1, v2, normal);\r
241 \r
242         if(VectorNormalize(normal, normal) == 0)        // normalizes and returns length\r
243                 Sys_ERROR("DPlane::DPlane: Bad Normal.\n");\r
244 \r
245         _d = (normal[0]*va[0]) + (normal[1]*va[1]) + (normal[2]*va[2]);\r
246 \r
247         VectorCopy(va, points[0]);\r
248         VectorCopy(vb, points[1]);\r
249         VectorCopy(vc, points[2]);\r
250 \r
251         m_bChkOk = TRUE;\r
252 \r
253         FillDefaultTexture(&texInfo, points[0], points[1], points[2], textureName);\r
254         if(bDetail)\r
255                 texInfo.m_nContents |= FACE_DETAIL;\r
256 }\r