]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/DPlane.cpp
uncrustify! now the code is only ugly on the *inside*
[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 #include "DPlane.h"
26 #include "DWinding.h"
27 #include "misc.h"
28
29 //////////////////////////////////////////////////////////////////////
30 // Construction/Destruction
31 //////////////////////////////////////////////////////////////////////
32
33 DPlane::DPlane( vec3_t va, vec3_t vb, vec3_t vc, _QERFaceData* texData ){
34         MakeNormal( va, vb, vc, normal );
35         if ( VectorNormalize( normal, normal ) == 0 ) {  // normalizes and returns length
36                 Sys_ERROR( "DPlane::DPlane: Bad Normal.\n" );
37         }
38
39         _d = ( normal[0] * va[0] ) + ( normal[1] * va[1] ) + ( normal[2] * va[2] );
40
41         VectorCopy( va, points[0] );
42         VectorCopy( vb, points[1] );
43         VectorCopy( vc, points[2] );
44
45         m_bChkOk = TRUE;
46
47         if ( texData ) {
48                 memcpy( &texInfo, texData, sizeof( _QERFaceData ) );
49         }
50         else{
51                 FillDefaultTexture( &texInfo, points[0], points[1], points[2], "textures/common/caulk" );
52         }
53 }
54
55 DPlane::~DPlane(){
56
57 }
58
59 //////////////////////////////////////////////////////////////////////
60 // Implementation
61 //////////////////////////////////////////////////////////////////////
62
63 vec_t DPlane::DistanceToPoint( vec3_t pnt ){
64         vec3_t tmp;
65         VectorSubtract( pnt, points[0], tmp );
66         return DotProduct( tmp, normal );
67 }
68
69 bool DPlane::PlaneIntersection( DPlane *pl1, DPlane *pl2, vec3_t out ){
70         float a1, a2, a3;
71         float b1, b2, b3;
72         float c1, c2, c3;
73
74         a1 = normal[0];         a2 = normal[1];         a3 = normal[2];
75         b1 = pl1->normal[0];    b2 = pl1->normal[1];    b3 = pl1->normal[2];
76         c1 = pl2->normal[0];    c2 = pl2->normal[1];    c3 = pl2->normal[2];
77
78         float d = Determinant3x3( a1, a2, a3, b1, b2, b3, c1, c2, c3 );
79
80         if ( d == 0 ) {
81                 return FALSE;
82         }
83
84         float v1 = _d;
85         float v2 = pl1->_d;
86         float v3 = pl2->_d;
87
88         float d1 = Determinant3x3( v1, a2, a3, v2, b2, b3, v3, c2, c3 );
89         float d2 = Determinant3x3( a1, v1, a3, b1, v2, b3, c1, v3, c3 );
90         float d3 = Determinant3x3( a1, a2, v1, b1, b2, v2, c1, c2, v3 );
91
92         out[0] = d1 / d;
93         out[1] = d2 / d;
94         out[2] = d3 / d;
95
96         return TRUE;
97 }
98
99 bool DPlane::IsRedundant( list<DPoint*>& pointList ){
100         int cnt = 0;
101
102         //list<DPoint *>::const_iterator point=pointList.begin();
103         for ( list<DPoint *>::const_iterator point = pointList.begin(); point != pointList.end(); point++ )
104         {
105                 if ( fabs( DistanceToPoint( ( *point )->_pnt ) ) < MAX_ROUND_ERROR ) {
106                         cnt++;
107                 }
108
109                 if ( cnt == 3 ) {
110                         return FALSE;
111                 }
112         }
113         return TRUE;
114 }
115
116 bool DPlane::operator ==( DPlane& other ){
117         vec3_t chk;
118         VectorSubtract( other.normal, normal, chk );
119         if ( fabs( VectorLength( chk ) ) > MAX_ROUND_ERROR ) {
120                 return FALSE;
121         }
122
123         if ( fabs( other._d - _d ) > MAX_ROUND_ERROR ) {
124                 return FALSE;
125         }
126
127         return TRUE;
128 }
129
130 bool DPlane::operator !=( DPlane& other ){
131         vec3_t chk;
132         VectorAdd( other.normal, normal, chk );
133         if ( fabs( VectorLength( chk ) ) > MAX_ROUND_ERROR ) {
134                 return FALSE;
135         }
136
137         return TRUE;
138 }
139
140 DWinding* DPlane::BaseWindingForPlane(){
141         int i, x;
142         vec_t max, v;
143         vec3_t org, vright, vup;
144
145 // find the major axis
146
147         max = -131072;
148         x = -1;
149         for ( i = 0 ; i < 3; i++ )
150         {
151                 v = (float)fabs( normal[i] );
152                 if ( v > max ) {
153                         x = i;
154                         max = v;
155                 }
156         }
157         if ( x == -1 ) {
158                 Sys_Printf( "BaseWindingForPlane: no axis found" );
159         }
160
161         VectorCopy( vec3_origin, vup );
162         switch ( x )
163         {
164         case 0:
165         case 1:
166                 vup[2] = 1;
167                 break;
168         case 2:
169                 vup[0] = 1;
170                 break;
171         }
172
173         v = DotProduct( vup, normal );
174         VectorMA( vup, -v, normal, vup );
175         VectorNormalize( vup, vup );
176
177         VectorScale( normal, _d, org );
178
179         CrossProduct( vup, normal, vright );
180
181         VectorScale( vup, 131072, vup );
182         VectorScale( vright, 131072, vright );
183
184 // project a really big axis aligned box onto the plane
185         DWinding* w = new DWinding;
186         w->AllocWinding( 4 );
187
188         VectorSubtract( org, vright, w->p[0] );
189         VectorAdd( w->p[0], vup, w->p[0] );
190
191         VectorAdd( org, vright, w->p[1] );
192         VectorAdd( w->p[1], vup, w->p[1] );
193
194         VectorAdd( org, vright, w->p[2] );
195         VectorSubtract( w->p[2], vup, w->p[2] );
196
197         VectorSubtract( org, vright, w->p[3] );
198         VectorSubtract( w->p[3], vup, w->p[3] );
199
200         return w;
201 }
202
203 void DPlane::Rebuild(){
204         vec3_t v1, v2;
205         VectorSubtract( points[0], points[1], v1 );
206         VectorSubtract( points[2], points[1], v2 );
207         CrossProduct( v1, v2, normal );
208
209         if ( VectorNormalize( normal, normal ) == 0 ) {  // normalizes and returns length
210                 Sys_ERROR( "DPlane::Rebuild: Bad Normal.\n" );
211         }
212
213         _d = ( normal[0] * points[0][0] ) + ( normal[1] * points[0][1] ) + ( normal[2] * points[0][2] );
214
215         VectorCopy( points[0], texInfo.m_v1 );
216         VectorCopy( points[1], texInfo.m_v2 );
217         VectorCopy( points[2], texInfo.m_v3 );
218 }
219
220 bool DPlane::AddToBrush_t( brush_t *brush ){
221         if ( m_bChkOk || !strcmp( texInfo.m_TextureName, "textures/common/caulk" ) ) {
222                 g_FuncTable.m_pfnAddFaceData( brush, &texInfo );
223                 return FALSE;
224         }
225
226         strcpy( texInfo.m_TextureName, "textures/common/caulk" );
227         g_FuncTable.m_pfnAddFaceData( brush, &texInfo );
228         return TRUE;
229 }
230
231 void DPlane::ScaleTexture()
232 { }
233
234 DPlane::DPlane( vec3_t va, vec3_t vb, vec3_t vc, const char* textureName, bool bDetail ){
235         vec3_t v1, v2;
236         VectorSubtract( va, vb, v1 );
237         VectorSubtract( vc, vb, v2 );
238         CrossProduct( v1, v2, normal );
239
240         if ( VectorNormalize( normal, normal ) == 0 ) {  // normalizes and returns length
241                 Sys_ERROR( "DPlane::DPlane: Bad Normal.\n" );
242         }
243
244         _d = ( normal[0] * va[0] ) + ( normal[1] * va[1] ) + ( normal[2] * va[2] );
245
246         VectorCopy( va, points[0] );
247         VectorCopy( vb, points[1] );
248         VectorCopy( vc, points[2] );
249
250         m_bChkOk = TRUE;
251
252         FillDefaultTexture( &texInfo, points[0], points[1], points[2], textureName );
253         if ( bDetail ) {
254                 texInfo.m_nContents |= FACE_DETAIL;
255         }
256 }