]> git.mxchange.org Git - flightgear.git/blob - src/Objects/ssgEntityArray.cxx
ignore resets for now because every z/Z key press would trigger a call to NOAA. We...
[flightgear.git] / src / Objects / ssgEntityArray.cxx
1 /*
2      PLIB - A Suite of Portable Game Libraries
3      Copyright (C) 1998,2002  Steve Baker
4  
5      This library is free software; you can redistribute it and/or
6      modify it under the terms of the GNU Library General Public
7      License as published by the Free Software Foundation; either
8      version 2 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      Library General Public License for more details.
14  
15      You should have received a copy of the GNU Library 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      For further information visit http://plib.sourceforge.net
20
21      $Id$
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #include "ssgEntityArray.hxx"
29
30
31 // Forward declaration of internal ssg stuff (for hot/isec/los/etc.)
32 void _ssgPushPath ( ssgEntity *l ) ;
33 void _ssgPopPath () ;
34
35
36 void ssgEntityArray::copy_from ( ssgEntityArray *src, int clone_flags )
37 {
38   ssgEntity::copy_from ( src, clone_flags ) ;
39
40   ssgEntity *k = src -> getModel ( ) ;
41   if ( k != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
42       setModel ( (ssgEntity *)( k -> clone ( clone_flags )) ) ;
43   else
44       setModel ( k ) ;
45
46   ssgTransform *t = src -> getPosTransform();
47   if ( t != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
48       pos = (ssgTransform *)( t -> clone ( clone_flags ) );
49   else
50       pos = t;
51
52   ssgVertexArray *v = src -> getLocations();
53   if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
54       locations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
55   else
56       locations = v;
57
58   v = src -> getOrientations();
59   if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
60       orientations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
61   else
62       orientations = v;
63 }
64
65 ssgBase *ssgEntityArray::clone ( int clone_flags )
66 {
67   ssgEntityArray *b = new ssgEntityArray ;
68   b -> copy_from ( this, clone_flags ) ;
69   return b ;
70 }
71
72
73
74 ssgEntityArray::ssgEntityArray (void)
75 {
76     type = ssgTypeBranch () ;
77     pos = new ssgTransform;
78     locations = new ssgVertexArray();
79     orientations = new ssgVertexArray();
80 }
81
82
83 ssgEntityArray::~ssgEntityArray (void)
84 {
85     removeModel() ;
86     ssgDeRefDelete( pos );
87     locations->removeAll();
88     orientations->removeAll();
89
90     delete orientations;
91     delete locations;
92     delete pos;
93 }
94
95
96 void ssgEntityArray::zeroSpareRecursive ()
97 {
98   zeroSpare () ;
99
100   model -> zeroSpareRecursive () ;
101   pos -> zeroSpareRecursive () ;
102   locations -> zeroSpareRecursive () ;
103   orientations -> zeroSpareRecursive () ;
104 }
105
106
107 void ssgEntityArray::recalcBSphere (void)
108 {
109   emptyBSphere () ;
110
111   pos->removeAllKids();
112   pos->addKid( model );
113
114   for ( int i = 0; i < locations->getNum(); ++i ) {
115       sgCoord c;
116       sgSetCoord( &c, locations->get(i), orientations->get(i) );
117       pos->setTransform( &c );
118       extendBSphere( pos->getBSphere() );
119   }
120
121   pos->removeAllKids();
122
123   /* FIXME: Traverse placement list
124   for ( ssgEntity *k = getKid ( 0 ) ; k != NULL ; k = getNextKid () )
125     extendBSphere ( k -> getBSphere () ) ;
126   */
127
128   bsphere_is_invalid = FALSE ;
129 }
130
131
132 void ssgEntityArray::removeModel ()
133 {
134     model->deadBeefCheck () ;
135     ssgDeRefDelete ( model ) ;
136 }
137
138
139 void ssgEntityArray::replaceModel ( ssgEntity *new_entity )
140 {
141     removeModel();
142     setModel( new_entity );
143 }
144
145
146 void ssgEntityArray::addPlacement ( sgVec3 loc, sgVec3 orient )
147 {
148     locations->add( loc ) ;
149     orientations->add( orient ) ;
150     dirtyBSphere () ;
151 }
152
153
154 void ssgEntityArray::removeAllPlacements()
155 {
156     locations->removeAll();
157     orientations->removeAll();
158     dirtyBSphere () ;
159 }
160
161
162 void ssgEntityArray::print ( FILE *fd, char *indent, int how_much )
163 {
164   ssgEntity::print ( fd, indent, how_much ) ;
165   fprintf ( fd, "%s  Num Kids=%d\n", indent, getNumKids() ) ;
166
167   if ( getNumParents() != getRef() )
168     ulSetError ( UL_WARNING, "Ref count doesn't tally with parent count" ) ;
169
170         if ( how_much > 1 )
171   {     if ( bsphere.isEmpty() )
172                         fprintf ( fd, "%s  BSphere is Empty.\n", indent ) ;
173                 else
174                         fprintf ( fd, "%s  BSphere  R=%g, C=(%g,%g,%g)\n", indent,
175                                 bsphere.getRadius(), bsphere.getCenter()[0], bsphere.getCenter()[1], bsphere.getCenter()[2] ) ;
176         }
177
178   char in [ 100 ] ;
179   sprintf ( in, "%s  ", indent ) ;
180
181   model -> print ( fd, in, how_much ) ;
182 }
183
184
185 #ifdef HAVE_PLIB_PSL
186 void ssgEntityArray::getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_verts )
187 {
188   int nb, nl, nt, nv ;
189
190   *num_branches = 1 ;   /* this! */
191   *num_leaves   = 0 ;
192   *num_tris     = 0 ;
193   *num_verts    = 0 ;
194
195   model -> getStats ( & nb, & nl, & nt, & nv ) ;
196   *num_branches += nb * locations->getNum() ;
197   *num_leaves   += nl * locations->getNum() ;
198   *num_tris     += nt * locations->getNum() ;
199   *num_verts    += nv * locations->getNum() ;
200 }
201 #endif
202
203
204 void ssgEntityArray::cull ( sgFrustum *f, sgMat4 m, int test_needed )
205 {
206   if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) )
207     return ;
208
209   int cull_result = cull_test ( f, m, test_needed ) ;
210
211   if ( cull_result == SSG_OUTSIDE )
212     return ;
213
214   pos->removeAllKids();
215   pos->addKid( model );
216
217   for ( int i = 0; i < locations->getNum(); ++i ) {
218       sgCoord c;
219       sgSetCoord( &c, locations->get(i), orientations->get(i) );
220       pos->setTransform( &c );
221       pos->cull( f, m, cull_result != SSG_INSIDE );
222   }
223
224   pos->removeAllKids();
225
226   postTravTests ( SSGTRAV_CULL ) ; 
227 }
228
229
230
231 void ssgEntityArray::hot ( sgVec3 s, sgMat4 m, int test_needed )
232 {
233   if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) )
234     return ;
235
236   int hot_result = hot_test ( s, m, test_needed ) ;
237
238   if ( hot_result == SSG_OUTSIDE )
239     return ;
240
241   _ssgPushPath ( this ) ;
242
243   pos->removeAllKids();
244   pos->addKid( model );
245
246   for ( int i = 0; i < locations->getNum(); ++i ) {
247       sgCoord c;
248       sgSetCoord( &c, locations->get(i), orientations->get(i) );
249       pos->setTransform( &c );
250       pos->hot ( s, m, hot_result != SSG_INSIDE );
251   }
252
253   pos->removeAllKids();
254
255   _ssgPopPath () ;
256
257   postTravTests ( SSGTRAV_HOT ) ;
258 }
259
260
261
262 void ssgEntityArray::los ( sgVec3 s, sgMat4 m, int test_needed )
263 {
264   if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) )
265     return ;
266
267   int los_result = los_test ( s, m, test_needed ) ;
268
269   if ( los_result == SSG_OUTSIDE )
270     return ;
271
272   _ssgPushPath ( this ) ;
273
274   pos->removeAllKids();
275   pos->addKid( model );
276
277   for ( int i = 0; i < locations->getNum(); ++i ) {
278       sgCoord c;
279       sgSetCoord( &c, locations->get(i), orientations->get(i) );
280       pos->setTransform( &c );
281       pos->los ( s, m, los_result != SSG_INSIDE ) ;
282   }
283
284   pos->removeAllKids();
285
286   _ssgPopPath () ;
287
288   postTravTests ( SSGTRAV_LOS) ;
289 }
290
291
292 void ssgEntityArray::isect ( sgSphere *s, sgMat4 m, int test_needed )
293 {
294   if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) )
295     return ;
296
297   int isect_result = isect_test ( s, m, test_needed ) ;
298
299   if ( isect_result == SSG_OUTSIDE )
300     return ;
301
302   _ssgPushPath ( this ) ;
303
304   pos->removeAllKids();
305   pos->addKid( model );
306
307   for ( int i = 0; i < locations->getNum(); ++i ) {
308       sgCoord c;
309       sgSetCoord( &c, locations->get(i), orientations->get(i) );
310       pos->setTransform( &c );
311       pos->isect ( s, m, isect_result != SSG_INSIDE ) ;
312   }
313
314   pos->removeAllKids();
315
316   _ssgPopPath () ;
317
318   postTravTests ( SSGTRAV_ISECT ) ; 
319 }
320
321
322 #if 0
323 int ssgEntityArray::load ( FILE *fd )
324 {
325   int nkids ;
326
327   _ssgReadInt ( fd, & nkids ) ;
328
329   if ( ! ssgEntity::load ( fd ) )
330     return FALSE ;
331
332   for ( int i = 0 ; i < nkids ; i++ )
333   {
334     ssgEntity *kid ;
335
336     if ( ! _ssgLoadObject ( fd, (ssgBase **) &kid, ssgTypeEntity () ) )
337       return FALSE ;
338
339     addKid ( kid ) ;
340   }
341
342   return TRUE ;
343 }
344
345
346 int ssgEntityArray::save ( FILE *fd )
347 {
348   _ssgWriteInt ( fd, getNumKids() ) ;
349
350   if ( ! ssgEntity::save ( fd ) )
351     return FALSE ;
352
353   for ( int i = 0 ; i < getNumKids() ; i++ )
354   {
355     if ( ! _ssgSaveObject ( fd, getKid ( i ) ) )
356        return FALSE ;
357   }
358
359   return TRUE ;
360 }
361 #endif
362