Merge branch 'work4' into next
Conflicts: src/Environment/environment_mgr.cxx Signed-off-by: Vivian Meazza <vivian.meazza@lineone.net>
This commit is contained in:
commit
a61f34667f
7 changed files with 283 additions and 150 deletions
|
@ -61,10 +61,12 @@ FGAIBallistic::FGAIBallistic(object_type ot) :
|
||||||
_slave_load_to_ac(false),
|
_slave_load_to_ac(false),
|
||||||
_contents_lb(0),
|
_contents_lb(0),
|
||||||
_report_collision(false),
|
_report_collision(false),
|
||||||
|
_report_expiry(false),
|
||||||
_report_impact(false),
|
_report_impact(false),
|
||||||
_external_force(false),
|
_external_force(false),
|
||||||
_impact_report_node(fgGetNode("/ai/models/model-impact", true)),
|
_impact_report_node(fgGetNode("/ai/models/model-impact", true)),
|
||||||
_old_height(0)
|
_old_height(0),
|
||||||
|
_elapsed_time(0)
|
||||||
|
|
||||||
{
|
{
|
||||||
no_roll = false;
|
no_roll = false;
|
||||||
|
@ -80,7 +82,8 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) {
|
||||||
|
|
||||||
FGAIBase::readFromScenario(scFileNode);
|
FGAIBase::readFromScenario(scFileNode);
|
||||||
|
|
||||||
//setPath(scFileNode->getStringValue("model", "Models/Geometry/rocket.ac"));
|
//setPath(scFileNode->getStringValue("model", "Models/Geometry/rocket.ac"));
|
||||||
|
setRandom(scFileNode->getBoolValue("random", false));
|
||||||
setAzimuth(scFileNode->getDoubleValue("azimuth", 0.0));
|
setAzimuth(scFileNode->getDoubleValue("azimuth", 0.0));
|
||||||
setElevation(scFileNode->getDoubleValue("elevation", 0));
|
setElevation(scFileNode->getDoubleValue("elevation", 0));
|
||||||
setDragArea(scFileNode->getDoubleValue("eda", 0.007));
|
setDragArea(scFileNode->getDoubleValue("eda", 0.007));
|
||||||
|
@ -93,10 +96,11 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) {
|
||||||
setCd(scFileNode->getDoubleValue("cd", 0.029));
|
setCd(scFileNode->getDoubleValue("cd", 0.029));
|
||||||
//setMass(scFileNode->getDoubleValue("mass", 0.007));
|
//setMass(scFileNode->getDoubleValue("mass", 0.007));
|
||||||
setWeight(scFileNode->getDoubleValue("weight", 0.25));
|
setWeight(scFileNode->getDoubleValue("weight", 0.25));
|
||||||
setStabilisation(scFileNode->getBoolValue("aero-stabilized", false));
|
setStabilisation(scFileNode->getBoolValue("aero-stabilised", false));
|
||||||
setNoRoll(scFileNode->getBoolValue("no-roll", false));
|
setNoRoll(scFileNode->getBoolValue("no-roll", false));
|
||||||
setRandom(scFileNode->getBoolValue("random", false));
|
|
||||||
setImpact(scFileNode->getBoolValue("impact", false));
|
setImpact(scFileNode->getBoolValue("impact", false));
|
||||||
|
setExpiry(scFileNode->getBoolValue("expiry", false));
|
||||||
|
setCollision(scFileNode->getBoolValue("collision", false));
|
||||||
setImpactReportNode(scFileNode->getStringValue("impact-reports"));
|
setImpactReportNode(scFileNode->getStringValue("impact-reports"));
|
||||||
setName(scFileNode->getStringValue("name", "Rocket"));
|
setName(scFileNode->getStringValue("name", "Rocket"));
|
||||||
setFuseRange(scFileNode->getDoubleValue("fuse-range", 0.0));
|
setFuseRange(scFileNode->getDoubleValue("fuse-range", 0.0));
|
||||||
|
@ -104,7 +108,7 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) {
|
||||||
setSubID(scFileNode->getIntValue("SubID", 0));
|
setSubID(scFileNode->getIntValue("SubID", 0));
|
||||||
setExternalForce(scFileNode->getBoolValue("external-force", false));
|
setExternalForce(scFileNode->getBoolValue("external-force", false));
|
||||||
setForcePath(scFileNode->getStringValue("force-path", ""));
|
setForcePath(scFileNode->getStringValue("force-path", ""));
|
||||||
setForceStabilisation(scFileNode->getBoolValue("force-stabilized", false));
|
setForceStabilisation(scFileNode->getBoolValue("force-stabilised", false));
|
||||||
setXoffset(scFileNode->getDoubleValue("x-offset", 0.0));
|
setXoffset(scFileNode->getDoubleValue("x-offset", 0.0));
|
||||||
setYoffset(scFileNode->getDoubleValue("y-offset", 0.0));
|
setYoffset(scFileNode->getDoubleValue("y-offset", 0.0));
|
||||||
setZoffset(scFileNode->getDoubleValue("z-offset", 0.0));
|
setZoffset(scFileNode->getDoubleValue("z-offset", 0.0));
|
||||||
|
@ -116,7 +120,6 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) {
|
||||||
setSlaved(scFileNode->getBoolValue("slaved", false));
|
setSlaved(scFileNode->getBoolValue("slaved", false));
|
||||||
setSlavedLoad(scFileNode->getBoolValue("slaved-load", false));
|
setSlavedLoad(scFileNode->getBoolValue("slaved-load", false));
|
||||||
setContentsNode(scFileNode->getStringValue("contents"));
|
setContentsNode(scFileNode->getStringValue("contents"));
|
||||||
setRandom(scFileNode->getBoolValue("random", false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FGAIBallistic::init(bool search_in_AI_path) {
|
bool FGAIBallistic::init(bool search_in_AI_path) {
|
||||||
|
@ -124,6 +127,16 @@ bool FGAIBallistic::init(bool search_in_AI_path) {
|
||||||
|
|
||||||
_impact_reported = false;
|
_impact_reported = false;
|
||||||
_collision_reported = false;
|
_collision_reported = false;
|
||||||
|
_expiry_reported = false;
|
||||||
|
|
||||||
|
_impact_lat = 0;
|
||||||
|
_impact_lon = 0;
|
||||||
|
_impact_elev = 0;
|
||||||
|
_impact_hdg = 0;
|
||||||
|
_impact_pitch = 0;
|
||||||
|
_impact_roll = 0;
|
||||||
|
_impact_speed = 0;
|
||||||
|
|
||||||
invisible = false;
|
invisible = false;
|
||||||
|
|
||||||
_elapsed_time += (sg_random() * 100);
|
_elapsed_time += (sg_random() * 100);
|
||||||
|
@ -131,6 +144,8 @@ bool FGAIBallistic::init(bool search_in_AI_path) {
|
||||||
props->setStringValue("material/name", "");
|
props->setStringValue("material/name", "");
|
||||||
props->setStringValue("name", _name.c_str());
|
props->setStringValue("name", _name.c_str());
|
||||||
props->setStringValue("submodels/path", _submodel.c_str());
|
props->setStringValue("submodels/path", _submodel.c_str());
|
||||||
|
props->setStringValue("force/path", _force_path.c_str());
|
||||||
|
//props->setStringValue("vector/path", _vector_path.c_str());
|
||||||
|
|
||||||
// start with high value so that animations don't trigger yet
|
// start with high value so that animations don't trigger yet
|
||||||
_ht_agl_ft = 1e10;
|
_ht_agl_ft = 1e10;
|
||||||
|
@ -263,7 +278,14 @@ void FGAIBallistic::update(double dt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIBallistic::setAzimuth(double az) {
|
void FGAIBallistic::setAzimuth(double az) {
|
||||||
hdg = _azimuth = az;
|
|
||||||
|
|
||||||
|
if (_random)
|
||||||
|
hdg = _azimuth = (az - 5 ) + (10 * sg_random());
|
||||||
|
else
|
||||||
|
hdg = _azimuth = az;
|
||||||
|
|
||||||
|
//cout << _name << " init hdg " << hdg << " random " << _random << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIBallistic::setElevation(double el) {
|
void FGAIBallistic::setElevation(double el) {
|
||||||
|
@ -291,7 +313,12 @@ void FGAIBallistic::setDragArea(double a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIBallistic::setLife(double seconds) {
|
void FGAIBallistic::setLife(double seconds) {
|
||||||
life = seconds;
|
|
||||||
|
if (_random){
|
||||||
|
life = seconds * _randomness + (seconds * (1 -_randomness) * sg_random());
|
||||||
|
//cout << "life " << life << endl;
|
||||||
|
} else
|
||||||
|
life = seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIBallistic::setBuoyancy(double fpss) {
|
void FGAIBallistic::setBuoyancy(double fpss) {
|
||||||
|
@ -321,6 +348,11 @@ void FGAIBallistic::setMass(double m) {
|
||||||
void FGAIBallistic::setWeight(double w) {
|
void FGAIBallistic::setWeight(double w) {
|
||||||
_weight_lb = w;
|
_weight_lb = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGAIBallistic::setRandomness(double r) {
|
||||||
|
_randomness = r;
|
||||||
|
}
|
||||||
|
|
||||||
void FGAIBallistic::setRandom(bool r) {
|
void FGAIBallistic::setRandom(bool r) {
|
||||||
_random = r;
|
_random = r;
|
||||||
}
|
}
|
||||||
|
@ -333,6 +365,11 @@ void FGAIBallistic::setCollision(bool c) {
|
||||||
_report_collision = c;
|
_report_collision = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGAIBallistic::setExpiry(bool e) {
|
||||||
|
_report_expiry = e;
|
||||||
|
//cout << "_report_expiry " << _report_expiry << endl;
|
||||||
|
}
|
||||||
|
|
||||||
void FGAIBallistic::setExternalForce(bool f) {
|
void FGAIBallistic::setExternalForce(bool f) {
|
||||||
_external_force = f;
|
_external_force = f;
|
||||||
}
|
}
|
||||||
|
@ -479,17 +516,17 @@ void FGAIBallistic::setHt(double h, double dt, double coeff){
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIBallistic::setHdg(double az, double dt, double coeff){
|
void FGAIBallistic::setHdg(double az, double dt, double coeff){
|
||||||
double recip = getRecip(hdg);
|
double recip = getRecip(hdg);
|
||||||
double c = dt / (coeff + dt);
|
double c = dt / (coeff + dt);
|
||||||
//we need to ensure that we turn the short way to the new hdg
|
//we need to ensure that we turn the short way to the new hdg
|
||||||
if (az < recip && az < hdg && hdg > 180) {
|
if (az < recip && az < hdg && hdg > 180) {
|
||||||
hdg = ((az + 360) * c) + (hdg * (1 - c));
|
hdg = ((az + 360) * c) + (hdg * (1 - c));
|
||||||
} else if (az > recip && az > hdg && hdg <= 180){
|
} else if (az > recip && az > hdg && hdg <= 180){
|
||||||
hdg = ((az - 360) * c) + (hdg * (1 - c));
|
hdg = ((az - 360) * c) + (hdg * (1 - c));
|
||||||
} else {
|
} else {
|
||||||
hdg = (az * c) + (hdg * (1 - c));
|
hdg = (az * c) + (hdg * (1 - c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double FGAIBallistic::getTgtXOffset() const {
|
double FGAIBallistic::getTgtXOffset() const {
|
||||||
return _tgt_x_offset;
|
return _tgt_x_offset;
|
||||||
|
@ -536,15 +573,22 @@ void FGAIBallistic::Run(double dt) {
|
||||||
_life_timer += dt;
|
_life_timer += dt;
|
||||||
|
|
||||||
// if life = -1 the object does not die
|
// if life = -1 the object does not die
|
||||||
if (_life_timer > life && life != -1)
|
if (_life_timer > life && life != -1){
|
||||||
setDie(true);
|
|
||||||
|
if (_report_expiry && !_expiry_reported){
|
||||||
|
//cout<<"AIBallistic: expiry"<< endl;
|
||||||
|
handle_expiry();
|
||||||
|
} else
|
||||||
|
setDie(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//set the contents in the appropriate tank or other property in the parent to zero
|
//set the contents in the appropriate tank or other property in the parent to zero
|
||||||
setContents(0);
|
setContents(0);
|
||||||
|
|
||||||
//randomise Cd by +- 5%
|
//randomise Cd by +- 10%
|
||||||
if (_random)
|
if (_random)
|
||||||
_Cd = _Cd * 0.95 + (0.05 * sg_random());
|
_Cd = _Cd * 0.90 + (0.10 * sg_random());
|
||||||
|
|
||||||
// Adjust Cd by Mach number. The equations are based on curves
|
// Adjust Cd by Mach number. The equations are based on curves
|
||||||
// for a conventional shell/bullet (no boat-tail).
|
// for a conventional shell/bullet (no boat-tail).
|
||||||
|
@ -617,12 +661,13 @@ void FGAIBallistic::Run(double dt) {
|
||||||
double friction_force_speed_east_deg_sec = 0;
|
double friction_force_speed_east_deg_sec = 0;
|
||||||
double force_elevation_deg = 0;
|
double force_elevation_deg = 0;
|
||||||
|
|
||||||
if (_external_force) {
|
if (_external_force) {
|
||||||
|
|
||||||
SGPropertyNode *n = fgGetNode(_force_path.c_str(), true);
|
SGPropertyNode *n = fgGetNode(_force_path.c_str(), true);
|
||||||
double force_lbs = n->getChild("force-lb", 0, true)->getDoubleValue();
|
double force_lbs = n->getChild("force-lb", 0, true)->getDoubleValue();
|
||||||
force_elevation_deg = n->getChild("force-elevation-deg", 0, true)->getDoubleValue();
|
force_elevation_deg = n->getChild("force-elevation-deg", 0, true)->getDoubleValue();
|
||||||
double force_azimuth_deg = n->getChild("force-azimuth-deg", 0, true)->getDoubleValue();
|
double force_azimuth_deg = n->getChild("force-azimuth-deg", 0, true)->getDoubleValue();
|
||||||
|
|
||||||
//resolve force into vertical and horizontal components:
|
//resolve force into vertical and horizontal components:
|
||||||
double v_force_lbs = force_lbs * sin( force_elevation_deg * SG_DEGREES_TO_RADIANS );
|
double v_force_lbs = force_lbs * sin( force_elevation_deg * SG_DEGREES_TO_RADIANS );
|
||||||
h_force_lbs = force_lbs * cos( force_elevation_deg * SG_DEGREES_TO_RADIANS );
|
h_force_lbs = force_lbs * cos( force_elevation_deg * SG_DEGREES_TO_RADIANS );
|
||||||
|
@ -751,14 +796,19 @@ void FGAIBallistic::Run(double dt) {
|
||||||
if (_azimuth < 0)
|
if (_azimuth < 0)
|
||||||
_azimuth += 360;
|
_azimuth += 360;
|
||||||
|
|
||||||
|
//cout << "_azimuth " << _azimuth << " hdg "<< hdg << endl;
|
||||||
|
|
||||||
if (_aero_stabilised) { // we simulate rotational moment of inertia by using a filter
|
if (_aero_stabilised) { // we simulate rotational moment of inertia by using a filter
|
||||||
|
cout<< "_aero_stabilised "<< endl;
|
||||||
const double coeff = 0.9;
|
const double coeff = 0.9;
|
||||||
|
|
||||||
// we assume a symetrical MI about the pitch and yaw axis
|
// we assume a symetrical MI about the pitch and yaw axis
|
||||||
setPch(_elevation, dt, coeff);
|
setPch(_elevation, dt, coeff);
|
||||||
setHdg(_azimuth, dt, coeff);
|
setHdg(_azimuth, dt, coeff);
|
||||||
} else if (_force_stabilised) { // we simulate rotational moment of inertia by using a filter
|
} else if (_force_stabilised) { // we simulate rotational moment of inertia by using a filter
|
||||||
const double coeff = 0.9;
|
//cout<< "_force_stabilised "<< endl;
|
||||||
|
|
||||||
|
const double coeff = 0.9;
|
||||||
double ratio = h_force_lbs/(_mass * slugs_to_lbs);
|
double ratio = h_force_lbs/(_mass * slugs_to_lbs);
|
||||||
|
|
||||||
if (ratio > 1) ratio = 1;
|
if (ratio > 1) ratio = 1;
|
||||||
|
@ -809,6 +859,20 @@ void FGAIBallistic::handle_impact() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGAIBallistic::handle_expiry() {
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: handle_expiry " << pos.getElevationM());
|
||||||
|
|
||||||
|
report_impact(pos.getElevationM());
|
||||||
|
_expiry_reported = true;
|
||||||
|
|
||||||
|
//if (life == -1){
|
||||||
|
// invisible = true;
|
||||||
|
//} else if (_subID == 0) // kill the AIObject if there is no subsubmodel
|
||||||
|
// setDie(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void FGAIBallistic::handle_collision()
|
void FGAIBallistic::handle_collision()
|
||||||
{
|
{
|
||||||
const FGAIBase *object = manager->calcCollision(pos.getElevationFt(),
|
const FGAIBase *object = manager->calcCollision(pos.getElevationFt(),
|
||||||
|
@ -857,7 +921,7 @@ SGVec3d FGAIBallistic::getCartHitchPos() const{
|
||||||
|
|
||||||
// convert geodetic positions to geocentered
|
// convert geodetic positions to geocentered
|
||||||
SGVec3d cartuserPos = getCartUserPos();
|
SGVec3d cartuserPos = getCartUserPos();
|
||||||
SGVec3d cartPos = getCartPos();
|
//SGVec3d cartPos = getCartPos();
|
||||||
|
|
||||||
// Transform to the right coordinate frame, configuration is done in
|
// Transform to the right coordinate frame, configuration is done in
|
||||||
// the x-forward, y-right, z-up coordinates (feet), computation
|
// the x-forward, y-right, z-up coordinates (feet), computation
|
||||||
|
|
|
@ -68,8 +68,10 @@ public:
|
||||||
void setWeight( double w );
|
void setWeight( double w );
|
||||||
void setNoRoll( bool nr );
|
void setNoRoll( bool nr );
|
||||||
void setRandom( bool r );
|
void setRandom( bool r );
|
||||||
|
void setRandomness( double r );
|
||||||
void setName(const string&);
|
void setName(const string&);
|
||||||
void setCollision(bool c);
|
void setCollision(bool c);
|
||||||
|
void setExpiry(bool e);
|
||||||
void setImpact(bool i);
|
void setImpact(bool i);
|
||||||
void setImpactReportNode(const string&);
|
void setImpactReportNode(const string&);
|
||||||
void setContentsNode(const string&);
|
void setContentsNode(const string&);
|
||||||
|
@ -150,7 +152,8 @@ private:
|
||||||
bool _wind; // if true, local wind will be applied to object
|
bool _wind; // if true, local wind will be applied to object
|
||||||
double _Cd; // drag coefficient
|
double _Cd; // drag coefficient
|
||||||
double _mass; // slugs
|
double _mass; // slugs
|
||||||
bool _random; // modifier for Cd
|
bool _random; // modifier for Cd, life, az
|
||||||
|
double _randomness; // dimension for _random
|
||||||
double _load_resistance; // ground load resistanc N/m^2
|
double _load_resistance; // ground load resistanc N/m^2
|
||||||
double _frictionFactor; // dimensionless modifier for Coefficient of Friction
|
double _frictionFactor; // dimensionless modifier for Coefficient of Friction
|
||||||
bool _solid; // if true ground is solid for FDMs
|
bool _solid; // if true ground is solid for FDMs
|
||||||
|
@ -164,6 +167,7 @@ private:
|
||||||
bool _report_collision; // if true a collision point with AI Objects is calculated
|
bool _report_collision; // if true a collision point with AI Objects is calculated
|
||||||
bool _report_impact; // if true an impact point on the terrain is calculated
|
bool _report_impact; // if true an impact point on the terrain is calculated
|
||||||
bool _external_force; // if true then apply external force
|
bool _external_force; // if true then apply external force
|
||||||
|
bool _report_expiry;
|
||||||
|
|
||||||
SGPropertyNode_ptr _impact_report_node; // report node for impact and collision
|
SGPropertyNode_ptr _impact_report_node; // report node for impact and collision
|
||||||
SGPropertyNode_ptr _contents_node; // report node for impact and collision
|
SGPropertyNode_ptr _contents_node; // report node for impact and collision
|
||||||
|
@ -181,6 +185,7 @@ private:
|
||||||
const SGMaterial* _material;
|
const SGMaterial* _material;
|
||||||
|
|
||||||
void handle_collision();
|
void handle_collision();
|
||||||
|
void handle_expiry();
|
||||||
void handle_impact();
|
void handle_impact();
|
||||||
void report_impact(double elevation, const FGAIBase *target = 0);
|
void report_impact(double elevation, const FGAIBase *target = 0);
|
||||||
void slaveToAC(double dt);
|
void slaveToAC(double dt);
|
||||||
|
@ -192,13 +197,13 @@ private:
|
||||||
double getDistanceLoadToHitch() const;
|
double getDistanceLoadToHitch() const;
|
||||||
double getElevLoadToHitch() const;
|
double getElevLoadToHitch() const;
|
||||||
double getBearingLoadToHitch() const;
|
double getBearingLoadToHitch() const;
|
||||||
|
|
||||||
double getRecip(double az);
|
double getRecip(double az);
|
||||||
double getMass() const;
|
double getMass() const;
|
||||||
|
|
||||||
double hs;
|
double hs;
|
||||||
double _ground_offset;
|
double _ground_offset;
|
||||||
double _load_offset;
|
double _load_offset;
|
||||||
double _force;
|
|
||||||
double _old_height;
|
double _old_height;
|
||||||
|
|
||||||
SGVec3d _oldcarthitchPos;
|
SGVec3d _oldcarthitchPos;
|
||||||
|
|
|
@ -81,6 +81,8 @@ FGAIBase::FGAIBase(object_type ot) :
|
||||||
delete_me = false;
|
delete_me = false;
|
||||||
_impact_reported = false;
|
_impact_reported = false;
|
||||||
_collision_reported = false;
|
_collision_reported = false;
|
||||||
|
_expiry_reported = false;
|
||||||
|
|
||||||
_subID = 0;
|
_subID = 0;
|
||||||
|
|
||||||
_x_offset = 0;
|
_x_offset = 0;
|
||||||
|
@ -579,6 +581,10 @@ bool FGAIBase::_getCollisionData() {
|
||||||
return _collision_reported;
|
return _collision_reported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FGAIBase::_getExpiryData() {
|
||||||
|
return _expiry_reported;
|
||||||
|
}
|
||||||
|
|
||||||
bool FGAIBase::_getImpactData() {
|
bool FGAIBase::_getImpactData() {
|
||||||
return _impact_reported;
|
return _impact_reported;
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,7 @@ protected:
|
||||||
|
|
||||||
bool _impact_reported;
|
bool _impact_reported;
|
||||||
bool _collision_reported;
|
bool _collision_reported;
|
||||||
|
bool _expiry_reported;
|
||||||
|
|
||||||
double _impact_lat;
|
double _impact_lat;
|
||||||
double _impact_lon;
|
double _impact_lon;
|
||||||
|
@ -246,6 +247,7 @@ public:
|
||||||
bool _getImpact();
|
bool _getImpact();
|
||||||
bool _getImpactData();
|
bool _getImpactData();
|
||||||
bool _getCollisionData();
|
bool _getCollisionData();
|
||||||
|
bool _getExpiryData();
|
||||||
|
|
||||||
SGPropertyNode* _getProps() const;
|
SGPropertyNode* _getProps() const;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ FGSubmodelMgr::FGSubmodelMgr()
|
||||||
string contents_node;
|
string contents_node;
|
||||||
contrail_altitude = 30000;
|
contrail_altitude = 30000;
|
||||||
_count = 0;
|
_count = 0;
|
||||||
|
_found_sub = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGSubmodelMgr::~FGSubmodelMgr()
|
FGSubmodelMgr::~FGSubmodelMgr()
|
||||||
|
@ -82,7 +83,9 @@ void FGSubmodelMgr::init()
|
||||||
void FGSubmodelMgr::postinit() {
|
void FGSubmodelMgr::postinit() {
|
||||||
// postinit, so that the AI list is populated
|
// postinit, so that the AI list is populated
|
||||||
loadAI();
|
loadAI();
|
||||||
loadSubmodels();
|
|
||||||
|
while (_found_sub)
|
||||||
|
loadSubmodels();
|
||||||
|
|
||||||
//TODO reload submodels if an MP ac joins
|
//TODO reload submodels if an MP ac joins
|
||||||
}
|
}
|
||||||
|
@ -106,6 +109,7 @@ void FGSubmodelMgr::update(double dt)
|
||||||
|
|
||||||
_impact = false;
|
_impact = false;
|
||||||
_hit = false;
|
_hit = false;
|
||||||
|
_expiry = false;
|
||||||
|
|
||||||
// check if the submodel hit an object or terrain
|
// check if the submodel hit an object or terrain
|
||||||
sm_list = ai->get_ai_list();
|
sm_list = ai->get_ai_list();
|
||||||
|
@ -115,14 +119,16 @@ void FGSubmodelMgr::update(double dt)
|
||||||
for (; sm_list_itr != end; ++sm_list_itr) {
|
for (; sm_list_itr != end; ++sm_list_itr) {
|
||||||
_impact = (*sm_list_itr)->_getImpactData();
|
_impact = (*sm_list_itr)->_getImpactData();
|
||||||
_hit = (*sm_list_itr)->_getCollisionData();
|
_hit = (*sm_list_itr)->_getCollisionData();
|
||||||
|
_expiry = (*sm_list_itr)->_getExpiryData();
|
||||||
int parent_subID = (*sm_list_itr)->_getSubID();
|
int parent_subID = (*sm_list_itr)->_getSubID();
|
||||||
//SG_LOG(SG_GENERAL, SG_DEBUG, "Submodel: Impact " << _impact << " hit! "
|
//SG_LOG(SG_GENERAL, SG_DEBUG, "Submodel: Impact " << _impact << " hit! "
|
||||||
// << _hit <<" parent_subID " << parent_subID);
|
// << _hit <<" parent_subID " << parent_subID);
|
||||||
if ( parent_subID == 0) // this entry in the list has no associated submodel
|
if ( parent_subID == 0) // this entry in the list has no associated submodel
|
||||||
continue; // so we can continue
|
continue; // so we can continue
|
||||||
|
|
||||||
if (_impact || _hit) {
|
if (_impact || _hit || _expiry) {
|
||||||
//SG_LOG(SG_GENERAL, SG_DEBUG, "Submodel: Impact " << _impact << " hit! " << _hit );
|
// SG_LOG(SG_GENERAL, SG_ALERT, "Submodel: Impact " << _impact << " hit! " << _hit
|
||||||
|
//<< " exipiry :-( " << _expiry );
|
||||||
|
|
||||||
submodel_iterator = submodels.begin();
|
submodel_iterator = submodels.begin();
|
||||||
|
|
||||||
|
@ -139,9 +145,11 @@ void FGSubmodelMgr::update(double dt)
|
||||||
_parent_roll = (*sm_list_itr)->_getImpactRoll();
|
_parent_roll = (*sm_list_itr)->_getImpactRoll();
|
||||||
_parent_speed = (*sm_list_itr)->_getImpactSpeed();
|
_parent_speed = (*sm_list_itr)->_getImpactSpeed();
|
||||||
(*submodel_iterator)->first_time = true;
|
(*submodel_iterator)->first_time = true;
|
||||||
|
//cout << "Impact: parent SubID = child_ID elev " << _parent_elev << endl;
|
||||||
|
|
||||||
if (release(*submodel_iterator, dt))
|
if (release(*submodel_iterator, dt))
|
||||||
(*sm_list_itr)->setDie(true);
|
(*sm_list_itr)->setDie(true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++submodel_iterator;
|
++submodel_iterator;
|
||||||
|
@ -169,64 +177,25 @@ void FGSubmodelMgr::update(double dt)
|
||||||
if ((*submodel_iterator)->trigger_node != 0) {
|
if ((*submodel_iterator)->trigger_node != 0) {
|
||||||
_trigger_node = (*submodel_iterator)->trigger_node;
|
_trigger_node = (*submodel_iterator)->trigger_node;
|
||||||
trigger = _trigger_node->getBoolValue();
|
trigger = _trigger_node->getBoolValue();
|
||||||
//cout << "trigger node found " << trigger << endl;
|
//cout << (*submodel_iterator)->name << "trigger node found " << trigger << endl;
|
||||||
} else {
|
} else {
|
||||||
trigger = true;
|
trigger = true;
|
||||||
//cout << (*submodel_iterator)->name << "trigger node not found " << trigger << endl;
|
//cout << (*submodel_iterator)->name << "trigger node not found " << trigger << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trigger) {
|
if (trigger && (*submodel_iterator)->count != 0) {
|
||||||
int id = (*submodel_iterator)->id;
|
|
||||||
string name = (*submodel_iterator)->name;
|
|
||||||
// don't release submodels from AI Objects if they are
|
|
||||||
// too far away to be seen. id 0 is not an AI model,
|
|
||||||
// so we can skip the whole process
|
|
||||||
sm_list_iterator sm_list_itr = sm_list.begin();
|
|
||||||
sm_list_iterator end = sm_list.end();
|
|
||||||
|
|
||||||
while (sm_list_itr != end) {
|
int id = (*submodel_iterator)->id;
|
||||||
in_range = true;
|
string name = (*submodel_iterator)->name;
|
||||||
|
/*SG_LOG(SG_GENERAL, SG_DEBUG,
|
||||||
|
"Submodels end: " << (*submodel_iterator)->id
|
||||||
|
<< " name " << (*submodel_iterator)->name
|
||||||
|
<< " count " << (*submodel_iterator)->count
|
||||||
|
<< " in range " << in_range);*/
|
||||||
|
|
||||||
if (id == 0) {
|
release(*submodel_iterator, dt);
|
||||||
//SG_LOG(SG_GENERAL, SG_DEBUG,
|
} else
|
||||||
// "Submodels: continuing: " << id << " name " << name );
|
(*submodel_iterator)->first_time = true;
|
||||||
++sm_list_itr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int parent_id = (*submodel_iterator)->id;
|
|
||||||
|
|
||||||
if (parent_id == id) {
|
|
||||||
double parent_lat = (*sm_list_itr)->_getLatitude();
|
|
||||||
double parent_lon = (*sm_list_itr)->_getLongitude();
|
|
||||||
string parent_name = (*sm_list_itr)->_getName();
|
|
||||||
double own_lat = _user_lat_node->getDoubleValue();
|
|
||||||
double own_lon = _user_lon_node->getDoubleValue();
|
|
||||||
double range_nm = getRange(parent_lat, parent_lon, own_lat, own_lon);
|
|
||||||
//cout << "parent name " << parent_name << ", "<< parent_id << ", "<< parent_lat << ", " << parent_lon << endl;
|
|
||||||
//cout << "own name " << own_lat << ", " << own_lon << " range " << range_nm << endl;
|
|
||||||
|
|
||||||
if (range_nm > 15) {
|
|
||||||
//SG_LOG(SG_GENERAL, SG_DEBUG,
|
|
||||||
// "Submodels: skipping release, out of range: " << id);
|
|
||||||
in_range = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++sm_list_itr;
|
|
||||||
} // end while
|
|
||||||
|
|
||||||
/*SG_LOG(SG_GENERAL, SG_DEBUG,
|
|
||||||
"Submodels end: " << (*submodel_iterator)->id
|
|
||||||
<< " name " << (*submodel_iterator)->name
|
|
||||||
<< " count " << (*submodel_iterator)->count
|
|
||||||
<< " in range " << in_range);*/
|
|
||||||
|
|
||||||
if ((*submodel_iterator)->count != 0 && in_range)
|
|
||||||
release(*submodel_iterator, dt);
|
|
||||||
|
|
||||||
} else
|
|
||||||
(*submodel_iterator)->first_time = true;
|
|
||||||
|
|
||||||
++submodel_iterator;
|
++submodel_iterator;
|
||||||
} // end while
|
} // end while
|
||||||
|
@ -247,9 +216,11 @@ bool FGSubmodelMgr::release(submodel *sm, double dt)
|
||||||
sm->timer += dt;
|
sm->timer += dt;
|
||||||
|
|
||||||
if (sm->timer < sm->delay) {
|
if (sm->timer < sm->delay) {
|
||||||
//cout << "not yet: timer" << sm->timer << " delay " << sm->delay<< endl;
|
//cout << "not yet: timer " << sm->timer << " delay " << sm->delay << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//cout << "released timer: " << sm->timer << " delay " << sm->delay << endl;
|
||||||
|
|
||||||
sm->timer = 0.0;
|
sm->timer = 0.0;
|
||||||
|
|
||||||
|
@ -262,9 +233,12 @@ bool FGSubmodelMgr::release(submodel *sm, double dt)
|
||||||
|
|
||||||
FGAIBallistic* ballist = new FGAIBallistic;
|
FGAIBallistic* ballist = new FGAIBallistic;
|
||||||
ballist->setPath(sm->model.c_str());
|
ballist->setPath(sm->model.c_str());
|
||||||
ballist->setLatitude(IC.lat);
|
ballist->setName(sm->name);
|
||||||
ballist->setLongitude(IC.lon);
|
ballist->setRandom(sm->random);
|
||||||
ballist->setAltitude(IC.alt);
|
ballist->setRandomness(sm->randomness);
|
||||||
|
ballist->setLatitude(offsetpos.getLatitudeDeg());
|
||||||
|
ballist->setLongitude(offsetpos.getLongitudeDeg());
|
||||||
|
ballist->setAltitude(offsetpos.getElevationFt());
|
||||||
ballist->setAzimuth(IC.azimuth);
|
ballist->setAzimuth(IC.azimuth);
|
||||||
ballist->setElevation(IC.elevation);
|
ballist->setElevation(IC.elevation);
|
||||||
ballist->setRoll(IC.roll);
|
ballist->setRoll(IC.roll);
|
||||||
|
@ -279,8 +253,8 @@ bool FGSubmodelMgr::release(submodel *sm, double dt)
|
||||||
ballist->setCd(sm->cd);
|
ballist->setCd(sm->cd);
|
||||||
ballist->setStabilisation(sm->aero_stabilised);
|
ballist->setStabilisation(sm->aero_stabilised);
|
||||||
ballist->setNoRoll(sm->no_roll);
|
ballist->setNoRoll(sm->no_roll);
|
||||||
ballist->setName(sm->name);
|
|
||||||
ballist->setCollision(sm->collision);
|
ballist->setCollision(sm->collision);
|
||||||
|
ballist->setExpiry(sm->expiry);
|
||||||
ballist->setImpact(sm->impact);
|
ballist->setImpact(sm->impact);
|
||||||
ballist->setImpactReportNode(sm->impact_report);
|
ballist->setImpactReportNode(sm->impact_report);
|
||||||
ballist->setFuseRange(sm->fuse_range);
|
ballist->setFuseRange(sm->fuse_range);
|
||||||
|
@ -293,7 +267,6 @@ bool FGSubmodelMgr::release(submodel *sm, double dt)
|
||||||
|
|
||||||
if (sm->count > 0)
|
if (sm->count > 0)
|
||||||
sm->count--;
|
sm->count--;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +311,9 @@ void FGSubmodelMgr::transform(submodel *sm)
|
||||||
|
|
||||||
//cout << " name " << name << " id " << id << " sub id" << sub_id << endl;
|
//cout << " name " << name << " id " << id << " sub id" << sub_id << endl;
|
||||||
|
|
||||||
if (_impact || _hit) {
|
// set the Initial Conditions for the types of submodel parent
|
||||||
|
|
||||||
|
if (_impact || _hit || _expiry) {
|
||||||
// set the data for a submodel tied to a submodel
|
// set the data for a submodel tied to a submodel
|
||||||
_count++;
|
_count++;
|
||||||
//cout << "Submodels: release sub sub " << _count<< endl;
|
//cout << "Submodels: release sub sub " << _count<< endl;
|
||||||
|
@ -413,12 +388,22 @@ void FGSubmodelMgr::transform(submodel *sm)
|
||||||
cout << "speed north " << IC.speed_north_fps << endl ;
|
cout << "speed north " << IC.speed_north_fps << endl ;
|
||||||
cout << "parent speed fps in" << IC.speed << "sm speed in " << sm->speed << endl ;*/
|
cout << "parent speed fps in" << IC.speed << "sm speed in " << sm->speed << endl ;*/
|
||||||
|
|
||||||
|
// Set the Initial Conditions that are common to all types of parent
|
||||||
IC.wind_from_east = _user_wind_from_east_node->getDoubleValue();
|
IC.wind_from_east = _user_wind_from_east_node->getDoubleValue();
|
||||||
IC.wind_from_north = _user_wind_from_north_node->getDoubleValue();
|
IC.wind_from_north = _user_wind_from_north_node->getDoubleValue();
|
||||||
|
|
||||||
in[0] = sm->x_offset;
|
userpos.setLatitudeDeg(IC.lat);
|
||||||
in[1] = sm->y_offset;
|
userpos.setLongitudeDeg(IC.lon);
|
||||||
in[2] = sm->z_offset;
|
userpos.setElevationFt(IC.alt);
|
||||||
|
|
||||||
|
_x_offset = sm->x_offset;
|
||||||
|
_y_offset = sm->y_offset;
|
||||||
|
_z_offset = sm->z_offset;
|
||||||
|
|
||||||
|
setOffsetPos();
|
||||||
|
|
||||||
|
//IC.elevation += sm->pitch_offset;
|
||||||
|
//IC.azimuth += sm->yaw_offset ;
|
||||||
|
|
||||||
// pre-process the trig functions
|
// pre-process the trig functions
|
||||||
cosRx = cos(-IC.roll * SG_DEGREES_TO_RADIANS);
|
cosRx = cos(-IC.roll * SG_DEGREES_TO_RADIANS);
|
||||||
|
@ -428,35 +413,35 @@ void FGSubmodelMgr::transform(submodel *sm)
|
||||||
cosRz = cos(IC.azimuth * SG_DEGREES_TO_RADIANS);
|
cosRz = cos(IC.azimuth * SG_DEGREES_TO_RADIANS);
|
||||||
sinRz = sin(IC.azimuth * SG_DEGREES_TO_RADIANS);
|
sinRz = sin(IC.azimuth * SG_DEGREES_TO_RADIANS);
|
||||||
|
|
||||||
// set up the transform matrix
|
//// set up the transform matrix
|
||||||
trans[0][0] = cosRy * cosRz;
|
//trans[0][0] = cosRy * cosRz;
|
||||||
trans[0][1] = -1 * cosRx * sinRz + sinRx * sinRy * cosRz ;
|
//trans[0][1] = -1 * cosRx * sinRz + sinRx * sinRy * cosRz ;
|
||||||
trans[0][2] = sinRx * sinRz + cosRx * sinRy * cosRz;
|
//trans[0][2] = sinRx * sinRz + cosRx * sinRy * cosRz;
|
||||||
|
|
||||||
trans[1][0] = cosRy * sinRz;
|
//trans[1][0] = cosRy * sinRz;
|
||||||
trans[1][1] = cosRx * cosRz + sinRx * sinRy * sinRz;
|
//trans[1][1] = cosRx * cosRz + sinRx * sinRy * sinRz;
|
||||||
trans[1][2] = -1 * sinRx * cosRx + cosRx * sinRy * sinRz;
|
//trans[1][2] = -1 * sinRx * cosRx + cosRx * sinRy * sinRz;
|
||||||
|
|
||||||
trans[2][0] = -1 * sinRy;
|
//trans[2][0] = -1 * sinRy;
|
||||||
trans[2][1] = sinRx * cosRy;
|
//trans[2][1] = sinRx * cosRy;
|
||||||
trans[2][2] = cosRx * cosRy;
|
//trans[2][2] = cosRx * cosRy;
|
||||||
|
|
||||||
|
|
||||||
// multiply the input and transform matrices
|
//// multiply the input and transform matrices
|
||||||
out[0] = in[0] * trans[0][0] + in[1] * trans[0][1] + in[2] * trans[0][2];
|
//out[0] = in[0] * trans[0][0] + in[1] * trans[0][1] + in[2] * trans[0][2];
|
||||||
out[1] = in[0] * trans[1][0] + in[1] * trans[1][1] + in[2] * trans[1][2];
|
//out[1] = in[0] * trans[1][0] + in[1] * trans[1][1] + in[2] * trans[1][2];
|
||||||
out[2] = in[0] * trans[2][0] + in[1] * trans[2][1] + in[2] * trans[2][2];
|
//out[2] = in[0] * trans[2][0] + in[1] * trans[2][1] + in[2] * trans[2][2];
|
||||||
|
|
||||||
// convert ft to degrees of latitude
|
//// convert ft to degrees of latitude
|
||||||
out[0] = out[0] / (366468.96 - 3717.12 * cos(IC.lat * SG_DEGREES_TO_RADIANS));
|
//out[0] = out[0] / (366468.96 - 3717.12 * cos(IC.lat * SG_DEGREES_TO_RADIANS));
|
||||||
|
|
||||||
// convert ft to degrees of longitude
|
//// convert ft to degrees of longitude
|
||||||
out[1] = out[1] / (365228.16 * cos(IC.lat * SG_DEGREES_TO_RADIANS));
|
//out[1] = out[1] / (365228.16 * cos(IC.lat * SG_DEGREES_TO_RADIANS));
|
||||||
|
|
||||||
// set submodel initial position
|
//// set submodel initial position
|
||||||
IC.lat += out[0];
|
//IC.lat += out[0];
|
||||||
IC.lon += out[1];
|
//IC.lon += out[1];
|
||||||
IC.alt += out[2];
|
//IC.alt += out[2];
|
||||||
|
|
||||||
// get aircraft velocity vector angles in XZ and XY planes
|
// get aircraft velocity vector angles in XZ and XY planes
|
||||||
//double alpha = _user_alpha_node->getDoubleValue();
|
//double alpha = _user_alpha_node->getDoubleValue();
|
||||||
|
@ -464,7 +449,7 @@ void FGSubmodelMgr::transform(submodel *sm)
|
||||||
//double velXY = IC.azimuth - (IC.elevation - alpha * sinRx);
|
//double velXY = IC.azimuth - (IC.elevation - alpha * sinRx);
|
||||||
|
|
||||||
// Get submodel initial velocity vector angles in XZ and XY planes.
|
// Get submodel initial velocity vector angles in XZ and XY planes.
|
||||||
// This needs to be fixed. This vector should be added to aircraft's vector.
|
// This vector should be added to aircraft's vector.
|
||||||
IC.elevation += (sm->yaw_offset * sinRx) + (sm->pitch_offset * cosRx);
|
IC.elevation += (sm->yaw_offset * sinRx) + (sm->pitch_offset * cosRx);
|
||||||
IC.azimuth += (sm->yaw_offset * cosRx) - (sm->pitch_offset * sinRx);
|
IC.azimuth += (sm->yaw_offset * cosRx) - (sm->pitch_offset * sinRx);
|
||||||
|
|
||||||
|
@ -487,7 +472,7 @@ void FGSubmodelMgr::transform(submodel *sm)
|
||||||
|
|
||||||
// if speeds are low this calculation can become unreliable
|
// if speeds are low this calculation can become unreliable
|
||||||
if (IC.speed > 1) {
|
if (IC.speed > 1) {
|
||||||
IC.azimuth = atan2(IC.total_speed_east , IC.total_speed_north) * SG_RADIANS_TO_DEGREES;
|
//IC.azimuth = atan2(IC.total_speed_east, IC.total_speed_north) * SG_RADIANS_TO_DEGREES;
|
||||||
// cout << "azimuth1 " << IC.azimuth<<endl;
|
// cout << "azimuth1 " << IC.azimuth<<endl;
|
||||||
|
|
||||||
// rationalise the output
|
// rationalise the output
|
||||||
|
@ -539,15 +524,6 @@ void FGSubmodelMgr::loadAI()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double FGSubmodelMgr::getRange(double lat, double lon, double lat2, double lon2) const
|
|
||||||
{
|
|
||||||
double course, distance, az2;
|
|
||||||
|
|
||||||
//calculate the bearing and range of the second pos from the first
|
|
||||||
geo_inverse_wgs_84(lat, lon, lat2, lon2, &course, &az2, &distance);
|
|
||||||
distance *= SG_METER_TO_NM;
|
|
||||||
return distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
|
void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
|
||||||
{
|
{
|
||||||
|
@ -595,6 +571,7 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
|
||||||
sm->aero_stabilised = entry_node->getBoolValue("aero-stabilised", true);
|
sm->aero_stabilised = entry_node->getBoolValue("aero-stabilised", true);
|
||||||
sm->no_roll = entry_node->getBoolValue("no-roll", false);
|
sm->no_roll = entry_node->getBoolValue("no-roll", false);
|
||||||
sm->collision = entry_node->getBoolValue("collision", false);
|
sm->collision = entry_node->getBoolValue("collision", false);
|
||||||
|
sm->expiry = entry_node->getBoolValue("expiry", false);
|
||||||
sm->impact = entry_node->getBoolValue("impact", false);
|
sm->impact = entry_node->getBoolValue("impact", false);
|
||||||
sm->impact_report = entry_node->getStringValue("impact-reports");
|
sm->impact_report = entry_node->getStringValue("impact-reports");
|
||||||
sm->fuse_range = entry_node->getDoubleValue("fuse-range", 0.0);
|
sm->fuse_range = entry_node->getDoubleValue("fuse-range", 0.0);
|
||||||
|
@ -604,6 +581,10 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
|
||||||
sm->force_stabilised= entry_node->getBoolValue("force-stabilised", false);
|
sm->force_stabilised= entry_node->getBoolValue("force-stabilised", false);
|
||||||
sm->ext_force = entry_node->getBoolValue("external-force", false);
|
sm->ext_force = entry_node->getBoolValue("external-force", false);
|
||||||
sm->force_path = entry_node->getStringValue("force-path", "");
|
sm->force_path = entry_node->getStringValue("force-path", "");
|
||||||
|
sm->random = entry_node->getBoolValue("random", false);
|
||||||
|
sm->randomness = entry_node->getDoubleValue("randomness", 0.5);
|
||||||
|
|
||||||
|
|
||||||
//cout << "sm->contents_node " << sm->contents_node << endl;
|
//cout << "sm->contents_node " << sm->contents_node << endl;
|
||||||
if (sm->contents_node != 0)
|
if (sm->contents_node != 0)
|
||||||
sm->contents = sm->contents_node->getDoubleValue();
|
sm->contents = sm->contents_node->getDoubleValue();
|
||||||
|
@ -626,11 +607,13 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
|
||||||
sm->sub_id = 0;
|
sm->sub_id = 0;
|
||||||
|
|
||||||
sm->prop = fgGetNode("/ai/submodels/submodel", index, true);
|
sm->prop = fgGetNode("/ai/submodels/submodel", index, true);
|
||||||
|
sm->prop->tie("delay", SGRawValuePointer<double>(&(sm->delay)));
|
||||||
sm->prop->tie("count", SGRawValuePointer<int>(&(sm->count)));
|
sm->prop->tie("count", SGRawValuePointer<int>(&(sm->count)));
|
||||||
sm->prop->tie("repeat", SGRawValuePointer<bool>(&(sm->repeat)));
|
sm->prop->tie("repeat", SGRawValuePointer<bool>(&(sm->repeat)));
|
||||||
sm->prop->tie("id", SGRawValuePointer<int>(&(sm->id)));
|
sm->prop->tie("id", SGRawValuePointer<int>(&(sm->id)));
|
||||||
sm->prop->tie("sub-id", SGRawValuePointer<int>(&(sm->sub_id)));
|
sm->prop->tie("sub-id", SGRawValuePointer<int>(&(sm->sub_id)));
|
||||||
sm->prop->tie("serviceable", SGRawValuePointer<bool>(&(sm->serviceable)));
|
sm->prop->tie("serviceable", SGRawValuePointer<bool>(&(sm->serviceable)));
|
||||||
|
sm->prop->tie("random", SGRawValuePointer<bool>(&(sm->random)));
|
||||||
string name = sm->name;
|
string name = sm->name;
|
||||||
sm->prop->setStringValue("name", name.c_str());
|
sm->prop->setStringValue("name", name.c_str());
|
||||||
|
|
||||||
|
@ -640,7 +623,7 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
|
||||||
|
|
||||||
string force_path = sm->force_path;
|
string force_path = sm->force_path;
|
||||||
sm->prop->setStringValue("force_path", force_path.c_str());
|
sm->prop->setStringValue("force_path", force_path.c_str());
|
||||||
//cout << "set force_path " << force_path << endl;
|
//cout << "set force_path Sub " << force_path << endl;
|
||||||
|
|
||||||
if (sm->contents_node != 0)
|
if (sm->contents_node != 0)
|
||||||
sm->prop->tie("contents-lbs", SGRawValuePointer<double>(&(sm->contents)));
|
sm->prop->tie("contents-lbs", SGRawValuePointer<double>(&(sm->contents)));
|
||||||
|
@ -698,14 +681,18 @@ void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable)
|
||||||
sm->aero_stabilised = entry_node->getBoolValue("aero-stabilised", true);
|
sm->aero_stabilised = entry_node->getBoolValue("aero-stabilised", true);
|
||||||
sm->no_roll = entry_node->getBoolValue("no-roll", false);
|
sm->no_roll = entry_node->getBoolValue("no-roll", false);
|
||||||
sm->collision = entry_node->getBoolValue("collision", false);
|
sm->collision = entry_node->getBoolValue("collision", false);
|
||||||
|
sm->expiry = entry_node->getBoolValue("expiry", false);
|
||||||
sm->impact = entry_node->getBoolValue("impact", false);
|
sm->impact = entry_node->getBoolValue("impact", false);
|
||||||
sm->impact_report = entry_node->getStringValue("impact-reports");
|
sm->impact_report = entry_node->getStringValue("impact-reports");
|
||||||
sm->fuse_range = entry_node->getDoubleValue("fuse-range", 0.0);
|
sm->fuse_range = entry_node->getDoubleValue("fuse-range", 0.0);
|
||||||
sm->contents_node = fgGetNode(entry_node->getStringValue("contents", "none"), false);
|
sm->contents_node = fgGetNode(entry_node->getStringValue("contents", "none"), false);
|
||||||
sm->speed_node = fgGetNode(entry_node->getStringValue("speed-node", "none"), false);
|
sm->speed_node = fgGetNode(entry_node->getStringValue("speed-node", "none"), false);
|
||||||
sm->submodel = entry_node->getStringValue("submodel-path", "");
|
sm->submodel = entry_node->getStringValue("submodel-path", "");
|
||||||
|
sm->force_stabilised= entry_node->getBoolValue("force-stabilised", false);
|
||||||
sm->ext_force = entry_node->getBoolValue("external-force", false);
|
sm->ext_force = entry_node->getBoolValue("external-force", false);
|
||||||
sm->force_path = entry_node->getStringValue("force-path", "");
|
sm->force_path = entry_node->getStringValue("force-path", "");
|
||||||
|
sm->random = entry_node->getBoolValue("random", false);
|
||||||
|
sm->randomness = entry_node->getDoubleValue("randomness", 0.5);
|
||||||
|
|
||||||
//cout << "sm->contents_node " << sm->contents_node << endl;
|
//cout << "sm->contents_node " << sm->contents_node << endl;
|
||||||
if (sm->contents_node != 0)
|
if (sm->contents_node != 0)
|
||||||
|
@ -734,16 +721,17 @@ void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable)
|
||||||
sm->prop->tie("id", SGRawValuePointer<int>(&(sm->id)));
|
sm->prop->tie("id", SGRawValuePointer<int>(&(sm->id)));
|
||||||
sm->prop->tie("sub-id", SGRawValuePointer<int>(&(sm->sub_id)));
|
sm->prop->tie("sub-id", SGRawValuePointer<int>(&(sm->sub_id)));
|
||||||
sm->prop->tie("serviceable", SGRawValuePointer<bool>(&(sm->serviceable)));
|
sm->prop->tie("serviceable", SGRawValuePointer<bool>(&(sm->serviceable)));
|
||||||
|
sm->prop->tie("random", SGRawValuePointer<bool>(&(sm->random)));
|
||||||
string name = sm->name;
|
string name = sm->name;
|
||||||
sm->prop->setStringValue("name", name.c_str());
|
sm->prop->setStringValue("name", name.c_str());
|
||||||
|
|
||||||
string submodel = sm->submodel;
|
string submodel = sm->submodel;
|
||||||
sm->prop->setStringValue("submodel", submodel.c_str());
|
sm->prop->setStringValue("submodel", submodel.c_str());
|
||||||
// cout << " set submodel path " << submodel<< endl;
|
// cout << " set submodel path AI" << submodel<< endl;
|
||||||
|
|
||||||
string force_path = sm->force_path;
|
string force_path = sm->force_path;
|
||||||
sm->prop->setStringValue("force_path", force_path.c_str());
|
sm->prop->setStringValue("force_path", force_path.c_str());
|
||||||
//cout << "set force_path " << force_path << endl;
|
cout << "set force_path AI" << force_path << endl;
|
||||||
|
|
||||||
if (sm->contents_node != 0)
|
if (sm->contents_node != 0)
|
||||||
sm->prop->tie("contents-lbs", SGRawValuePointer<double>(&(sm->contents)));
|
sm->prop->tie("contents-lbs", SGRawValuePointer<double>(&(sm->contents)));
|
||||||
|
@ -757,31 +745,38 @@ void FGSubmodelMgr::loadSubmodels()
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Loading sub submodels");
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Loading sub submodels");
|
||||||
|
|
||||||
|
_found_sub = false;
|
||||||
|
|
||||||
submodel_iterator = submodels.begin();
|
submodel_iterator = submodels.begin();
|
||||||
|
|
||||||
while (submodel_iterator != submodels.end()) {
|
while (submodel_iterator != submodels.end()) {
|
||||||
string submodel = (*submodel_iterator)->submodel;
|
string submodel = (*submodel_iterator)->submodel;
|
||||||
if (!submodel.empty()) {
|
if (!submodel.empty()) {
|
||||||
//int id = (*submodel_iterator)->id;
|
//int id = (*submodel_iterator)->id;
|
||||||
bool serviceable = true;
|
bool serviceable = true;
|
||||||
//SG_LOG(SG_GENERAL, SG_DEBUG, "found path sub sub "
|
//SG_LOG(SG_GENERAL, SG_DEBUG, "found path sub sub "
|
||||||
// << submodel
|
// << submodel
|
||||||
// << " index " << index
|
// << " index " << index
|
||||||
// << "name " << (*submodel_iterator)->name);
|
// << "name " << (*submodel_iterator)->name);
|
||||||
|
|
||||||
(*submodel_iterator)->sub_id = index;
|
if ((*submodel_iterator)->sub_id == 0){
|
||||||
setSubData(index, submodel, serviceable);
|
(*submodel_iterator)->sub_id = index;
|
||||||
}
|
_found_sub = true;
|
||||||
|
setSubData(index, submodel, serviceable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
++submodel_iterator;
|
++submodel_iterator;
|
||||||
}
|
} // end while
|
||||||
|
|
||||||
subsubmodel_iterator = subsubmodels.begin();
|
subsubmodel_iterator = subsubmodels.begin();
|
||||||
|
|
||||||
while (subsubmodel_iterator != subsubmodels.end()) {
|
while (subsubmodel_iterator != subsubmodels.end()) {
|
||||||
submodels.push_back(*subsubmodel_iterator);
|
submodels.push_back(*subsubmodel_iterator);
|
||||||
++subsubmodel_iterator;
|
++subsubmodel_iterator;
|
||||||
}
|
} // end while
|
||||||
|
|
||||||
|
subsubmodels.clear();
|
||||||
|
|
||||||
//submodel_iterator = submodels.begin();
|
//submodel_iterator = submodels.begin();
|
||||||
|
|
||||||
|
@ -796,4 +791,44 @@ void FGSubmodelMgr::loadSubmodels()
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SGVec3d FGSubmodelMgr::getCartOffsetPos() const{
|
||||||
|
|
||||||
|
// convert geodetic positions to geocentered
|
||||||
|
SGVec3d cartuserPos = SGVec3d::fromGeod(userpos);
|
||||||
|
|
||||||
|
// Transform to the right coordinate frame, configuration is done in
|
||||||
|
// the x-forward, y-right, z-up coordinates (feet), computation
|
||||||
|
// in the simulation usual body x-forward, y-right, z-down coordinates
|
||||||
|
// (meters) )
|
||||||
|
|
||||||
|
SGVec3d _off(_x_offset * SG_FEET_TO_METER,
|
||||||
|
_y_offset * SG_FEET_TO_METER,
|
||||||
|
-_z_offset * SG_FEET_TO_METER);
|
||||||
|
|
||||||
|
// Transform the user position to the horizontal local coordinate system.
|
||||||
|
SGQuatd hlTrans = SGQuatd::fromLonLat(userpos);
|
||||||
|
|
||||||
|
// and postrotate the orientation of the user model wrt the horizontal
|
||||||
|
// local frame
|
||||||
|
hlTrans *= SGQuatd::fromYawPitchRollDeg(
|
||||||
|
IC.azimuth,
|
||||||
|
IC.elevation,
|
||||||
|
IC.roll);
|
||||||
|
|
||||||
|
// The offset converted to the usual body fixed coordinate system
|
||||||
|
// rotated to the earth-fixed coordinates axis
|
||||||
|
SGVec3d off = hlTrans.backTransform(_off);
|
||||||
|
|
||||||
|
// Add the position offset of the user model to get the geocentered position
|
||||||
|
SGVec3d offsetPos = cartuserPos + off;
|
||||||
|
|
||||||
|
return offsetPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGSubmodelMgr::setOffsetPos(){
|
||||||
|
// convert the offset geocentered position to geodetic
|
||||||
|
SGVec3d cartoffsetPos = getCartOffsetPos();
|
||||||
|
|
||||||
|
SGGeodesy::SGCartToGeod(cartoffsetPos, offsetpos);
|
||||||
|
}
|
||||||
// end of submodel.cxx
|
// end of submodel.cxx
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
double drag_area;
|
double drag_area;
|
||||||
double life;
|
double life;
|
||||||
double buoyancy;
|
double buoyancy;
|
||||||
|
double randomness;
|
||||||
bool wind;
|
bool wind;
|
||||||
bool first_time;
|
bool first_time;
|
||||||
double cd;
|
double cd;
|
||||||
|
@ -62,7 +63,9 @@ public:
|
||||||
int id;
|
int id;
|
||||||
bool no_roll;
|
bool no_roll;
|
||||||
bool serviceable;
|
bool serviceable;
|
||||||
|
bool random;
|
||||||
bool collision;
|
bool collision;
|
||||||
|
bool expiry;
|
||||||
bool impact;
|
bool impact;
|
||||||
string impact_report;
|
string impact_report;
|
||||||
double fuse_range;
|
double fuse_range;
|
||||||
|
@ -141,6 +144,10 @@ private:
|
||||||
double _parent_pitch;
|
double _parent_pitch;
|
||||||
double _parent_roll;
|
double _parent_roll;
|
||||||
double _parent_speed;
|
double _parent_speed;
|
||||||
|
double _x_offset;
|
||||||
|
double _y_offset;
|
||||||
|
double _z_offset;
|
||||||
|
|
||||||
|
|
||||||
static const double lbs_to_slugs; //conversion factor
|
static const double lbs_to_slugs; //conversion factor
|
||||||
|
|
||||||
|
@ -148,6 +155,8 @@ private:
|
||||||
|
|
||||||
bool _impact;
|
bool _impact;
|
||||||
bool _hit;
|
bool _hit;
|
||||||
|
bool _expiry;
|
||||||
|
bool _found_sub;
|
||||||
|
|
||||||
SGPropertyNode_ptr _serviceable_node;
|
SGPropertyNode_ptr _serviceable_node;
|
||||||
SGPropertyNode_ptr _user_lat_node;
|
SGPropertyNode_ptr _user_lat_node;
|
||||||
|
@ -190,9 +199,13 @@ private:
|
||||||
|
|
||||||
bool release(submodel *, double dt);
|
bool release(submodel *, double dt);
|
||||||
|
|
||||||
double getRange(double lat, double lon, double lat2, double lon2) const;
|
|
||||||
|
|
||||||
int _count;
|
int _count;
|
||||||
|
|
||||||
|
SGGeod userpos;
|
||||||
|
SGGeod offsetpos;
|
||||||
|
SGVec3d getCartOffsetPos() const;
|
||||||
|
void setOffsetPos();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/scene/sky/sky.hxx>
|
#include <simgear/scene/sky/sky.hxx>
|
||||||
|
@ -294,12 +292,22 @@ FGEnvironmentMgr::update (double dt)
|
||||||
|
|
||||||
_environment->set_elevation_ft(fgGetDouble("/position/altitude-ft"));
|
_environment->set_elevation_ft(fgGetDouble("/position/altitude-ft"));
|
||||||
_environment->set_local_weather_lift_fps(fgGetDouble("/local-weather/current/thermal-lift"));
|
_environment->set_local_weather_lift_fps(fgGetDouble("/local-weather/current/thermal-lift"));
|
||||||
osg::Vec3 windVec(-_environment->get_wind_from_north_fps(),
|
osg::Vec3 windVec(_environment->get_wind_from_north_fps(),
|
||||||
-_environment->get_wind_from_east_fps(),
|
-_environment->get_wind_from_east_fps(),
|
||||||
_environment->get_wind_from_down_fps());
|
0);
|
||||||
|
// SG_LOG(SG_GENERAL, SG_ALERT, "-_environment->get_wind_from_north_mps() " <<
|
||||||
|
//_environment->get_wind_from_north_fps() * SG_FEET_TO_METER
|
||||||
|
//<< " -_environment->get_wind_from_east_mps() "
|
||||||
|
//<< -_environment->get_wind_from_east_fps() * SG_FEET_TO_METER
|
||||||
|
//);
|
||||||
|
|
||||||
// simgear::Particles::setWindVector(windVec * SG_FEET_TO_METER);
|
// simgear::Particles::setWindVector(windVec * SG_FEET_TO_METER);
|
||||||
simgear::Particles::setWindFrom( _environment->get_wind_from_heading_deg(),
|
simgear::Particles::setWindFrom( _environment->get_wind_from_heading_deg(),
|
||||||
_environment->get_wind_speed_kt() );
|
_environment->get_wind_speed_kt() );
|
||||||
|
//double wind_true_deg = _environment->get_wind_from_heading_deg();
|
||||||
|
//simgear::Particles::setWindFrom( wind_true_deg,
|
||||||
|
// _environment->get_wind_speed_kt() );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FGEnvironment
|
FGEnvironment
|
||||||
|
|
Loading…
Add table
Reference in a new issue