2007-06-24 07:57:45 +00:00
|
|
|
//// submodel.cxx - models a releasable submodel.
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
// Written by Dave Culp, started Aug 2004
|
2007-03-30 22:51:52 +00:00
|
|
|
// With major additions by Vivian Meaaza 2004 - 2007
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
//
|
|
|
|
// This file is in the Public Domain and comes with no warranty.
|
|
|
|
|
2006-02-18 13:58:09 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
#include "submodel.hxx"
|
2004-08-26 08:38:43 +00:00
|
|
|
|
|
|
|
#include <simgear/structure/exception.hxx>
|
|
|
|
#include <simgear/misc/sg_path.hxx>
|
2007-03-30 22:51:52 +00:00
|
|
|
#include <simgear/math/sg_geodesy.hxx>
|
2008-07-31 12:04:32 +00:00
|
|
|
#include <simgear/props/props_io.hxx>
|
2004-08-26 08:38:43 +00:00
|
|
|
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
#include <Main/fg_props.hxx>
|
|
|
|
#include <Main/util.hxx>
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
#include "AIBase.hxx"
|
|
|
|
#include "AIManager.hxx"
|
|
|
|
#include "AIBallistic.hxx"
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
|
2012-11-23 20:00:20 +00:00
|
|
|
using std::cout;
|
|
|
|
using std::endl;
|
2013-03-28 16:49:52 +00:00
|
|
|
using std::string;
|
|
|
|
using std::vector;
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
|
2004-10-22 09:58:24 +00:00
|
|
|
const double FGSubmodelMgr::lbs_to_slugs = 0.031080950172;
|
2004-09-22 08:47:05 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
FGSubmodelMgr::FGSubmodelMgr()
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
{
|
2010-08-28 23:00:09 +00:00
|
|
|
x_offset = y_offset = z_offset = 0.0;
|
|
|
|
pitch_offset = 0.0;
|
2007-03-30 22:51:52 +00:00
|
|
|
yaw_offset = 0.0;
|
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
//out[0] = out[1] = out[2] = 0;
|
2012-11-24 10:59:13 +00:00
|
|
|
//string contents_node;
|
2007-03-30 22:51:52 +00:00
|
|
|
contrail_altitude = 30000;
|
2007-06-07 16:30:26 +00:00
|
|
|
_count = 0;
|
2010-08-14 12:39:30 +00:00
|
|
|
_found_sub = true;
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
FGSubmodelMgr::~FGSubmodelMgr()
|
2007-06-07 16:30:26 +00:00
|
|
|
{
|
|
|
|
}
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2010-10-28 14:10:37 +00:00
|
|
|
FGAIManager* FGSubmodelMgr::aiManager()
|
|
|
|
{
|
2011-11-19 14:37:49 +00:00
|
|
|
return (FGAIManager*)globals->get_subsystem("ai-model");
|
2010-10-28 14:10:37 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
void FGSubmodelMgr::init()
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
{
|
2007-03-30 22:51:52 +00:00
|
|
|
index = 0;
|
|
|
|
|
2004-10-28 08:44:24 +00:00
|
|
|
_serviceable_node = fgGetNode("/sim/submodels/serviceable", true);
|
2007-03-30 22:51:52 +00:00
|
|
|
_serviceable_node->setBoolValue(true);
|
2004-09-05 09:45:34 +00:00
|
|
|
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
_user_lat_node = fgGetNode("/position/latitude-deg", true);
|
|
|
|
_user_lon_node = fgGetNode("/position/longitude-deg", true);
|
|
|
|
_user_alt_node = fgGetNode("/position/altitude-ft", true);
|
|
|
|
|
|
|
|
_user_heading_node = fgGetNode("/orientation/heading-deg", true);
|
2015-05-20 18:25:37 +00:00
|
|
|
_user_pitch_node = fgGetNode("/orientation/pitch-deg", true);
|
|
|
|
_user_roll_node = fgGetNode("/orientation/roll-deg", true);
|
|
|
|
_user_yaw_node = fgGetNode("/orientation/yaw-deg", true);
|
|
|
|
_user_alpha_node = fgGetNode("/orientation/alpha-deg", true);
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
|
|
|
|
_user_speed_node = fgGetNode("/velocities/uBody-fps", true);
|
2004-09-05 09:45:34 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
_user_wind_from_east_node = fgGetNode("/environment/wind-from-east-fps", true);
|
|
|
|
_user_wind_from_north_node = fgGetNode("/environment/wind-from-north-fps", true);
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
_user_speed_down_fps_node = fgGetNode("/velocities/speed-down-fps", true);
|
|
|
|
_user_speed_east_fps_node = fgGetNode("/velocities/speed-east-fps", true);
|
|
|
|
_user_speed_north_fps_node = fgGetNode("/velocities/speed-north-fps", true);
|
2004-09-22 08:47:05 +00:00
|
|
|
|
2004-11-07 14:46:21 +00:00
|
|
|
_contrail_altitude_node = fgGetNode("/environment/params/contrail-altitude", true);
|
2007-04-27 11:02:39 +00:00
|
|
|
contrail_altitude = _contrail_altitude_node->getDoubleValue();
|
|
|
|
_contrail_trigger = fgGetNode("ai/submodels/contrails", true);
|
2004-11-07 14:46:21 +00:00
|
|
|
_contrail_trigger->setBoolValue(false);
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2007-05-12 10:39:56 +00:00
|
|
|
load();
|
2007-04-27 11:02:39 +00:00
|
|
|
}
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
void FGSubmodelMgr::postinit()
|
|
|
|
{
|
2007-04-27 11:02:39 +00:00
|
|
|
// postinit, so that the AI list is populated
|
2015-05-20 18:25:37 +00:00
|
|
|
loadAI();
|
2010-07-16 22:05:05 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
while (_found_sub)
|
|
|
|
loadSubmodels();
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
//TODO reload submodels if an MP ac joins
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
//_model_added_node = fgGetNode("ai/models/model-added", true);
|
|
|
|
//_model_added_node->addChangeListener(this, false);
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
void FGSubmodelMgr::bind()
|
2015-05-20 18:25:37 +00:00
|
|
|
{
|
|
|
|
}
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
void FGSubmodelMgr::unbind()
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
{
|
2007-03-30 22:51:52 +00:00
|
|
|
submodel_iterator = submodels.begin();
|
|
|
|
while (submodel_iterator != submodels.end()) {
|
|
|
|
(*submodel_iterator)->prop->untie("count");
|
|
|
|
++submodel_iterator;
|
|
|
|
}
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
void FGSubmodelMgr::update(double dt)
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
{
|
2007-06-07 16:30:26 +00:00
|
|
|
if (!_serviceable_node->getBoolValue())
|
2007-03-30 22:51:52 +00:00
|
|
|
return;
|
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
_impact = false;
|
|
|
|
_hit = false;
|
2010-08-14 12:39:30 +00:00
|
|
|
_expiry = false;
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// Check if the submodel hit an object or terrain
|
2010-10-28 14:10:37 +00:00
|
|
|
FGAIManager::ai_list_type sm_list(aiManager()->get_ai_list());
|
2015-05-20 18:25:37 +00:00
|
|
|
FGAIManager::ai_list_iterator sm_list_itr = sm_list.begin();
|
|
|
|
FGAIManager::ai_list_iterator end = sm_list.end();
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
for (; sm_list_itr != end; ++sm_list_itr) {
|
2010-08-28 23:00:09 +00:00
|
|
|
FGAIBase::object_type object_type =(*sm_list_itr)->getType();
|
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// Continue if object is not ballistic
|
|
|
|
if (object_type != FGAIBase::otBallistic) {
|
|
|
|
continue;
|
2010-08-28 23:00:09 +00:00
|
|
|
}
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
int parent_subID = (*sm_list_itr)->_getSubID();
|
2010-08-28 23:00:09 +00:00
|
|
|
int id = (*sm_list_itr)->getID();
|
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
if (parent_subID == 0 || id == -1) // this entry in the list has no associated submodel
|
2010-08-28 23:00:09 +00:00
|
|
|
continue; // or is invalid so we can continue
|
2010-08-01 09:47:40 +00:00
|
|
|
|
2011-12-11 12:55:56 +00:00
|
|
|
//SG_LOG(SG_AI, SG_DEBUG, "Submodel: Impact " << _impact << " hit! "
|
2009-01-18 21:56:55 +00:00
|
|
|
// << _hit <<" parent_subID " << parent_subID);
|
2010-08-01 09:47:40 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
_hit = (*sm_list_itr)->_getCollisionData();
|
|
|
|
_impact = (*sm_list_itr)->_getImpactData();
|
|
|
|
_expiry = (*sm_list_itr)->_getExpiryData();
|
|
|
|
|
2011-12-11 12:55:56 +00:00
|
|
|
//SG_LOG(SG_AI, SG_ALERT, "Submodel: " << (*sm_list_itr)->_getName()
|
2010-08-28 23:00:09 +00:00
|
|
|
// << " Impact " << _impact << " hit! " << _hit
|
|
|
|
// << " exipiry :-( " << _expiry );
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2010-07-16 22:05:05 +00:00
|
|
|
if (_impact || _hit || _expiry) {
|
2011-12-11 12:55:56 +00:00
|
|
|
// SG_LOG(SG_AI, SG_ALERT, "Submodel: Impact " << _impact << " hit! " << _hit
|
2010-08-14 12:39:30 +00:00
|
|
|
//<< " exipiry :-( " << _expiry );
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
submodel_iterator = submodels.begin();
|
|
|
|
|
|
|
|
while (submodel_iterator != submodels.end()) {
|
|
|
|
int child_ID = (*submodel_iterator)->id;
|
2007-06-24 07:57:45 +00:00
|
|
|
//cout << "Impact: parent SubID " << parent_subID << " child_ID " << child_ID << endl;
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
if ( parent_subID == child_ID ) {
|
|
|
|
_parent_lat = (*sm_list_itr)->_getImpactLat();
|
|
|
|
_parent_lon = (*sm_list_itr)->_getImpactLon();
|
|
|
|
_parent_elev = (*sm_list_itr)->_getImpactElevFt();
|
|
|
|
_parent_hdg = (*sm_list_itr)->_getImpactHdg();
|
|
|
|
_parent_pitch = (*sm_list_itr)->_getImpactPitch();
|
|
|
|
_parent_roll = (*sm_list_itr)->_getImpactRoll();
|
|
|
|
_parent_speed = (*sm_list_itr)->_getImpactSpeed();
|
|
|
|
(*submodel_iterator)->first_time = true;
|
2010-08-14 12:39:30 +00:00
|
|
|
//cout << "Impact: parent SubID = child_ID elev " << _parent_elev << endl;
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
if (release(*submodel_iterator, dt)) {
|
2007-06-07 16:30:26 +00:00
|
|
|
(*sm_list_itr)->setDie(true);
|
2010-08-28 23:00:09 +00:00
|
|
|
//cout << "Impact: set die" << (*sm_list_itr)->_getName() << endl;
|
|
|
|
}
|
2010-07-28 21:20:50 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
++submodel_iterator;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
_contrail_trigger->setBoolValue(_user_alt_node->getDoubleValue() > contrail_altitude);
|
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
bool trigger = false;
|
|
|
|
int i = -1;
|
|
|
|
|
|
|
|
submodel_iterator = submodels.begin();
|
2007-06-07 16:30:26 +00:00
|
|
|
while (submodel_iterator != submodels.end()) {
|
2007-03-30 22:51:52 +00:00
|
|
|
i++;
|
|
|
|
|
2011-12-11 12:55:56 +00:00
|
|
|
/*SG_LOG(SG_AI, SG_DEBUG,
|
2007-06-24 07:57:45 +00:00
|
|
|
"Submodels: " << (*submodel_iterator)->id
|
|
|
|
<< " name " << (*submodel_iterator)->name
|
2010-08-14 12:39:30 +00:00
|
|
|
);*/
|
2007-06-07 22:48:37 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
if ((*submodel_iterator)->trigger_node != 0) {
|
2007-06-07 16:30:26 +00:00
|
|
|
_trigger_node = (*submodel_iterator)->trigger_node;
|
|
|
|
trigger = _trigger_node->getBoolValue();
|
2010-07-28 21:20:50 +00:00
|
|
|
//cout << (*submodel_iterator)->name << "trigger node found " << trigger << endl;
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-08-28 23:00:09 +00:00
|
|
|
trigger = false;
|
|
|
|
//cout << (*submodel_iterator)->name << " trigger node not found " << trigger << endl;
|
2007-03-30 22:51:52 +00:00
|
|
|
}
|
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
if (trigger && (*submodel_iterator)->count != 0) {
|
2010-09-27 15:48:38 +00:00
|
|
|
//int id = (*submodel_iterator)->id;
|
2012-11-24 10:59:13 +00:00
|
|
|
//const string& name = (*submodel_iterator)->name;
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2011-12-11 12:55:56 +00:00
|
|
|
SG_LOG(SG_AI, SG_DEBUG,
|
2010-08-14 12:39:30 +00:00
|
|
|
"Submodels release: " << (*submodel_iterator)->id
|
|
|
|
<< " name " << (*submodel_iterator)->name
|
|
|
|
<< " count " << (*submodel_iterator)->count
|
2010-08-28 23:00:09 +00:00
|
|
|
<< " slaved " << (*submodel_iterator)->slaved
|
2010-08-14 12:39:30 +00:00
|
|
|
);
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
release(*submodel_iterator, dt);
|
|
|
|
} else
|
|
|
|
(*submodel_iterator)->first_time = true;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
++submodel_iterator;
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
}
|
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
bool FGSubmodelMgr::release(submodel *sm, double dt)
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
{
|
2015-05-20 18:25:37 +00:00
|
|
|
// Only run if first time or repeat is set to true
|
2007-06-07 22:48:37 +00:00
|
|
|
if (!sm->first_time && !sm->repeat) {
|
2007-03-30 22:51:52 +00:00
|
|
|
return false;
|
2007-06-07 16:30:26 +00:00
|
|
|
}
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
sm->timer += dt;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
if (sm->timer < sm->delay) {
|
2010-07-28 21:20:50 +00:00
|
|
|
//cout << "not yet: timer " << sm->timer << " delay " << sm->delay << endl;
|
2007-03-30 22:51:52 +00:00
|
|
|
return false;
|
2007-06-07 16:30:26 +00:00
|
|
|
}
|
2015-05-20 18:25:37 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
//cout << "released timer: " << sm->timer << " delay " << sm->delay << endl;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
sm->timer = 0.0;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
if (sm->first_time) {
|
2007-03-30 22:51:52 +00:00
|
|
|
dt = 0.0;
|
2007-06-07 22:48:37 +00:00
|
|
|
sm->first_time = false;
|
2007-03-30 22:51:52 +00:00
|
|
|
}
|
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// Calculate submodel's initial conditions in world-coordinates
|
|
|
|
transform(sm);
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
FGAIBallistic* ballist = new FGAIBallistic;
|
2007-06-07 22:48:37 +00:00
|
|
|
ballist->setPath(sm->model.c_str());
|
2010-07-28 21:20:50 +00:00
|
|
|
ballist->setName(sm->name);
|
2010-08-28 23:00:09 +00:00
|
|
|
ballist->setSlaved(sm->slaved);
|
2010-08-14 12:39:30 +00:00
|
|
|
ballist->setRandom(sm->random);
|
2015-05-21 20:45:15 +00:00
|
|
|
ballist->setLifeRandomness(sm->life_randomness->get_value());
|
2010-08-14 12:39:30 +00:00
|
|
|
ballist->setLatitude(offsetpos.getLatitudeDeg());
|
|
|
|
ballist->setLongitude(offsetpos.getLongitudeDeg());
|
|
|
|
ballist->setAltitude(offsetpos.getElevationFt());
|
2015-05-21 20:45:15 +00:00
|
|
|
ballist->setAzimuthRandomError(sm->azimuth_error->get_value());
|
2007-03-30 22:51:52 +00:00
|
|
|
ballist->setAzimuth(IC.azimuth);
|
2015-05-21 20:45:15 +00:00
|
|
|
ballist->setElevationRandomError(sm->elevation_error->get_value());
|
2007-03-30 22:51:52 +00:00
|
|
|
ballist->setElevation(IC.elevation);
|
|
|
|
ballist->setRoll(IC.roll);
|
|
|
|
ballist->setSpeed(IC.speed / SG_KT_TO_FPS);
|
|
|
|
ballist->setWind_from_east(IC.wind_from_east);
|
|
|
|
ballist->setWind_from_north(IC.wind_from_north);
|
|
|
|
ballist->setMass(IC.mass);
|
2007-06-07 22:48:37 +00:00
|
|
|
ballist->setDragArea(sm->drag_area);
|
|
|
|
ballist->setLife(sm->life);
|
|
|
|
ballist->setBuoyancy(sm->buoyancy);
|
|
|
|
ballist->setWind(sm->wind);
|
2015-05-21 20:45:15 +00:00
|
|
|
ballist->setCdRandomness(sm->cd_randomness->get_value());
|
2007-06-07 22:48:37 +00:00
|
|
|
ballist->setCd(sm->cd);
|
|
|
|
ballist->setStabilisation(sm->aero_stabilised);
|
|
|
|
ballist->setNoRoll(sm->no_roll);
|
|
|
|
ballist->setCollision(sm->collision);
|
2010-08-14 12:39:30 +00:00
|
|
|
ballist->setExpiry(sm->expiry);
|
2007-06-07 22:48:37 +00:00
|
|
|
ballist->setImpact(sm->impact);
|
|
|
|
ballist->setImpactReportNode(sm->impact_report);
|
|
|
|
ballist->setFuseRange(sm->fuse_range);
|
|
|
|
ballist->setSubmodel(sm->submodel.c_str());
|
|
|
|
ballist->setSubID(sm->sub_id);
|
2009-01-18 21:56:55 +00:00
|
|
|
ballist->setForceStabilisation(sm->force_stabilised);
|
2007-12-21 23:37:05 +00:00
|
|
|
ballist->setExternalForce(sm->ext_force);
|
|
|
|
ballist->setForcePath(sm->force_path.c_str());
|
2015-05-23 08:41:22 +00:00
|
|
|
ballist->setXoffset(_x_offset);
|
|
|
|
ballist->setYoffset(_y_offset);
|
|
|
|
ballist->setZoffset(_z_offset);
|
2015-04-30 12:54:36 +00:00
|
|
|
ballist->setPitchoffset(sm->pitch_offset->get_value());
|
|
|
|
ballist->setYawoffset(sm->yaw_offset->get_value());
|
2010-09-08 17:09:03 +00:00
|
|
|
ballist->setParentNodes(_selected_ac);
|
2010-08-28 23:00:09 +00:00
|
|
|
ballist->setContentsNode(sm->contents_node);
|
|
|
|
ballist->setWeight(sm->weight);
|
2015-05-20 18:25:37 +00:00
|
|
|
|
2010-10-28 14:10:37 +00:00
|
|
|
aiManager()->attach(ballist);
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
if (sm->count > 0)
|
|
|
|
sm->count--;
|
2007-03-30 22:51:52 +00:00
|
|
|
return true;
|
David Culp:
Right now the code is not very configurable, and there is only one submodel per airplane possible. It is implemented as an SGSubSystem, just like the electrics, vacuum, etc. systems. To make it work you need to make a release binding like this (for my joystick trigger):
<button n="0">
<desc>Trigger</desc>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">true</value>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/systems/submodel/trigger</property>
<value type="bool">false</value>
</binding>
</mod-up>
</button>
Then, each airplane that uses the system should have something like this added to its *-set.xml file (note that this does *not* go within the <sim></sim> tags):
<systems>
<submodel>
<serviceable type="bool">true</serviceable>
<amount type="int">70</amount>
</submodel>
</systems>
Future improvements will include:
1) more configurability, so the user can create multiple submodels, and can assign them different locations, and pitch and yaw adjustments, and nitial velocity.
2) sound?
3) a more accurate calculation of the submodels location at any pitch/roll/yaw.
4) a way to pre-load the model, so the AI code doesn't have to parse the model every time it creates an instance.
I think that's all of it.
2004-08-22 16:22:18 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
void FGSubmodelMgr::load()
|
2004-08-26 08:38:43 +00:00
|
|
|
{
|
2015-05-20 18:25:37 +00:00
|
|
|
SGPropertyNode_ptr path_node = fgGetNode("/sim/submodels/path");
|
2004-08-26 08:38:43 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
if (path_node) {
|
2007-06-10 18:24:48 +00:00
|
|
|
const int id = 0;
|
2015-05-20 18:25:37 +00:00
|
|
|
const string& path = path_node->getStringValue();
|
|
|
|
bool serviceable =_serviceable_node->getBoolValue();
|
|
|
|
setData(id, path, serviceable, "/ai/submodels/submodel", submodels);
|
2007-03-30 22:51:52 +00:00
|
|
|
}
|
|
|
|
}
|
2004-08-26 12:27:39 +00:00
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
void FGSubmodelMgr::transform(submodel *sm)
|
2004-08-26 08:38:43 +00:00
|
|
|
{
|
2015-05-20 18:25:37 +00:00
|
|
|
// Set initial conditions
|
2010-08-28 23:00:09 +00:00
|
|
|
if (sm->contents_node != 0 && !sm->slaved) {
|
2015-05-20 18:25:37 +00:00
|
|
|
// Get the weight of the contents (lbs) and convert to mass (slugs)
|
2007-12-21 23:37:05 +00:00
|
|
|
sm->contents = sm->contents_node->getChild("level-lbs",0,1)->getDoubleValue();
|
|
|
|
//cout << "transform: contents " << sm->contents << endl;
|
2007-06-07 22:48:37 +00:00
|
|
|
IC.mass = (sm->weight + sm->contents) * lbs_to_slugs;
|
2007-12-21 23:37:05 +00:00
|
|
|
//cout << "mass inc contents" << IC.mass << endl;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// Set contents to 0 in the parent
|
2007-12-21 23:37:05 +00:00
|
|
|
sm->contents_node->getChild("level-gal_us",0,1)->setDoubleValue(0);
|
|
|
|
/*cout << "contents " << sm->contents_node->getChild("level-gal_us")->getDoubleValue()
|
|
|
|
<< " " << sm->contents_node->getChild("level-lbs",0,1)->getDoubleValue()
|
|
|
|
<< endl;*/
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
|
|
|
else {
|
2007-06-07 22:48:37 +00:00
|
|
|
IC.mass = sm->weight * lbs_to_slugs;
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
int id = sm->id;
|
2010-09-27 15:48:38 +00:00
|
|
|
//int sub_id = sm->sub_id;
|
2012-11-24 10:59:13 +00:00
|
|
|
//const string& name = sm->name;
|
2010-08-28 23:00:09 +00:00
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
if (sm->speed_node != 0)
|
|
|
|
sm->speed = sm->speed_node->getDoubleValue();
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
// set the Initial Conditions for the types of submodel parent
|
2010-07-28 21:20:50 +00:00
|
|
|
|
|
|
|
if (_impact || _hit || _expiry) {
|
2007-06-07 16:30:26 +00:00
|
|
|
_count++;
|
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// Set the data for a submodel tied to a submodel
|
2007-06-07 16:30:26 +00:00
|
|
|
IC.lat = _parent_lat;
|
|
|
|
IC.lon = _parent_lon;
|
|
|
|
IC.alt = _parent_elev;
|
|
|
|
IC.roll = _parent_roll; // rotation about x axis
|
|
|
|
IC.elevation = _parent_pitch; // rotation about y axis
|
2007-06-07 22:48:37 +00:00
|
|
|
IC.azimuth = _parent_hdg; // rotation about z axis
|
2007-06-07 16:30:26 +00:00
|
|
|
IC.speed = _parent_speed;
|
|
|
|
IC.speed_down_fps = 0;
|
|
|
|
IC.speed_east_fps = 0;
|
|
|
|
IC.speed_north_fps = 0;
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
|
|
|
else if (id == 0) {
|
|
|
|
// Set the data for a submodel tied to the main model
|
2007-04-27 11:02:39 +00:00
|
|
|
IC.lat = _user_lat_node->getDoubleValue();
|
|
|
|
IC.lon = _user_lon_node->getDoubleValue();
|
|
|
|
IC.alt = _user_alt_node->getDoubleValue();
|
|
|
|
IC.roll = _user_roll_node->getDoubleValue(); // rotation about x axis
|
|
|
|
IC.elevation = _user_pitch_node->getDoubleValue(); // rotation about y axis
|
|
|
|
IC.azimuth = _user_heading_node->getDoubleValue(); // rotation about z axis
|
|
|
|
IC.speed = _user_speed_node->getDoubleValue();
|
|
|
|
IC.speed_down_fps = _user_speed_down_fps_node->getDoubleValue();
|
|
|
|
IC.speed_east_fps = _user_speed_east_fps_node->getDoubleValue();
|
|
|
|
IC.speed_north_fps = _user_speed_north_fps_node->getDoubleValue();
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Set the data for a submodel tied to an AI Object
|
2010-08-28 23:00:09 +00:00
|
|
|
setParentNode(id);
|
2007-03-30 22:51:52 +00:00
|
|
|
}
|
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
// Set the Initial Conditions that are common to all types of parent
|
2007-03-30 22:51:52 +00:00
|
|
|
IC.wind_from_east = _user_wind_from_east_node->getDoubleValue();
|
|
|
|
IC.wind_from_north = _user_wind_from_north_node->getDoubleValue();
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
userpos.setLatitudeDeg(IC.lat);
|
|
|
|
userpos.setLongitudeDeg(IC.lon);
|
|
|
|
userpos.setElevationFt(IC.alt);
|
2010-07-28 21:20:50 +00:00
|
|
|
|
2015-05-23 08:41:22 +00:00
|
|
|
if (sm->offsets_in_meter) {
|
|
|
|
_x_offset = -sm->x_offset->get_value() * SG_METER_TO_FEET;
|
|
|
|
_y_offset = sm->y_offset->get_value() * SG_METER_TO_FEET;
|
|
|
|
_z_offset = sm->z_offset->get_value() * SG_METER_TO_FEET;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
_x_offset = sm->x_offset->get_value();
|
|
|
|
_y_offset = sm->y_offset->get_value();
|
|
|
|
_z_offset = sm->z_offset->get_value();
|
|
|
|
}
|
2010-07-28 21:20:50 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
setOffsetPos();
|
2010-07-28 21:20:50 +00:00
|
|
|
|
2015-05-23 04:58:53 +00:00
|
|
|
// Compute initial orientation using yaw and pitch offsets and parent's orientation
|
|
|
|
const double yaw_offset = sm->yaw_offset->get_value();
|
|
|
|
const double pitch_offset = sm->pitch_offset->get_value();
|
2015-05-22 03:09:02 +00:00
|
|
|
|
|
|
|
SGQuatd ic_quat = SGQuatd::fromYawPitchRollDeg(IC.azimuth, IC.elevation, IC.roll);
|
|
|
|
ic_quat *= SGQuatd::fromYawPitchRollDeg(yaw_offset, pitch_offset, 0.0);
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2015-05-23 04:58:53 +00:00
|
|
|
// Calculate total speed using speeds of submodel and parent
|
|
|
|
SGVec3d total_speed = SGVec3d(IC.speed_north_fps, IC.speed_east_fps, IC.speed_down_fps);
|
|
|
|
total_speed += ic_quat.rotate(SGVec3d(sm->speed, 0, 0));
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2015-05-23 04:58:53 +00:00
|
|
|
IC.speed = length(total_speed);
|
2015-05-22 03:09:02 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// If speeds are low this calculation can become unreliable
|
2007-06-07 22:48:37 +00:00
|
|
|
if (IC.speed > 1) {
|
2015-05-23 04:58:53 +00:00
|
|
|
const double total_speed_north = total_speed.x();
|
|
|
|
const double total_speed_east = total_speed.y();
|
|
|
|
const double total_speed_down = total_speed.z();
|
|
|
|
|
|
|
|
IC.azimuth = atan2(total_speed_east, total_speed_north) * SG_RADIANS_TO_DEGREES;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// Rationalize the output
|
2007-06-07 16:30:26 +00:00
|
|
|
if (IC.azimuth < 0)
|
|
|
|
IC.azimuth += 360;
|
|
|
|
else if (IC.azimuth >= 360)
|
|
|
|
IC.azimuth -= 360;
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2015-05-23 04:58:53 +00:00
|
|
|
IC.elevation = -atan(total_speed_down / sqrt(total_speed_north
|
|
|
|
* total_speed_north + total_speed_east * total_speed_east))
|
2007-06-24 07:57:45 +00:00
|
|
|
* SG_RADIANS_TO_DEGREES;
|
2007-08-01 10:44:17 +00:00
|
|
|
}
|
2015-05-23 04:58:53 +00:00
|
|
|
else {
|
|
|
|
double ic_roll;
|
|
|
|
ic_quat.getEulerDeg(IC.azimuth, IC.elevation, ic_roll);
|
|
|
|
}
|
2004-09-07 19:10:10 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
void FGSubmodelMgr::updatelat(double lat)
|
2004-09-07 19:10:10 +00:00
|
|
|
{
|
2007-03-30 22:51:52 +00:00
|
|
|
ft_per_deg_latitude = 366468.96 - 3717.12 * cos(lat / SG_RADIANS_TO_DEGREES);
|
|
|
|
ft_per_deg_longitude = 365228.16 * cos(lat / SG_RADIANS_TO_DEGREES);
|
2004-09-05 09:45:34 +00:00
|
|
|
}
|
2004-08-26 12:27:39 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
void FGSubmodelMgr::loadAI()
|
|
|
|
{
|
2015-05-20 18:25:37 +00:00
|
|
|
SG_LOG(SG_AI, SG_DEBUG, "Submodels: Loading AI submodels");
|
2007-05-12 10:39:56 +00:00
|
|
|
|
2010-10-28 14:10:37 +00:00
|
|
|
FGAIManager::ai_list_type sm_list(aiManager()->get_ai_list());
|
2004-09-01 21:05:04 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
if (sm_list.empty()) {
|
2011-12-11 12:55:56 +00:00
|
|
|
SG_LOG(SG_AI, SG_ALERT, "Submodels: Unable to read AI submodel list");
|
2007-03-30 22:51:52 +00:00
|
|
|
return;
|
|
|
|
}
|
2004-09-14 08:27:55 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
FGAIManager::ai_list_iterator sm_list_itr = sm_list.begin();
|
|
|
|
FGAIManager::ai_list_iterator end = sm_list.end();
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
while (sm_list_itr != end) {
|
2007-07-15 14:08:31 +00:00
|
|
|
string path = (*sm_list_itr)->_getSMPath();
|
2007-04-27 11:02:39 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
if (path.empty()) {
|
|
|
|
++sm_list_itr;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int id = (*sm_list_itr)->getID();
|
2007-05-12 10:39:56 +00:00
|
|
|
bool serviceable = (*sm_list_itr)->_getServiceable();
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2012-11-24 10:59:13 +00:00
|
|
|
//string type = (*sm_list_itr)->getTypeString();
|
2010-08-14 12:39:30 +00:00
|
|
|
//cout << "loadAI: type " << type << " path "<< path << " serviceable " << serviceable << endl;
|
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
setData(id, path, serviceable, "/ai/submodels/submodel", submodels);
|
2007-03-30 22:51:52 +00:00
|
|
|
++sm_list_itr;
|
|
|
|
}
|
|
|
|
}
|
2004-09-27 14:24:20 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
void FGSubmodelMgr::setData(int id, const string& path, bool serviceable, const string& property_path, submodel_vector_type& models)
|
2007-05-12 10:39:56 +00:00
|
|
|
{
|
|
|
|
SGPropertyNode root;
|
|
|
|
|
2010-09-06 08:12:25 +00:00
|
|
|
SGPath config = globals->resolve_aircraft_path(path);
|
2007-05-12 10:39:56 +00:00
|
|
|
try {
|
2011-12-11 12:55:56 +00:00
|
|
|
SG_LOG(SG_AI, SG_DEBUG,
|
2007-06-24 07:57:45 +00:00
|
|
|
"Submodels: Trying to read AI submodels file: " << config.str());
|
2007-05-12 10:39:56 +00:00
|
|
|
readProperties(config.str(), &root);
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
|
|
|
catch (const sg_exception &) {
|
2011-12-11 12:55:56 +00:00
|
|
|
SG_LOG(SG_AI, SG_ALERT,
|
2007-06-24 07:57:45 +00:00
|
|
|
"Submodels: Unable to read AI submodels file: " << config.str());
|
2007-05-12 10:39:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vector<SGPropertyNode_ptr> children = root.getChildren("submodel");
|
|
|
|
vector<SGPropertyNode_ptr>::iterator it = children.begin();
|
|
|
|
vector<SGPropertyNode_ptr>::iterator end = children.end();
|
|
|
|
|
|
|
|
for (int i = 0; it != end; ++it, i++) {
|
|
|
|
//cout << "Reading AI submodel " << (*it)->getPath() << endl;
|
2015-05-20 18:25:37 +00:00
|
|
|
submodel *sm = new submodel;
|
|
|
|
SGPropertyNode_ptr entry_node = *it;
|
|
|
|
sm->name = entry_node->getStringValue("name", "none_defined");
|
|
|
|
sm->model = entry_node->getStringValue("model", "Models/Geometry/rocket.ac");
|
|
|
|
sm->speed = entry_node->getDoubleValue("speed", 2329.4);
|
|
|
|
sm->repeat = entry_node->getBoolValue("repeat", false);
|
|
|
|
sm->delay = entry_node->getDoubleValue("delay", 0.25);
|
|
|
|
sm->count = entry_node->getIntValue("count", 1);
|
|
|
|
sm->slaved = entry_node->getBoolValue("slaved", false);
|
|
|
|
sm->drag_area = entry_node->getDoubleValue("eda", 0.034);
|
|
|
|
sm->life = entry_node->getDoubleValue("life", 900.0);
|
|
|
|
sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
|
|
|
|
sm->wind = entry_node->getBoolValue("wind", false);
|
|
|
|
sm->cd = entry_node->getDoubleValue("cd", 0.193);
|
|
|
|
sm->weight = entry_node->getDoubleValue("weight", 0.25);
|
|
|
|
sm->aero_stabilised = entry_node->getBoolValue("aero-stabilised", true);
|
|
|
|
sm->no_roll = entry_node->getBoolValue("no-roll", false);
|
|
|
|
sm->collision = entry_node->getBoolValue("collision", false);
|
|
|
|
sm->expiry = entry_node->getBoolValue("expiry", false);
|
|
|
|
sm->impact = entry_node->getBoolValue("impact", false);
|
|
|
|
sm->impact_report = entry_node->getStringValue("impact-reports");
|
|
|
|
sm->fuse_range = entry_node->getDoubleValue("fuse-range", 0.0);
|
|
|
|
sm->contents_node = fgGetNode(entry_node->getStringValue("contents", "none"), false);
|
|
|
|
sm->speed_node = fgGetNode(entry_node->getStringValue("speed-prop", "none"), false);
|
|
|
|
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->force_path = entry_node->getStringValue("force-path", "");
|
|
|
|
sm->random = entry_node->getBoolValue("random", false);
|
2010-07-28 21:20:50 +00:00
|
|
|
|
2015-04-25 10:33:34 +00:00
|
|
|
SGPropertyNode_ptr prop_root = fgGetNode("/", true);
|
2015-04-30 09:39:00 +00:00
|
|
|
SGPropertyNode n;
|
2015-05-23 08:41:22 +00:00
|
|
|
SGPropertyNode_ptr a, b;
|
2015-04-30 09:39:00 +00:00
|
|
|
|
2015-05-23 08:41:22 +00:00
|
|
|
// Offsets
|
|
|
|
a = entry_node->getNode("offsets", false);
|
|
|
|
sm->offsets_in_meter = (a != 0);
|
|
|
|
|
|
|
|
if (a) {
|
|
|
|
b = a->getNode("x-m");
|
|
|
|
sm->x_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
|
|
|
|
|
|
|
b = a->getNode("y-m");
|
|
|
|
sm->y_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
|
|
|
|
|
|
|
b = a->getNode("z-m");
|
|
|
|
sm->z_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
2015-05-24 03:37:42 +00:00
|
|
|
|
2015-05-28 21:40:58 +00:00
|
|
|
b = a->getNode("heading-deg");
|
2015-05-24 03:37:42 +00:00
|
|
|
sm->yaw_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
|
|
|
|
2015-05-28 21:40:58 +00:00
|
|
|
b = a->getNode("pitch-deg");
|
2015-05-24 03:37:42 +00:00
|
|
|
sm->pitch_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
2015-05-23 08:41:22 +00:00
|
|
|
}
|
|
|
|
else {
|
2015-05-24 03:37:42 +00:00
|
|
|
SG_LOG(SG_AI, SG_WARN, "Submodels: <*-offset> is deprecated. Use <offsets> instead");
|
|
|
|
|
2015-05-23 08:41:22 +00:00
|
|
|
b = entry_node->getNode("x-offset");
|
|
|
|
sm->x_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
|
|
|
|
|
|
|
b = entry_node->getNode("y-offset");
|
|
|
|
sm->y_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
|
|
|
|
|
|
|
b = entry_node->getNode("z-offset");
|
|
|
|
sm->z_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
2015-05-24 03:37:42 +00:00
|
|
|
|
|
|
|
b = entry_node->getNode("yaw-offset");
|
|
|
|
sm->yaw_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
|
|
|
|
|
|
|
b = entry_node->getNode("pitch-offset");
|
|
|
|
sm->pitch_offset = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
2015-05-23 08:41:22 +00:00
|
|
|
}
|
|
|
|
|
2015-05-21 20:45:15 +00:00
|
|
|
// Randomness
|
|
|
|
a = entry_node->getNode("randomness", true);
|
|
|
|
|
|
|
|
// Maximum azimuth randomness error in degrees
|
|
|
|
b = a->getNode("azimuth");
|
|
|
|
sm->azimuth_error = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
|
|
|
|
|
|
|
// Maximum elevation randomness error in degrees
|
|
|
|
b = a->getNode("elevation");
|
|
|
|
sm->elevation_error = new FGXMLAutopilot::InputValue(*prop_root, b ? *b : n);
|
|
|
|
|
|
|
|
// Randomness of Cd (plus or minus)
|
|
|
|
b = a->getNode("cd");
|
|
|
|
if (!b) {
|
|
|
|
b = a->getNode("cd", true);
|
|
|
|
b->setDoubleValue(0.1);
|
|
|
|
}
|
|
|
|
sm->cd_randomness = new FGXMLAutopilot::InputValue(*prop_root, *b);
|
|
|
|
|
|
|
|
// Randomness of life (plus or minus)
|
|
|
|
b = a->getNode("life");
|
|
|
|
if (!b) {
|
|
|
|
b = a->getNode("life", true);
|
|
|
|
b->setDoubleValue(0.5);
|
|
|
|
}
|
|
|
|
sm->life_randomness = new FGXMLAutopilot::InputValue(*prop_root, *b);
|
2015-04-25 10:33:34 +00:00
|
|
|
|
2007-05-12 10:39:56 +00:00
|
|
|
if (sm->contents_node != 0)
|
|
|
|
sm->contents = sm->contents_node->getDoubleValue();
|
|
|
|
|
|
|
|
const char *trigger_path = entry_node->getStringValue("trigger", 0);
|
|
|
|
if (trigger_path) {
|
|
|
|
sm->trigger_node = fgGetNode(trigger_path, true);
|
|
|
|
sm->trigger_node->setBoolValue(sm->trigger_node->getBoolValue());
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
|
|
|
else {
|
2007-05-12 10:39:56 +00:00
|
|
|
sm->trigger_node = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sm->speed_node != 0)
|
|
|
|
sm->speed = sm->speed_node->getDoubleValue();
|
|
|
|
|
|
|
|
sm->timer = sm->delay;
|
|
|
|
sm->id = id;
|
|
|
|
sm->first_time = false;
|
|
|
|
sm->serviceable = serviceable;
|
2007-06-07 16:30:26 +00:00
|
|
|
sm->sub_id = 0;
|
2007-05-12 10:39:56 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
sm->prop = fgGetNode(property_path, index, true);
|
2010-08-14 12:39:30 +00:00
|
|
|
sm->prop->tie("delay", SGRawValuePointer<double>(&(sm->delay)));
|
2007-05-12 10:39:56 +00:00
|
|
|
sm->prop->tie("count", SGRawValuePointer<int>(&(sm->count)));
|
|
|
|
sm->prop->tie("repeat", SGRawValuePointer<bool>(&(sm->repeat)));
|
|
|
|
sm->prop->tie("id", SGRawValuePointer<int>(&(sm->id)));
|
2007-06-07 16:30:26 +00:00
|
|
|
sm->prop->tie("sub-id", SGRawValuePointer<int>(&(sm->sub_id)));
|
2007-05-12 10:39:56 +00:00
|
|
|
sm->prop->tie("serviceable", SGRawValuePointer<bool>(&(sm->serviceable)));
|
2010-07-28 21:20:50 +00:00
|
|
|
sm->prop->tie("random", SGRawValuePointer<bool>(&(sm->random)));
|
2010-08-28 23:00:09 +00:00
|
|
|
sm->prop->tie("slaved", SGRawValuePointer<bool>(&(sm->slaved)));
|
2012-11-24 10:59:13 +00:00
|
|
|
const string& name = sm->name;
|
2007-05-12 10:39:56 +00:00
|
|
|
sm->prop->setStringValue("name", name.c_str());
|
|
|
|
|
2012-11-24 10:59:13 +00:00
|
|
|
const string& submodel = sm->submodel;
|
2007-06-07 16:30:26 +00:00
|
|
|
sm->prop->setStringValue("submodel", submodel.c_str());
|
|
|
|
|
2012-11-24 10:59:13 +00:00
|
|
|
const string& force_path = sm->force_path;
|
2007-12-21 23:37:05 +00:00
|
|
|
sm->prop->setStringValue("force_path", force_path.c_str());
|
|
|
|
|
2007-05-12 10:39:56 +00:00
|
|
|
if (sm->contents_node != 0)
|
|
|
|
sm->prop->tie("contents-lbs", SGRawValuePointer<double>(&(sm->contents)));
|
|
|
|
|
|
|
|
index++;
|
2015-05-20 18:25:37 +00:00
|
|
|
models.push_back(sm);
|
2007-06-07 16:30:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGSubmodelMgr::loadSubmodels()
|
|
|
|
{
|
2011-12-11 12:55:56 +00:00
|
|
|
SG_LOG(SG_AI, SG_DEBUG, "Submodels: Loading sub submodels");
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
_found_sub = false;
|
2007-05-12 10:39:56 +00:00
|
|
|
|
2010-07-16 22:05:05 +00:00
|
|
|
submodel_iterator = submodels.begin();
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
while (submodel_iterator != submodels.end()) {
|
2012-11-24 10:59:13 +00:00
|
|
|
const string& submodel = (*submodel_iterator)->submodel;
|
2010-08-14 12:39:30 +00:00
|
|
|
if (!submodel.empty()) {
|
|
|
|
//int id = (*submodel_iterator)->id;
|
|
|
|
bool serviceable = true;
|
2011-12-11 12:55:56 +00:00
|
|
|
SG_LOG(SG_AI, SG_DEBUG, "found path sub sub "
|
2010-08-28 23:00:09 +00:00
|
|
|
<< submodel
|
|
|
|
<< " index " << index
|
|
|
|
<< " name " << (*submodel_iterator)->name);
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
if ((*submodel_iterator)->sub_id == 0) {
|
2010-08-14 12:39:30 +00:00
|
|
|
(*submodel_iterator)->sub_id = index;
|
|
|
|
_found_sub = true;
|
2015-05-20 18:25:37 +00:00
|
|
|
setData(index, submodel, serviceable, "/ai/submodels/subsubmodel", subsubmodels);
|
2010-08-14 12:39:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++submodel_iterator;
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
submodels.reserve(submodels.size() + subsubmodels.size());
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// Add all elements from subsubmodels to submodels
|
|
|
|
subsubmodel_iterator = subsubmodels.begin();
|
2007-06-07 16:30:26 +00:00
|
|
|
while (subsubmodel_iterator != subsubmodels.end()) {
|
|
|
|
submodels.push_back(*subsubmodel_iterator);
|
|
|
|
++subsubmodel_iterator;
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
2010-07-16 22:05:05 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
subsubmodels.clear();
|
2007-05-12 10:39:56 +00:00
|
|
|
}
|
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
SGVec3d FGSubmodelMgr::getCartOffsetPos() const
|
|
|
|
{
|
|
|
|
// Convert geodetic positions to geocentered
|
2010-07-28 21:20:50 +00:00
|
|
|
SGVec3d cartuserPos = SGVec3d::fromGeod(userpos);
|
2015-05-20 18:25:37 +00:00
|
|
|
|
2010-07-28 21:20:50 +00:00
|
|
|
// 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) )
|
2010-08-14 12:39:30 +00:00
|
|
|
SGVec3d _off(_x_offset * SG_FEET_TO_METER,
|
2010-07-28 21:20:50 +00:00
|
|
|
_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);
|
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// And postrotate the orientation of the user model wrt the horizontal
|
2010-07-28 21:20:50 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
void FGSubmodelMgr::setOffsetPos()
|
|
|
|
{
|
|
|
|
// Convert the offset geocentered position to geodetic
|
2010-07-28 21:20:50 +00:00
|
|
|
SGVec3d cartoffsetPos = getCartOffsetPos();
|
|
|
|
SGGeodesy::SGCartToGeod(cartoffsetPos, offsetpos);
|
2010-08-14 12:39:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FGSubmodelMgr::valueChanged(SGPropertyNode *prop)
|
|
|
|
{
|
2010-09-08 17:09:03 +00:00
|
|
|
return; // this isn't working atm
|
2010-08-14 12:39:30 +00:00
|
|
|
|
|
|
|
const char* _model_added = _model_added_node->getStringValue();
|
|
|
|
|
2012-11-23 20:00:20 +00:00
|
|
|
std::basic_string <char>::size_type indexCh2b;
|
2010-08-14 12:39:30 +00:00
|
|
|
|
|
|
|
string str2 = _model_added;
|
2010-09-08 17:09:03 +00:00
|
|
|
const char *cstr2b = "multiplayer";
|
2015-05-20 18:25:37 +00:00
|
|
|
indexCh2b = str2.find(cstr2b, 0);
|
2010-09-08 17:09:03 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
// Ignoring Ballistic Objects; there are potentially too many
|
|
|
|
if (indexCh2b != string::npos ) {
|
2010-09-08 17:09:03 +00:00
|
|
|
//cout << "Submodels: model added - " << str2 <<" read path "<< endl;
|
|
|
|
//return;
|
|
|
|
SGPropertyNode *a_node = fgGetNode(_model_added, true);
|
|
|
|
SGPropertyNode *sub_node = a_node->getChild("sim", 0, true);
|
2010-08-14 12:39:30 +00:00
|
|
|
SGPropertyNode_ptr path_node = sub_node->getChild("path", 0, true);
|
2010-09-08 17:09:03 +00:00
|
|
|
SGPropertyNode_ptr callsign_node = a_node->getChild("callsign", 0, true);
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2012-11-24 10:59:13 +00:00
|
|
|
//const string& callsign = callsign_node->getStringValue();
|
2010-09-08 17:09:03 +00:00
|
|
|
//cout << "Submodels: model added - " << callsign <<" read callsign "<< endl;
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
cout << "model added - " << str2 <<" returning " << endl;
|
|
|
|
}
|
2010-08-28 23:00:09 +00:00
|
|
|
}
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
void FGSubmodelMgr::setParentNode(int id)
|
|
|
|
{
|
2010-08-28 23:00:09 +00:00
|
|
|
const SGPropertyNode_ptr ai = fgGetNode("/ai/models", true);
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
for (int i = ai->nChildren() - 1; i >= -1; i--) {
|
|
|
|
SGPropertyNode_ptr model;
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
if (i < 0) {
|
|
|
|
// Last iteration: selected model
|
2010-08-28 23:00:09 +00:00
|
|
|
model = _selected_ac;
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-08-28 23:00:09 +00:00
|
|
|
model = ai->getChild(i);
|
|
|
|
int parent_id = model->getIntValue("id");
|
2015-05-20 18:25:37 +00:00
|
|
|
if (!model->nChildren()) {
|
2010-08-28 23:00:09 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (parent_id == id) {
|
2015-05-20 18:25:37 +00:00
|
|
|
// Save selected model for last iteration
|
|
|
|
_selected_ac = model;
|
2010-08-28 23:00:09 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!model)
|
|
|
|
continue;
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2015-05-20 18:25:37 +00:00
|
|
|
if (_selected_ac != 0) {
|
2010-08-28 23:00:09 +00:00
|
|
|
const string name = _selected_ac->getStringValue("name");
|
|
|
|
IC.lat = _selected_ac->getDoubleValue("position/latitude-deg");
|
|
|
|
IC.lon = _selected_ac->getDoubleValue("position/longitude-deg");
|
|
|
|
IC.alt = _selected_ac->getDoubleValue("position/altitude-ft");
|
|
|
|
IC.roll = _selected_ac->getDoubleValue("orientation/roll-deg");
|
|
|
|
IC.elevation = _selected_ac->getDoubleValue("orientation/pitch-deg");
|
|
|
|
IC.azimuth = _selected_ac->getDoubleValue("orientation/true-heading-deg");
|
|
|
|
IC.speed = _selected_ac->getDoubleValue("velocities/true-airspeed-kt") * SG_KT_TO_FPS;
|
|
|
|
IC.speed_down_fps = -_selected_ac->getDoubleValue("velocities/vertical-speed-fps");
|
|
|
|
IC.speed_east_fps = _selected_ac->getDoubleValue("velocities/speed-east-fps");
|
|
|
|
IC.speed_north_fps = _selected_ac->getDoubleValue("velocities/speed-north-fps");
|
2015-05-20 18:25:37 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-12-11 12:55:56 +00:00
|
|
|
SG_LOG(SG_AI, SG_ALERT, "AISubmodel: parent node not found ");
|
2010-08-28 23:00:09 +00:00
|
|
|
}
|
2010-07-28 21:20:50 +00:00
|
|
|
}
|