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