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
|
|
|
|
|
|
|
|
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;
|
2007-03-30 22:51:52 +00:00
|
|
|
string contents_node;
|
|
|
|
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);
|
|
|
|
_user_pitch_node = fgGetNode("/orientation/pitch-deg", true);
|
|
|
|
_user_roll_node = fgGetNode("/orientation/roll-deg", true);
|
|
|
|
_user_yaw_node = fgGetNode("/orientation/yaw-deg", true);
|
2004-09-09 08:40:08 +00:00
|
|
|
_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();
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2007-04-27 11:02:39 +00:00
|
|
|
}
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2007-04-27 11:02:39 +00:00
|
|
|
void FGSubmodelMgr::postinit() {
|
|
|
|
// postinit, so that the AI list is populated
|
2010-08-28 23:00:09 +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()
|
|
|
|
{}
|
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
|
|
|
|
2007-06-07 22:48: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());
|
|
|
|
FGAIManager::ai_list_iterator sm_list_itr = sm_list.begin(),
|
|
|
|
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();
|
|
|
|
|
|
|
|
if (object_type != FGAIBase::otBallistic){// only work on ballistic objects
|
|
|
|
continue; // so continue
|
|
|
|
}
|
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();
|
|
|
|
|
|
|
|
if ( parent_subID == 0 || id == -1) // this entry in the list has no associated submodel
|
|
|
|
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
|
|
|
|
2010-08-28 23:00:09 +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-04-27 11:02:39 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
// bool in_range = true;
|
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;
|
2007-03-30 22:51:52 +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) {
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2010-09-27 15:48:38 +00:00
|
|
|
//int id = (*submodel_iterator)->id;
|
2010-08-14 12:39:30 +00:00
|
|
|
string name = (*submodel_iterator)->name;
|
|
|
|
|
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;
|
|
|
|
} // end while
|
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
|
|
|
{
|
2010-08-28 23:00:09 +00:00
|
|
|
//cout << "release id " << sm->id
|
|
|
|
// << " name " << sm->name
|
|
|
|
// << " first time " << sm->first_time
|
|
|
|
// << " repeat " << sm->repeat
|
|
|
|
// << " slaved " << sm->slaved
|
|
|
|
// << endl;
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2007-03-30 22:51:52 +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) {
|
2010-08-28 23:00:09 +00:00
|
|
|
//cout<< "returning: "<< sm->name
|
|
|
|
// << " not first time " << sm->first_time
|
|
|
|
// << " repeat " << sm->repeat
|
|
|
|
// << " slaved " << sm->slaved
|
|
|
|
// << endl;
|
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
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
transform(sm); // calculate submodel's initial conditions in world-coordinates
|
|
|
|
|
|
|
|
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);
|
|
|
|
ballist->setRandomness(sm->randomness);
|
|
|
|
ballist->setLatitude(offsetpos.getLatitudeDeg());
|
|
|
|
ballist->setLongitude(offsetpos.getLongitudeDeg());
|
|
|
|
ballist->setAltitude(offsetpos.getElevationFt());
|
2007-03-30 22:51:52 +00:00
|
|
|
ballist->setAzimuth(IC.azimuth);
|
|
|
|
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);
|
|
|
|
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());
|
2010-08-28 23:00:09 +00:00
|
|
|
ballist->setXoffset(sm->x_offset);
|
|
|
|
ballist->setYoffset(sm->y_offset);
|
|
|
|
ballist->setZoffset(sm->z_offset);
|
|
|
|
ballist->setPitchoffset(sm->pitch_offset);
|
|
|
|
ballist->setYawoffset(sm->yaw_offset);
|
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);
|
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
|
|
|
{
|
2004-10-28 08:44:24 +00:00
|
|
|
SGPropertyNode *path = fgGetNode("/sim/submodels/path");
|
2004-08-26 08:38:43 +00:00
|
|
|
|
|
|
|
if (path) {
|
2007-06-10 18:24:48 +00:00
|
|
|
const int id = 0;
|
2007-05-12 10:39:56 +00:00
|
|
|
string Path = path->getStringValue();
|
|
|
|
bool Seviceable =_serviceable_node->getBoolValue();
|
|
|
|
setData(id, Path, Seviceable);
|
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
|
|
|
{
|
2007-06-07 16:30:26 +00:00
|
|
|
// set initial conditions
|
2010-08-28 23:00:09 +00:00
|
|
|
if (sm->contents_node != 0 && !sm->slaved) {
|
2007-03-30 22:51:52 +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
|
|
|
|
|
|
|
// 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;*/
|
|
|
|
} else
|
2007-06-07 22:48:37 +00:00
|
|
|
IC.mass = sm->weight * lbs_to_slugs;
|
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;
|
2010-08-28 23:00:09 +00:00
|
|
|
string name = sm->name;
|
|
|
|
|
2007-06-07 16:30:26 +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
|
|
|
|
|
|
|
|
|
|
|
//cout << " name " << name << " id " << id << " sub id" << sub_id << endl;
|
|
|
|
|
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
|
|
|
// set the data for a submodel tied to a submodel
|
2010-08-28 23:00:09 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
_count++;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
} else if (id == 0) {
|
|
|
|
//set the data for a submodel tied to the main model
|
2010-08-01 09:47:40 +00:00
|
|
|
|
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();
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
// set the data for a submodel tied to an AI Object
|
2010-08-14 12:39:30 +00:00
|
|
|
//cout << " set the data for a submodel tied to an AI Object " << id << endl;
|
2010-08-28 23:00:09 +00:00
|
|
|
setParentNode(id);
|
2007-03-30 22:51:52 +00:00
|
|
|
}
|
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
//cout << "Submodel: setting IC "<< name << endl;
|
|
|
|
//cout << "heading " << IC.azimuth << endl ;
|
|
|
|
//cout << "speed down " << IC.speed_down_fps << endl ;
|
|
|
|
//cout << "speed east " << IC.speed_east_fps << endl ;
|
|
|
|
//cout << "speed north " << IC.speed_north_fps << endl ;
|
|
|
|
//cout << "parent speed fps in " << IC.speed << "sm speed in " << sm->speed << endl ;
|
|
|
|
//cout << "lat " << IC.lat;
|
|
|
|
//cout << "alt " << IC.alt << endl ;
|
|
|
|
|
2004-09-07 19:10:10 +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-28 23:00:09 +00:00
|
|
|
//cout << "wind e " << IC.wind_from_east << " n " << IC.wind_from_north << endl;
|
|
|
|
|
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
|
|
|
|
|
|
|
_x_offset = sm->x_offset;
|
|
|
|
_y_offset = sm->y_offset;
|
|
|
|
_z_offset = sm->z_offset;
|
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
setOffsetPos();
|
2010-07-28 21:20:50 +00:00
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
//IC.elevation += sm->pitch_offset;
|
|
|
|
//IC.azimuth += sm->yaw_offset ;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
// pre-process the trig functions
|
2004-09-17 16:32:58 +00:00
|
|
|
cosRx = cos(-IC.roll * SG_DEGREES_TO_RADIANS);
|
|
|
|
sinRx = sin(-IC.roll * SG_DEGREES_TO_RADIANS);
|
|
|
|
cosRy = cos(-IC.elevation * SG_DEGREES_TO_RADIANS);
|
|
|
|
sinRy = sin(-IC.elevation * SG_DEGREES_TO_RADIANS);
|
2004-09-07 19:10:10 +00:00
|
|
|
cosRz = cos(IC.azimuth * SG_DEGREES_TO_RADIANS);
|
|
|
|
sinRz = sin(IC.azimuth * SG_DEGREES_TO_RADIANS);
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
// Get submodel initial velocity vector angles in XZ and XY planes.
|
2010-07-28 21:20:50 +00:00
|
|
|
// This vector should be added to aircraft's vector.
|
2007-06-07 22:48:37 +00:00
|
|
|
IC.elevation += (sm->yaw_offset * sinRx) + (sm->pitch_offset * cosRx);
|
|
|
|
IC.azimuth += (sm->yaw_offset * cosRx) - (sm->pitch_offset * sinRx);
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
// calculate the total speed north
|
2007-06-07 22:48:37 +00:00
|
|
|
IC.total_speed_north = sm->speed * cos(IC.elevation * SG_DEGREES_TO_RADIANS)
|
2007-06-24 07:57:45 +00:00
|
|
|
* cos(IC.azimuth * SG_DEGREES_TO_RADIANS) + IC.speed_north_fps;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
// calculate the total speed east
|
2007-06-07 22:48:37 +00:00
|
|
|
IC.total_speed_east = sm->speed * cos(IC.elevation * SG_DEGREES_TO_RADIANS)
|
2007-06-24 07:57:45 +00:00
|
|
|
* sin(IC.azimuth * SG_DEGREES_TO_RADIANS) + IC.speed_east_fps;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
// calculate the total speed down
|
2007-06-07 22:48:37 +00:00
|
|
|
IC.total_speed_down = sm->speed * -sin(IC.elevation * SG_DEGREES_TO_RADIANS)
|
2007-06-24 07:57:45 +00:00
|
|
|
+ IC.speed_down_fps;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
// re-calculate speed, elevation and azimuth
|
|
|
|
IC.speed = sqrt(IC.total_speed_north * IC.total_speed_north
|
2007-06-24 07:57:45 +00:00
|
|
|
+ IC.total_speed_east * IC.total_speed_east
|
|
|
|
+ IC.total_speed_down * IC.total_speed_down);
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-24 07:57:45 +00:00
|
|
|
// if speeds are low this calculation can become unreliable
|
2007-06-07 22:48:37 +00:00
|
|
|
if (IC.speed > 1) {
|
2010-08-28 23:00:09 +00:00
|
|
|
IC.azimuth = atan2(IC.total_speed_east, IC.total_speed_north) * SG_RADIANS_TO_DEGREES;
|
2007-06-07 16:30:26 +00:00
|
|
|
// cout << "azimuth1 " << IC.azimuth<<endl;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
// rationalise the output
|
|
|
|
if (IC.azimuth < 0)
|
|
|
|
IC.azimuth += 360;
|
|
|
|
else if (IC.azimuth >= 360)
|
|
|
|
IC.azimuth -= 360;
|
2007-08-01 10:44:17 +00:00
|
|
|
// cout << "azimuth2 " << IC.azimuth<<endl;
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2007-08-01 10:44:17 +00:00
|
|
|
IC.elevation = -atan(IC.total_speed_down / sqrt(IC.total_speed_north
|
2007-06-24 07:57:45 +00:00
|
|
|
* IC.total_speed_north + IC.total_speed_east * IC.total_speed_east))
|
|
|
|
* SG_RADIANS_TO_DEGREES;
|
2007-08-01 10:44:17 +00:00
|
|
|
}
|
2010-08-28 23:00:09 +00:00
|
|
|
//cout << "IC.speed " << IC.speed / SG_KT_TO_FPS << endl;
|
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()
|
|
|
|
{
|
2011-12-11 12:55:56 +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
|
|
|
|
2010-10-28 14:10:37 +00:00
|
|
|
FGAIManager::ai_list_iterator sm_list_itr = sm_list.begin(),
|
|
|
|
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();
|
2010-08-14 12:39:30 +00:00
|
|
|
string type = (*sm_list_itr)->getTypeString();
|
2007-05-12 10:39:56 +00:00
|
|
|
bool serviceable = (*sm_list_itr)->_getServiceable();
|
2010-08-14 12:39:30 +00:00
|
|
|
|
|
|
|
//cout << "loadAI: type " << type << " path "<< path << " serviceable " << serviceable << endl;
|
|
|
|
|
2007-05-12 10:39:56 +00:00
|
|
|
setData(id, path, serviceable);
|
2007-03-30 22:51:52 +00:00
|
|
|
++sm_list_itr;
|
|
|
|
}
|
|
|
|
}
|
2004-09-27 14:24:20 +00:00
|
|
|
|
2007-05-12 10:39:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
|
|
|
|
{
|
|
|
|
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);
|
2008-06-01 14:59:20 +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;
|
|
|
|
submodel* sm = new submodel;
|
|
|
|
SGPropertyNode * 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->x_offset = entry_node->getDoubleValue("x-offset", 0.0);
|
|
|
|
sm->y_offset = entry_node->getDoubleValue("y-offset", 0.0);
|
|
|
|
sm->z_offset = entry_node->getDoubleValue("z-offset", 0.0);
|
|
|
|
sm->yaw_offset = entry_node->getDoubleValue("yaw-offset", 0.0);
|
|
|
|
sm->pitch_offset = entry_node->getDoubleValue("pitch-offset", 0.0);
|
|
|
|
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);
|
2007-06-07 16:30:26 +00:00
|
|
|
sm->collision = entry_node->getBoolValue("collision", false);
|
2010-08-14 12:39:30 +00:00
|
|
|
sm->expiry = entry_node->getBoolValue("expiry", false);
|
2007-05-15 16:19:11 +00:00
|
|
|
sm->impact = entry_node->getBoolValue("impact", false);
|
2007-06-07 16:30:26 +00:00
|
|
|
sm->impact_report = entry_node->getStringValue("impact-reports");
|
|
|
|
sm->fuse_range = entry_node->getDoubleValue("fuse-range", 0.0);
|
2007-05-12 10:39:56 +00:00
|
|
|
sm->contents_node = fgGetNode(entry_node->getStringValue("contents", "none"), false);
|
2010-08-14 12:39:30 +00:00
|
|
|
sm->speed_node = fgGetNode(entry_node->getStringValue("speed-prop", "none"), false);
|
2007-06-07 16:30:26 +00:00
|
|
|
sm->submodel = entry_node->getStringValue("submodel-path", "");
|
2009-01-18 21:56:55 +00:00
|
|
|
sm->force_stabilised= entry_node->getBoolValue("force-stabilised", false);
|
2007-12-21 23:37:05 +00:00
|
|
|
sm->ext_force = entry_node->getBoolValue("external-force", false);
|
|
|
|
sm->force_path = entry_node->getStringValue("force-path", "");
|
2010-08-14 12:39:30 +00:00
|
|
|
sm->random = entry_node->getBoolValue("random", false);
|
|
|
|
sm->randomness = entry_node->getDoubleValue("randomness", 0.5);
|
2010-07-28 21:20:50 +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());
|
|
|
|
} else {
|
|
|
|
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
|
|
|
|
|
|
|
sm->prop = fgGetNode("/ai/submodels/submodel", 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)));
|
2007-05-12 10:39:56 +00:00
|
|
|
string name = sm->name;
|
|
|
|
sm->prop->setStringValue("name", name.c_str());
|
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
string submodel = sm->submodel;
|
|
|
|
sm->prop->setStringValue("submodel", submodel.c_str());
|
|
|
|
|
2007-12-21 23:37:05 +00:00
|
|
|
string force_path = sm->force_path;
|
|
|
|
sm->prop->setStringValue("force_path", force_path.c_str());
|
2010-07-28 21:20:50 +00:00
|
|
|
//cout << "set force_path Sub " << force_path << endl;
|
2007-12-21 23:37:05 +00:00
|
|
|
|
2007-05-12 10:39:56 +00:00
|
|
|
if (sm->contents_node != 0)
|
|
|
|
sm->prop->tie("contents-lbs", SGRawValuePointer<double>(&(sm->contents)));
|
|
|
|
|
|
|
|
index++;
|
|
|
|
submodels.push_back(sm);
|
|
|
|
}
|
2007-06-07 16:30:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable)
|
|
|
|
{
|
|
|
|
SGPropertyNode root;
|
2010-09-06 08:12:25 +00:00
|
|
|
SGPath config = globals->resolve_aircraft_path(path);
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2007-06-07 16:30:26 +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-06-07 16:30:26 +00:00
|
|
|
readProperties(config.str(), &root);
|
|
|
|
|
2008-06-01 14:59:20 +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-06-07 16:30:26 +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;
|
|
|
|
submodel* sm = new submodel;
|
|
|
|
SGPropertyNode * 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->x_offset = entry_node->getDoubleValue("x-offset", 0.0);
|
|
|
|
sm->y_offset = entry_node->getDoubleValue("y-offset", 0.0);
|
|
|
|
sm->z_offset = entry_node->getDoubleValue("z-offset", 0.0);
|
|
|
|
sm->yaw_offset = entry_node->getDoubleValue("yaw-offset", 0.0);
|
|
|
|
sm->pitch_offset = entry_node->getDoubleValue("pitch-offset", 0.0);
|
|
|
|
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);
|
2010-08-14 12:39:30 +00:00
|
|
|
sm->expiry = entry_node->getBoolValue("expiry", false);
|
2007-06-07 16:30:26 +00:00
|
|
|
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);
|
2010-08-14 12:39:30 +00:00
|
|
|
sm->speed_node = fgGetNode(entry_node->getStringValue("speed-prop", "none"), false);
|
2007-06-07 16:30:26 +00:00
|
|
|
sm->submodel = entry_node->getStringValue("submodel-path", "");
|
2010-08-14 12:39:30 +00:00
|
|
|
sm->force_stabilised= entry_node->getBoolValue("force-stabilised", false);
|
2007-12-21 23:37:05 +00:00
|
|
|
sm->ext_force = entry_node->getBoolValue("external-force", false);
|
|
|
|
sm->force_path = entry_node->getStringValue("force-path", "");
|
2010-08-14 12:39:30 +00:00
|
|
|
sm->random = entry_node->getBoolValue("random", false);
|
|
|
|
sm->randomness = entry_node->getDoubleValue("randomness", 0.5);
|
2007-06-07 16:30:26 +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());
|
|
|
|
} else {
|
|
|
|
sm->trigger_node = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sm->speed_node != 0)
|
|
|
|
sm->speed = sm->speed_node->getDoubleValue();
|
|
|
|
|
|
|
|
sm->timer = sm->delay;
|
|
|
|
sm->id = index;
|
|
|
|
sm->first_time = false;
|
|
|
|
sm->serviceable = serviceable;
|
|
|
|
sm->sub_id = 0;
|
|
|
|
|
|
|
|
sm->prop = fgGetNode("/ai/submodels/subsubmodel", index, true);
|
|
|
|
sm->prop->tie("count", SGRawValuePointer<int>(&(sm->count)));
|
|
|
|
sm->prop->tie("repeat", SGRawValuePointer<bool>(&(sm->repeat)));
|
|
|
|
sm->prop->tie("id", SGRawValuePointer<int>(&(sm->id)));
|
|
|
|
sm->prop->tie("sub-id", SGRawValuePointer<int>(&(sm->sub_id)));
|
|
|
|
sm->prop->tie("serviceable", SGRawValuePointer<bool>(&(sm->serviceable)));
|
2010-08-14 12:39:30 +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)));
|
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
string name = sm->name;
|
|
|
|
sm->prop->setStringValue("name", name.c_str());
|
|
|
|
|
|
|
|
string submodel = sm->submodel;
|
2010-08-28 23:00:09 +00:00
|
|
|
sm->prop->setStringValue("submodel-path", submodel.c_str());
|
2010-07-28 21:20:50 +00:00
|
|
|
// cout << " set submodel path AI" << submodel<< endl;
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2007-12-21 23:37:05 +00:00
|
|
|
string force_path = sm->force_path;
|
|
|
|
sm->prop->setStringValue("force_path", force_path.c_str());
|
2010-08-01 09:47:40 +00:00
|
|
|
//cout << "set force_path AI" << force_path << endl;
|
2007-12-21 23:37:05 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
if (sm->contents_node != 0)
|
|
|
|
sm->prop->tie("contents-lbs", SGRawValuePointer<double>(&(sm->contents)));
|
|
|
|
|
|
|
|
index++;
|
|
|
|
subsubmodels.push_back(sm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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()) {
|
|
|
|
string submodel = (*submodel_iterator)->submodel;
|
|
|
|
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
|
|
|
|
|
|
|
if ((*submodel_iterator)->sub_id == 0){
|
|
|
|
(*submodel_iterator)->sub_id = index;
|
|
|
|
_found_sub = true;
|
|
|
|
setSubData(index, submodel, serviceable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++submodel_iterator;
|
|
|
|
} // end while
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
subsubmodel_iterator = subsubmodels.begin();
|
|
|
|
|
|
|
|
while (subsubmodel_iterator != subsubmodels.end()) {
|
2010-08-28 23:00:09 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
submodels.push_back(*subsubmodel_iterator);
|
|
|
|
++subsubmodel_iterator;
|
2010-07-16 22:05:05 +00:00
|
|
|
} // end while
|
|
|
|
|
2010-08-14 12:39:30 +00:00
|
|
|
subsubmodels.clear();
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2009-08-21 14:29:11 +00:00
|
|
|
//submodel_iterator = submodels.begin();
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
//int subcount = 0;
|
|
|
|
|
2009-08-21 14:29:11 +00:00
|
|
|
//while (submodel_iterator != submodels.end()) {
|
2010-08-28 23:00:09 +00:00
|
|
|
// int id = (*submodel_iterator)->id;
|
|
|
|
// subcount++;
|
|
|
|
|
2011-12-11 12:55:56 +00:00
|
|
|
// SG_LOG(SG_AI, SG_ALERT,"after pushback "
|
2010-08-28 23:00:09 +00:00
|
|
|
// << " parent id " << id
|
|
|
|
// << " name " << (*submodel_iterator)->name
|
|
|
|
// << " sub id " << (*submodel_iterator)->sub_id
|
|
|
|
// << " subcount "<< subcount);
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
// ++submodel_iterator;
|
2009-08-21 14:29:11 +00:00
|
|
|
//}
|
2007-05-12 10:39:56 +00:00
|
|
|
}
|
|
|
|
|
2010-07-28 21:20:50 +00:00
|
|
|
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) )
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
// 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);
|
2010-08-28 23:00:09 +00:00
|
|
|
|
|
|
|
//cout << "OFFSET POS" << offsetpos.getElevationFt();
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
basic_string <char>::size_type indexCh2b;
|
|
|
|
|
|
|
|
string str2 = _model_added;
|
2010-09-08 17:09:03 +00:00
|
|
|
const char *cstr2b = "multiplayer";
|
2010-08-14 12:39:30 +00:00
|
|
|
indexCh2b = str2.find( cstr2b, 0 );
|
|
|
|
|
|
|
|
if (indexCh2b != string::npos ){ // we will ignore Ballistic Objects - there are potentially too many
|
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
|
|
|
|
2010-09-08 17:09:03 +00:00
|
|
|
string callsign = callsign_node->getStringValue();
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2010-09-08 17:09:03 +00:00
|
|
|
//cout << "Submodels: model added - " << callsign <<" read callsign "<< endl;
|
2010-08-14 12:39:30 +00:00
|
|
|
return;
|
|
|
|
|
2010-09-08 17:09:03 +00:00
|
|
|
} else {
|
|
|
|
cout << "model added - " << str2 <<" returning "<< endl;
|
|
|
|
return;
|
2010-08-14 12:39:30 +00:00
|
|
|
}
|
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
}
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
void FGSubmodelMgr::setParentNode(int id) {
|
2010-08-14 12:39:30 +00:00
|
|
|
|
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
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
if (i < 0) { // last iteration: selected model
|
|
|
|
model = _selected_ac;
|
|
|
|
} else {
|
|
|
|
model = ai->getChild(i);
|
|
|
|
string path = ai->getPath();
|
|
|
|
const string name = model->getStringValue("name");
|
|
|
|
int parent_id = model->getIntValue("id");
|
|
|
|
if (!model->nChildren()){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (parent_id == id) {
|
|
|
|
_selected_ac = model; // save selected model for last iteration
|
|
|
|
break;
|
|
|
|
}
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
}
|
|
|
|
if (!model)
|
|
|
|
continue;
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2010-08-28 23:08:50 +00:00
|
|
|
}// end for loop
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
if (_selected_ac != 0){
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
//cout << " parent node found"<< endl;
|
2010-08-14 12:39:30 +00:00
|
|
|
|
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");
|
2010-08-14 12:39:30 +00:00
|
|
|
|
2010-08-28 23:00:09 +00:00
|
|
|
//cout << name << " IC.speed " << IC.speed << endl;
|
|
|
|
|
|
|
|
} 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-08-14 12:39:30 +00:00
|
|
|
|
2010-07-28 21:20:50 +00:00
|
|
|
}
|
2007-03-30 22:51:52 +00:00
|
|
|
// end of submodel.cxx
|