Move Curt's ssgEntityArray experiment over to SimGear.
This commit is contained in:
parent
fe4f907099
commit
d5eedd2c65
362
simgear/screen/ssgEntityArray.cxx
Normal file
362
simgear/screen/ssgEntityArray.cxx
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
PLIB - A Suite of Portable Game Libraries
|
||||
Copyright (C) 1998,2002 Steve Baker
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "ssgEntityArray.hxx"
|
||||
|
||||
|
||||
// Forward declaration of internal ssg stuff (for hot/isec/los/etc.)
|
||||
void _ssgPushPath ( ssgEntity *l ) ;
|
||||
void _ssgPopPath () ;
|
||||
|
||||
|
||||
void ssgEntityArray::copy_from ( ssgEntityArray *src, int clone_flags )
|
||||
{
|
||||
ssgEntity::copy_from ( src, clone_flags ) ;
|
||||
|
||||
ssgEntity *k = src -> getModel ( ) ;
|
||||
if ( k != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
|
||||
setModel ( (ssgEntity *)( k -> clone ( clone_flags )) ) ;
|
||||
else
|
||||
setModel ( k ) ;
|
||||
|
||||
ssgTransform *t = src -> getPosTransform();
|
||||
if ( t != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
|
||||
pos = (ssgTransform *)( t -> clone ( clone_flags ) );
|
||||
else
|
||||
pos = t;
|
||||
|
||||
ssgVertexArray *v = src -> getLocations();
|
||||
if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
|
||||
locations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
|
||||
else
|
||||
locations = v;
|
||||
|
||||
v = src -> getOrientations();
|
||||
if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
|
||||
orientations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
|
||||
else
|
||||
orientations = v;
|
||||
}
|
||||
|
||||
ssgBase *ssgEntityArray::clone ( int clone_flags )
|
||||
{
|
||||
ssgEntityArray *b = new ssgEntityArray ;
|
||||
b -> copy_from ( this, clone_flags ) ;
|
||||
return b ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ssgEntityArray::ssgEntityArray (void)
|
||||
{
|
||||
type = ssgTypeBranch () ;
|
||||
pos = new ssgTransform;
|
||||
locations = new ssgVertexArray();
|
||||
orientations = new ssgVertexArray();
|
||||
}
|
||||
|
||||
|
||||
ssgEntityArray::~ssgEntityArray (void)
|
||||
{
|
||||
removeModel() ;
|
||||
ssgDeRefDelete( pos );
|
||||
locations->removeAll();
|
||||
orientations->removeAll();
|
||||
|
||||
delete orientations;
|
||||
delete locations;
|
||||
delete pos;
|
||||
}
|
||||
|
||||
|
||||
void ssgEntityArray::zeroSpareRecursive ()
|
||||
{
|
||||
zeroSpare () ;
|
||||
|
||||
model -> zeroSpareRecursive () ;
|
||||
pos -> zeroSpareRecursive () ;
|
||||
locations -> zeroSpareRecursive () ;
|
||||
orientations -> zeroSpareRecursive () ;
|
||||
}
|
||||
|
||||
|
||||
void ssgEntityArray::recalcBSphere (void)
|
||||
{
|
||||
emptyBSphere () ;
|
||||
|
||||
pos->removeAllKids();
|
||||
pos->addKid( model );
|
||||
|
||||
for ( int i = 0; i < locations->getNum(); ++i ) {
|
||||
sgCoord c;
|
||||
sgSetCoord( &c, locations->get(i), orientations->get(i) );
|
||||
pos->setTransform( &c );
|
||||
extendBSphere( pos->getBSphere() );
|
||||
}
|
||||
|
||||
pos->removeAllKids();
|
||||
|
||||
/* FIXME: Traverse placement list
|
||||
for ( ssgEntity *k = getKid ( 0 ) ; k != NULL ; k = getNextKid () )
|
||||
extendBSphere ( k -> getBSphere () ) ;
|
||||
*/
|
||||
|
||||
bsphere_is_invalid = FALSE ;
|
||||
}
|
||||
|
||||
|
||||
void ssgEntityArray::removeModel ()
|
||||
{
|
||||
model->deadBeefCheck () ;
|
||||
ssgDeRefDelete ( model ) ;
|
||||
}
|
||||
|
||||
|
||||
void ssgEntityArray::replaceModel ( ssgEntity *new_entity )
|
||||
{
|
||||
removeModel();
|
||||
setModel( new_entity );
|
||||
}
|
||||
|
||||
|
||||
void ssgEntityArray::addPlacement ( sgVec3 loc, sgVec3 orient )
|
||||
{
|
||||
locations->add( loc ) ;
|
||||
orientations->add( orient ) ;
|
||||
dirtyBSphere () ;
|
||||
}
|
||||
|
||||
|
||||
void ssgEntityArray::removeAllPlacements()
|
||||
{
|
||||
locations->removeAll();
|
||||
orientations->removeAll();
|
||||
dirtyBSphere () ;
|
||||
}
|
||||
|
||||
|
||||
void ssgEntityArray::print ( FILE *fd, char *indent, int how_much )
|
||||
{
|
||||
ssgEntity::print ( fd, indent, how_much ) ;
|
||||
fprintf ( fd, "%s Num Kids=%d\n", indent, getNumKids() ) ;
|
||||
|
||||
if ( getNumParents() != getRef() )
|
||||
ulSetError ( UL_WARNING, "Ref count doesn't tally with parent count" ) ;
|
||||
|
||||
if ( how_much > 1 )
|
||||
{ if ( bsphere.isEmpty() )
|
||||
fprintf ( fd, "%s BSphere is Empty.\n", indent ) ;
|
||||
else
|
||||
fprintf ( fd, "%s BSphere R=%g, C=(%g,%g,%g)\n", indent,
|
||||
bsphere.getRadius(), bsphere.getCenter()[0], bsphere.getCenter()[1], bsphere.getCenter()[2] ) ;
|
||||
}
|
||||
|
||||
char in [ 100 ] ;
|
||||
sprintf ( in, "%s ", indent ) ;
|
||||
|
||||
model -> print ( fd, in, how_much ) ;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_PLIB_PSL
|
||||
void ssgEntityArray::getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_verts )
|
||||
{
|
||||
int nb, nl, nt, nv ;
|
||||
|
||||
*num_branches = 1 ; /* this! */
|
||||
*num_leaves = 0 ;
|
||||
*num_tris = 0 ;
|
||||
*num_verts = 0 ;
|
||||
|
||||
model -> getStats ( & nb, & nl, & nt, & nv ) ;
|
||||
*num_branches += nb * locations->getNum() ;
|
||||
*num_leaves += nl * locations->getNum() ;
|
||||
*num_tris += nt * locations->getNum() ;
|
||||
*num_verts += nv * locations->getNum() ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void ssgEntityArray::cull ( sgFrustum *f, sgMat4 m, int test_needed )
|
||||
{
|
||||
if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) )
|
||||
return ;
|
||||
|
||||
int cull_result = cull_test ( f, m, test_needed ) ;
|
||||
|
||||
if ( cull_result == SSG_OUTSIDE )
|
||||
return ;
|
||||
|
||||
pos->removeAllKids();
|
||||
pos->addKid( model );
|
||||
|
||||
for ( int i = 0; i < locations->getNum(); ++i ) {
|
||||
sgCoord c;
|
||||
sgSetCoord( &c, locations->get(i), orientations->get(i) );
|
||||
pos->setTransform( &c );
|
||||
pos->cull( f, m, cull_result != SSG_INSIDE );
|
||||
}
|
||||
|
||||
pos->removeAllKids();
|
||||
|
||||
postTravTests ( SSGTRAV_CULL ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ssgEntityArray::hot ( sgVec3 s, sgMat4 m, int test_needed )
|
||||
{
|
||||
if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) )
|
||||
return ;
|
||||
|
||||
int hot_result = hot_test ( s, m, test_needed ) ;
|
||||
|
||||
if ( hot_result == SSG_OUTSIDE )
|
||||
return ;
|
||||
|
||||
_ssgPushPath ( this ) ;
|
||||
|
||||
pos->removeAllKids();
|
||||
pos->addKid( model );
|
||||
|
||||
for ( int i = 0; i < locations->getNum(); ++i ) {
|
||||
sgCoord c;
|
||||
sgSetCoord( &c, locations->get(i), orientations->get(i) );
|
||||
pos->setTransform( &c );
|
||||
pos->hot ( s, m, hot_result != SSG_INSIDE );
|
||||
}
|
||||
|
||||
pos->removeAllKids();
|
||||
|
||||
_ssgPopPath () ;
|
||||
|
||||
postTravTests ( SSGTRAV_HOT ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ssgEntityArray::los ( sgVec3 s, sgMat4 m, int test_needed )
|
||||
{
|
||||
if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) )
|
||||
return ;
|
||||
|
||||
int los_result = los_test ( s, m, test_needed ) ;
|
||||
|
||||
if ( los_result == SSG_OUTSIDE )
|
||||
return ;
|
||||
|
||||
_ssgPushPath ( this ) ;
|
||||
|
||||
pos->removeAllKids();
|
||||
pos->addKid( model );
|
||||
|
||||
for ( int i = 0; i < locations->getNum(); ++i ) {
|
||||
sgCoord c;
|
||||
sgSetCoord( &c, locations->get(i), orientations->get(i) );
|
||||
pos->setTransform( &c );
|
||||
pos->los ( s, m, los_result != SSG_INSIDE ) ;
|
||||
}
|
||||
|
||||
pos->removeAllKids();
|
||||
|
||||
_ssgPopPath () ;
|
||||
|
||||
postTravTests ( SSGTRAV_LOS) ;
|
||||
}
|
||||
|
||||
|
||||
void ssgEntityArray::isect ( sgSphere *s, sgMat4 m, int test_needed )
|
||||
{
|
||||
if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) )
|
||||
return ;
|
||||
|
||||
int isect_result = isect_test ( s, m, test_needed ) ;
|
||||
|
||||
if ( isect_result == SSG_OUTSIDE )
|
||||
return ;
|
||||
|
||||
_ssgPushPath ( this ) ;
|
||||
|
||||
pos->removeAllKids();
|
||||
pos->addKid( model );
|
||||
|
||||
for ( int i = 0; i < locations->getNum(); ++i ) {
|
||||
sgCoord c;
|
||||
sgSetCoord( &c, locations->get(i), orientations->get(i) );
|
||||
pos->setTransform( &c );
|
||||
pos->isect ( s, m, isect_result != SSG_INSIDE ) ;
|
||||
}
|
||||
|
||||
pos->removeAllKids();
|
||||
|
||||
_ssgPopPath () ;
|
||||
|
||||
postTravTests ( SSGTRAV_ISECT ) ;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int ssgEntityArray::load ( FILE *fd )
|
||||
{
|
||||
int nkids ;
|
||||
|
||||
_ssgReadInt ( fd, & nkids ) ;
|
||||
|
||||
if ( ! ssgEntity::load ( fd ) )
|
||||
return FALSE ;
|
||||
|
||||
for ( int i = 0 ; i < nkids ; i++ )
|
||||
{
|
||||
ssgEntity *kid ;
|
||||
|
||||
if ( ! _ssgLoadObject ( fd, (ssgBase **) &kid, ssgTypeEntity () ) )
|
||||
return FALSE ;
|
||||
|
||||
addKid ( kid ) ;
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
int ssgEntityArray::save ( FILE *fd )
|
||||
{
|
||||
_ssgWriteInt ( fd, getNumKids() ) ;
|
||||
|
||||
if ( ! ssgEntity::save ( fd ) )
|
||||
return FALSE ;
|
||||
|
||||
for ( int i = 0 ; i < getNumKids() ; i++ )
|
||||
{
|
||||
if ( ! _ssgSaveObject ( fd, getKid ( i ) ) )
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
#endif
|
||||
|
66
simgear/screen/ssgEntityArray.hxx
Normal file
66
simgear/screen/ssgEntityArray.hxx
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef _SSG_ENTITY_ARRAY_HXX
|
||||
#define _SSG_ENTITY_ARRAY_HXX
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <plib/ssg.h>
|
||||
|
||||
|
||||
class ssgEntityArray : public ssgEntity
|
||||
{
|
||||
// The replicated child
|
||||
ssgEntity *model ;
|
||||
|
||||
// The one transformation node
|
||||
ssgTransform *pos;
|
||||
|
||||
// The list of locations and orientations
|
||||
ssgVertexArray *locations;
|
||||
ssgVertexArray *orientations;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void copy_from ( ssgEntityArray *src, int clone_flags ) ;
|
||||
|
||||
public:
|
||||
|
||||
virtual void zeroSpareRecursive ();
|
||||
|
||||
virtual ssgBase *clone ( int clone_flags = 0 ) ;
|
||||
ssgEntityArray (void) ;
|
||||
virtual ~ssgEntityArray (void) ;
|
||||
|
||||
ssgEntity *getModel () const { return model ; }
|
||||
void setModel ( ssgEntity *entity ) { model = entity; }
|
||||
void removeModel () ;
|
||||
void replaceModel ( ssgEntity *new_entity ) ;
|
||||
|
||||
ssgVertexArray *getLocations () const { return locations; }
|
||||
ssgVertexArray *getOrientations () const { return orientations; }
|
||||
|
||||
float *getLocation ( int i ) const { return locations->get( i ); }
|
||||
float *getOrientation ( int i ) const { return orientations->get( i ); }
|
||||
void addPlacement ( sgVec3 loc, sgVec3 orient );
|
||||
virtual int getNumPlacements() const { return locations->getNum(); }
|
||||
void removeAllPlacements();
|
||||
|
||||
ssgTransform *getPosTransform() { return pos; }
|
||||
|
||||
virtual const char *getTypeName(void) ;
|
||||
virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ;
|
||||
virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ;
|
||||
virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ;
|
||||
virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ;
|
||||
virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
|
||||
#ifdef HAVE_PLIB_PSL
|
||||
virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) ;
|
||||
#endif
|
||||
virtual int load ( FILE *fd ) ;
|
||||
virtual int save ( FILE *fd ) ;
|
||||
virtual void recalcBSphere () ;
|
||||
} ;
|
||||
|
||||
|
||||
#endif // _SSG_ENTITY_ARRAY_HXX
|
Loading…
Reference in New Issue
Block a user