1
0
Fork 0

This is a little something I'm dabbling with ... an alternate approach

to doing random ground cover objects.  This is still in it's embrionic
state so don't expect this to do anything useful or interesting yet.
It shouldn't hurt anything though either.
This commit is contained in:
curt 2003-05-22 19:05:16 +00:00
parent 0d9685184a
commit 9b27c9c425
3 changed files with 419 additions and 1 deletions

View file

@ -2,6 +2,7 @@ noinst_LIBRARIES = libObjects.a
libObjects_a_SOURCES = \ libObjects_a_SOURCES = \
obj.cxx obj.hxx \ obj.cxx obj.hxx \
userdata.cxx userdata.hxx userdata.cxx userdata.hxx \
ssgEntityArray.hxx ssgEntityArray.cxx
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src

View file

@ -0,0 +1,357 @@
/*
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$
*/
#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 ) ;
}
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() ;
}
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

View file

@ -0,0 +1,60 @@
#ifndef _SSG_ENTITY_ARRAY_HXX
#define _SSG_ENTITY_ARRAY_HXX
#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 () { return model ; }
void setModel ( ssgEntity *entity ) { model = entity; }
void removeModel () ;
void replaceModel ( ssgEntity *new_entity ) ;
ssgVertexArray *getLocations () { return locations; }
ssgVertexArray *getOrientations () { return orientations; }
float *getLocation ( int i ) { return locations->get( i ); }
float *getOrientation ( int i ) { return orientations->get( i ); }
void addPlacement ( sgVec3 loc, sgVec3 orient );
virtual int getNumPlacements() { 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 ) ;
virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) ;
virtual int load ( FILE *fd ) ;
virtual int save ( FILE *fd ) ;
virtual void recalcBSphere () ;
} ;
#endif // _SSG_ENTITY_ARRAY_HXX