Mathias Frhlich:
This patch makes the aircraft carrier's hardware appear in the scenegraph.
This commit is contained in:
parent
91ae7ce82a
commit
63c1f4b613
6 changed files with 291 additions and 22 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue