1
0
Fork 0

Mathias Frhlich:

This patch makes the aircraft carrier's hardware  appear in the scenegraph.
This commit is contained in:
ehofman 2004-11-26 10:24:48 +00:00
parent 91ae7ce82a
commit 63c1f4b613
6 changed files with 291 additions and 22 deletions

View file

@ -21,6 +21,7 @@
#define _FG_AIBASE_HXX
#include <string>
#include <list>
#include <simgear/constants.h>
#include <simgear/math/point3d.hxx>
@ -29,6 +30,7 @@
#include <Main/fg_props.hxx>
SG_USING_STD(string);
SG_USING_STD(list);
class FGAIManager;
class FGAIFlightPlan;
@ -67,6 +69,9 @@ typedef struct {
bool wind; // if true, model reacts to parent wind
double mass; // in slugs
bool aero_stabilised; // if true, ballistic object aligns with trajectory
list<string> solid_objects; // List of solid object names
list<string> wire_objects; // List of wire object names
list<string> catapult_objects; // List of catapult object names
double radius; // used by ship ojects, in feet
} FGAIModelEntity;

View file

@ -21,6 +21,9 @@
# include <config.h>
#endif
#include <string>
#include <vector>
#include "AICarrier.hxx"
@ -30,10 +33,179 @@ FGAICarrier::FGAICarrier(FGAIManager* mgr) : FGAIShip(mgr) {
FGAICarrier::~FGAICarrier() {
}
void FGAICarrier::setSolidObjects(const list<string>& so) {
solid_objects = so;
}
void FGAICarrier::setWireObjects(const list<string>& wo) {
wire_objects = wo;
}
void FGAICarrier::setCatapultObjects(const list<string>& co) {
catapult_objects = co;
}
void FGAICarrier::getVelocityWrtEarth(sgVec3 v) {
sgCopyVec3(v, vel_wrt_earth );
}
void FGAICarrier::update(double dt) {
FGAIShip::update(dt);
// Update the velocity information stored in those nodes.
double v_north = 0.51444444*speed*cos(hdg * SGD_DEGREES_TO_RADIANS);
double v_east = 0.51444444*speed*sin(hdg * SGD_DEGREES_TO_RADIANS);
double sin_lat = sin(pos.lat() * SGD_DEGREES_TO_RADIANS);
double cos_lat = cos(pos.lat() * SGD_DEGREES_TO_RADIANS);
double sin_lon = sin(pos.lon() * SGD_DEGREES_TO_RADIANS);
double cos_lon = cos(pos.lon() * SGD_DEGREES_TO_RADIANS);
sgSetVec3( vel_wrt_earth,
- cos_lon*sin_lat*v_north - sin_lon*v_east,
- sin_lon*sin_lat*v_north + cos_lon*v_east,
cos_lat*v_north );
}
bool FGAICarrier::init() {
if (!FGAIShip::init())
return false;
// process the 3d model here
// mark some objects solid, mark the wires ...
// The model should be used for altitude computations.
// To avoid that every detail in a carrier 3D model will end into
// the aircraft local cache, only set the HOT traversal bit on
// selected objects.
ssgEntity *sel = aip.getSceneGraph();
// Clear the HOT traversal flag
mark_nohot(sel);
// Selectively set that flag again for wires/cats/solid objects.
// Attach a pointer to this carrier class to those objects.
mark_wires(sel, wire_objects);
mark_cat(sel, catapult_objects);
mark_solid(sel, solid_objects);
return true;
}
void FGAICarrier::mark_nohot(ssgEntity* e) {
if (e->isAKindOf(ssgTypeBranch())) {
ssgBranch* br = (ssgBranch*)e;
ssgEntity* kid;
for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
mark_nohot(kid);
br->clrTraversalMaskBits(SSGTRAV_HOT);
} else if (e->isAKindOf(ssgTypeLeaf())) {
e->clrTraversalMaskBits(SSGTRAV_HOT);
}
}
bool FGAICarrier::mark_wires(ssgEntity* e, const list<string>& wire_objects) {
bool found = false;
if (e->isAKindOf(ssgTypeBranch())) {
ssgBranch* br = (ssgBranch*)e;
ssgEntity* kid;
for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
found = mark_wires(kid, wire_objects) || found;
if (found)
br->setTraversalMaskBits(SSGTRAV_HOT);
} else if (e->isAKindOf(ssgTypeLeaf())) {
list<string>::const_iterator it;
for (it = wire_objects.begin(); it != wire_objects.end(); ++it) {
if (e->getName() && (*it) == e->getName()) {
e->setTraversalMaskBits(SSGTRAV_HOT);
e->setUserData( FGAICarrierHardware::newWire( this ) );
ssgLeaf *l = (ssgLeaf*)e;
if ( l->getNumLines() != 1 ) {
SG_LOG(SG_GENERAL, SG_ALERT,
"AICarrier: Found wires not modelled with exactly one line!");
}
found = true;
}
}
}
return found;
}
bool FGAICarrier::mark_solid(ssgEntity* e, const list<string>& solid_objects) {
bool found = false;
if (e->isAKindOf(ssgTypeBranch())) {
ssgBranch* br = (ssgBranch*)e;
ssgEntity* kid;
for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
found = mark_solid(kid, solid_objects) || found;
if (found)
br->setTraversalMaskBits(SSGTRAV_HOT);
} else if (e->isAKindOf(ssgTypeLeaf())) {
list<string>::const_iterator it;
for (it = solid_objects.begin(); it != solid_objects.end(); ++it) {
if (e->getName() && (*it) == e->getName()) {
e->setTraversalMaskBits(SSGTRAV_HOT);
e->setUserData( FGAICarrierHardware::newSolid( this ) );
found = true;
}
}
}
return found;
}
bool FGAICarrier::mark_cat(ssgEntity* e, const list<string>& cat_objects) {
bool found = false;
if (e->isAKindOf(ssgTypeBranch())) {
ssgBranch* br = (ssgBranch*)e;
ssgEntity* kid;
for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
found = mark_cat(kid, cat_objects) || found;
if (found)
br->setTraversalMaskBits(SSGTRAV_HOT);
} else if (e->isAKindOf(ssgTypeLeaf())) {
list<string>::const_iterator it;
for (it = cat_objects.begin(); it != cat_objects.end(); ++it) {
if (e->getName() && (*it) == e->getName()) {
e->setTraversalMaskBits(SSGTRAV_HOT);
e->setUserData( FGAICarrierHardware::newCatapult( this ) );
ssgLeaf *l = (ssgLeaf*)e;
if ( l->getNumLines() != 1 ) {
SG_LOG(SG_GENERAL, SG_ALERT,
"AICarrier: Found a cat not modelled with exactly one line!");
}
// Now some special code to make shure the cat points in the right
// direction. The 0 index must be the backward end, the 1 index
// the forward end.
// Forward is positive x-direction in our 3D model, also the model
// as such is flattened when it is loaded, so we do not need to care
// for transforms ...
short v[2];
l->getLine(0, v, v+1 );
sgVec3 ends[2];
for (int k=0; k<2; ++k)
sgCopyVec3( ends[k], l->getVertex( v[k] ) );
// When the 1 end is behind the 0 end, swap the coordinates.
if (ends[0][0] < ends[1][0]) {
sgCopyVec3( l->getVertex( v[0] ), ends[1] );
sgCopyVec3( l->getVertex( v[1] ), ends[0] );
}
found = true;
}
}
}
return found;
}
int FGAICarrierHardware::unique_id = 1;

View file

@ -21,8 +21,52 @@
#ifndef _FG_AICARRIER_HXX
#define _FG_AICARRIER_HXX
#include <string>
#include <list>
#include <plib/ssg.h>
#include <simgear/compiler.h>
SG_USING_STD(string);
SG_USING_STD(list);
#include "AIShip.hxx"
class FGAIManager;
class FGAICarrier;
class FGAICarrierHardware : public ssgBase {
public:
enum Type { Catapult, Wire, Solid };
FGAICarrier *carrier;
int id;
Type type;
static FGAICarrierHardware* newCatapult(FGAICarrier *c) {
FGAICarrierHardware* ch = new FGAICarrierHardware;
ch->carrier = c;
ch->type = Catapult;
ch->id = unique_id++;
return ch;
}
static FGAICarrierHardware* newWire(FGAICarrier *c) {
FGAICarrierHardware* ch = new FGAICarrierHardware;
ch->carrier = c;
ch->type = Wire;
ch->id = unique_id++;
return ch;
}
static FGAICarrierHardware* newSolid(FGAICarrier *c) {
FGAICarrierHardware* ch = new FGAICarrierHardware;
ch->carrier = c;
ch->type = Solid;
ch->id = unique_id++;
return ch;
}
private:
static int unique_id;
};
class FGAICarrier : public FGAIShip {
@ -31,9 +75,28 @@ public:
FGAICarrier(FGAIManager* mgr);
~FGAICarrier();
void setSolidObjects(const list<string>& solid_objects);
void setWireObjects(const list<string>& wire_objects);
void setCatapultObjects(const list<string>& catapult_objects);
void getVelocityWrtEarth(sgVec3 v);
bool init();
private:
void update(double dt);
void mark_nohot(ssgEntity*);
bool mark_wires(ssgEntity*, const list<string>&);
bool mark_cat(ssgEntity*, const list<string>&);
bool mark_solid(ssgEntity*, const list<string>&);
list<string> solid_objects; // List of solid object names
list<string> wire_objects; // List of wire object names
list<string> catapult_objects; // List of catapult object names
// Velocity wrt earth.
sgVec3 vel_wrt_earth;
};
#endif // _FG_AICARRIER_HXX

View file

@ -192,7 +192,7 @@ FGAIManager::createCarrier( FGAIModelEntity *entity ) {
//cout << "creating carrier" << endl;
FGAIShip* ai_carrier = new FGAICarrier(this);
FGAICarrier* ai_carrier = new FGAICarrier(this);
ai_list.push_back(ai_carrier);
++numObjects[0];
++numObjects[FGAIBase::otShip];
@ -203,6 +203,9 @@ FGAIManager::createCarrier( FGAIModelEntity *entity ) {
ai_carrier->setLongitude(entity->longitude);
ai_carrier->setLatitude(entity->latitude);
ai_carrier->setBank(entity->rudder);
ai_carrier->setSolidObjects(entity->solid_objects);
ai_carrier->setWireObjects(entity->wire_objects);
ai_carrier->setCatapultObjects(entity->catapult_objects);
ai_carrier->setRadius(entity->radius);
if ( entity->fp ) {

View file

@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <cstdio>
#include <simgear/misc/sg_path.hxx>
#include <simgear/debug/logstream.hxx>
@ -32,7 +33,8 @@
#include "AIScenario.hxx"
#include "AIFlightPlan.hxx"
static list<string>
getAllNodeVals(const char* name, SGPropertyNode * entry_node);
FGAIScenario::FGAIScenario(string &filename)
{
@ -92,6 +94,10 @@ FGAIScenario::FGAIScenario(string &filename)
en->y_pivot = entry_node->getDoubleValue("y-pivot", 0.0);
en->z_pivot = entry_node->getDoubleValue("z-pivot", 0.0); */
en->wire_objects = getAllNodeVals("wire", entry_node);
en->catapult_objects = getAllNodeVals("catapult", entry_node);
en->solid_objects = getAllNodeVals("solid", entry_node);
en->fp = NULL;
if (en->flightplan != ""){
en->fp = new FGAIFlightPlan( en->flightplan );
@ -126,5 +132,25 @@ int FGAIScenario::nEntries( void )
return entries.size();
}
static list<string>
getAllNodeVals(const char* name, SGPropertyNode * entry_node)
{
list<string> retval;
int i=0;
do {
char nodename[100];
snprintf(nodename, sizeof(nodename), "%s[%d]", name, i);
const char* objname = entry_node->getStringValue(nodename, 0);
if (objname == 0)
return retval;
retval.push_back(string(objname));
++i;
} while (1);
return retval;
}
// end scenario.cxx

View file

@ -49,31 +49,31 @@ FGGroundCache::extractGroundProperty( ssgLeaf* l )
GroundProperty *gp = new GroundProperty;
gp->wire_id = -1;
// FGAICarrierHardware *ud =
// dynamic_cast<FGAICarrierHardware*>(l->getUserData());
// if (ud) {
// switch (ud->type) {
// case FGAICarrierHardware::Wire:
// gp->type = FGInterface::Wire;
// gp->wire_id = ud->id;
// break;
// case FGAICarrierHardware::Catapult:
// gp->type = FGInterface::Catapult;
// break;
// default:
// gp->type = FGInterface::Solid;
// break;
// }
FGAICarrierHardware *ud =
dynamic_cast<FGAICarrierHardware*>(l->getUserData());
if (ud) {
switch (ud->type) {
case FGAICarrierHardware::Wire:
gp->type = FGInterface::Wire;
gp->wire_id = ud->id;
break;
case FGAICarrierHardware::Catapult:
gp->type = FGInterface::Catapult;
break;
default:
gp->type = FGInterface::Solid;
break;
}
// // Copy the velocity from the carrier class.
// ud->carrier->getVelocityWrtEarth( gp->vel );
// }
// Copy the velocity from the carrier class.
ud->carrier->getVelocityWrtEarth( gp->vel );
}
// else {
else {
// Initialize velocity field.
sgSetVec3( gp->vel, 0.0, 0.0, 0.0 );
// }
}
// Get the texture name and decide what ground type we have.
ssgState *st = l->getState();