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>
|
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
|
|
|
{
|
2007-03-30 22:51:52 +00:00
|
|
|
x_offset = y_offset = 0.0;
|
|
|
|
z_offset = -4.0;
|
|
|
|
pitch_offset = 2.0;
|
|
|
|
yaw_offset = 0.0;
|
|
|
|
|
|
|
|
out[0] = out[1] = out[2] = 0;
|
|
|
|
string contents_node;
|
|
|
|
contrail_altitude = 30000;
|
2007-06-07 16:30:26 +00:00
|
|
|
_count = 0;
|
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
|
|
|
|
|
|
|
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
|
|
|
|
2004-11-07 14:46:21 +00:00
|
|
|
ai = (FGAIManager*)globals->get_subsystem("ai_model");
|
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
|
|
|
|
2007-04-27 11:02:39 +00:00
|
|
|
void FGSubmodelMgr::postinit() {
|
|
|
|
// postinit, so that the AI list is populated
|
2007-03-30 22:51:52 +00:00
|
|
|
loadAI();
|
2007-06-07 16:30:26 +00:00
|
|
|
loadSubmodels();
|
|
|
|
|
|
|
|
//TODO reload submodels if an MP ac joins
|
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;
|
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
// check if the submodel hit an object or terrain
|
2007-06-07 16:30:26 +00:00
|
|
|
sm_list = ai->get_ai_list();
|
|
|
|
sm_list_iterator sm_list_itr = sm_list.begin();
|
|
|
|
sm_list_iterator end = sm_list.end();
|
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
for (; sm_list_itr != end; ++sm_list_itr) {
|
2007-06-07 16:30:26 +00:00
|
|
|
_impact = (*sm_list_itr)->_getImpactData();
|
|
|
|
_hit = (*sm_list_itr)->_getCollisionData();
|
|
|
|
int parent_subID = (*sm_list_itr)->_getSubID();
|
2007-06-24 07:57:45 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodel: Impact " << _impact << " hit! "
|
|
|
|
<< _hit <<" parent_subID " << parent_subID);
|
2007-06-07 22:48:37 +00:00
|
|
|
if ( parent_subID == 0) // this entry in the list has no associated submodel
|
|
|
|
continue; // so we can continue
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
if (_impact || _hit) {
|
2007-06-24 07:57:45 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodel: Impact " << _impact << " hit! " << _hit );
|
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;
|
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
if (release(*submodel_iterator, dt))
|
2007-06-07 16:30:26 +00:00
|
|
|
(*sm_list_itr)->setDie(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
++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
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
bool in_range = true;
|
|
|
|
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++;
|
2007-06-07 16:30:26 +00:00
|
|
|
in_range = true;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
2007-06-24 07:57:45 +00:00
|
|
|
"Submodels: " << (*submodel_iterator)->id
|
|
|
|
<< " name " << (*submodel_iterator)->name
|
|
|
|
<< " in range " << in_range);
|
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();
|
|
|
|
//cout << "trigger node found " << trigger << endl;
|
2007-03-30 22:51:52 +00:00
|
|
|
} else {
|
|
|
|
trigger = true;
|
2007-06-07 16:30:26 +00:00
|
|
|
//cout << (*submodel_iterator)->name << "trigger node not found " << trigger << endl;
|
2007-03-30 22:51:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (trigger) {
|
|
|
|
int id = (*submodel_iterator)->id;
|
2007-06-07 16:30:26 +00:00
|
|
|
string name = (*submodel_iterator)->name;
|
2007-03-30 22:51:52 +00:00
|
|
|
// don't release submodels from AI Objects if they are
|
|
|
|
// too far away to be seen. id 0 is not an AI model,
|
|
|
|
// so we can skip the whole process
|
|
|
|
sm_list_iterator sm_list_itr = sm_list.begin();
|
|
|
|
sm_list_iterator end = sm_list.end();
|
|
|
|
|
|
|
|
while (sm_list_itr != end) {
|
2007-12-21 23:37:05 +00:00
|
|
|
in_range = true;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
if (id == 0) {
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
2007-06-24 07:57:45 +00:00
|
|
|
"Submodels: continuing: " << id << " name " << name );
|
2007-03-30 22:51:52 +00:00
|
|
|
++sm_list_itr;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
int parent_id = (*submodel_iterator)->id;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
if (parent_id == id) {
|
|
|
|
double parent_lat = (*sm_list_itr)->_getLatitude();
|
|
|
|
double parent_lon = (*sm_list_itr)->_getLongitude();
|
2007-12-21 23:37:05 +00:00
|
|
|
string parent_name = (*sm_list_itr)->_getName();
|
2007-03-30 22:51:52 +00:00
|
|
|
double own_lat = _user_lat_node->getDoubleValue();
|
|
|
|
double own_lon = _user_lon_node->getDoubleValue();
|
|
|
|
double range_nm = getRange(parent_lat, parent_lon, own_lat, own_lon);
|
2007-12-21 23:37:05 +00:00
|
|
|
//cout << "parent name " << parent_name << ", "<< parent_id << ", "<< parent_lat << ", " << parent_lon << endl;
|
|
|
|
//cout << "own name " << own_lat << ", " << own_lon << " range " << range_nm << endl;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
if (range_nm > 15) {
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
2007-12-21 23:37:05 +00:00
|
|
|
"Submodels: skipping release, out of range: " << id);
|
2007-03-30 22:51:52 +00:00
|
|
|
in_range = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++sm_list_itr;
|
|
|
|
} // end while
|
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
2007-06-24 07:57:45 +00:00
|
|
|
"Submodels end: " << (*submodel_iterator)->id
|
|
|
|
<< " name " << (*submodel_iterator)->name
|
|
|
|
<< " count " << (*submodel_iterator)->count
|
|
|
|
<< " in range " << in_range);
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
if ((*submodel_iterator)->count != 0 && in_range)
|
2007-06-07 22:48:37 +00:00
|
|
|
release(*submodel_iterator, dt);
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
} else
|
|
|
|
(*submodel_iterator)->first_time = true;
|
|
|
|
|
|
|
|
++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
|
|
|
{
|
2007-06-07 22:48:37 +00:00
|
|
|
//cout << "release id " << sm->id << " name " << sm->name
|
2007-06-24 07:57:45 +00:00
|
|
|
//<< " first time " << sm->first_time << " repeat " << sm->repeat <<
|
2007-06-07 16:30:26 +00:00
|
|
|
// endl;
|
|
|
|
|
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) {
|
|
|
|
//cout<< "not first time " << sm->first_time<< " repeat " << sm->repeat <<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) {
|
|
|
|
//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
|
|
|
}
|
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());
|
2007-03-30 22:51:52 +00:00
|
|
|
ballist->setLatitude(IC.lat);
|
|
|
|
ballist->setLongitude(IC.lon);
|
|
|
|
ballist->setAltitude(IC.alt);
|
|
|
|
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->setName(sm->name);
|
|
|
|
ballist->setCollision(sm->collision);
|
|
|
|
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);
|
2007-12-21 23:37:05 +00:00
|
|
|
ballist->setExternalForce(sm->ext_force);
|
|
|
|
ballist->setForcePath(sm->force_path.c_str());
|
2007-03-30 22:51:52 +00:00
|
|
|
ai->attach(ballist);
|
|
|
|
|
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
|
2007-06-07 22:48:37 +00:00
|
|
|
if (sm->contents_node != 0) {
|
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
|
|
|
|
|
|
|
// cout << "mass " << IC.mass << endl;
|
|
|
|
|
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
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
int id = sm->id;
|
2007-06-07 16:30:26 +00:00
|
|
|
//int sub_id = (*submodel)->sub_id;
|
2007-06-07 22:48:37 +00:00
|
|
|
string name = sm->name;
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
//cout << " name " << name << " id " << id << " sub id" << sub_id << endl;
|
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
if (_impact || _hit) {
|
2007-06-07 16:30:26 +00:00
|
|
|
// set the data for a submodel tied to a submodel
|
|
|
|
_count++;
|
|
|
|
//cout << "Submodels: release sub sub " << _count<< endl;
|
2007-06-07 22:48:37 +00:00
|
|
|
//cout << " id " << sm->id
|
2007-06-07 16:30:26 +00:00
|
|
|
// << " lat " << _parent_lat
|
|
|
|
// << " lon " << _parent_lon
|
|
|
|
// << " elev " << _parent_elev
|
2007-06-07 22:48:37 +00:00
|
|
|
// << " name " << sm->name
|
2007-06-07 16:30:26 +00:00
|
|
|
// << endl;
|
|
|
|
|
|
|
|
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
|
|
|
|
/*cout << "Submodels: release main sub " << endl;
|
2007-06-07 22:48:37 +00:00
|
|
|
cout << " name " << sm->name
|
|
|
|
<< " id" << sm->id
|
2007-06-07 16:30:26 +00:00
|
|
|
<< endl;*/
|
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
|
|
|
|
sm_list_iterator sm_list_itr = sm_list.begin();
|
|
|
|
sm_list_iterator end = sm_list.end();
|
|
|
|
|
|
|
|
while (sm_list_itr != end) {
|
2007-06-07 16:30:26 +00:00
|
|
|
int parent_id = (*sm_list_itr)->getID();
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
if (id != parent_id) {
|
2007-03-30 22:51:52 +00:00
|
|
|
++sm_list_itr;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
//cout << "found id " << id << endl;
|
|
|
|
IC.lat = (*sm_list_itr)->_getLatitude();
|
|
|
|
IC.lon = (*sm_list_itr)->_getLongitude();
|
|
|
|
IC.alt = (*sm_list_itr)->_getAltitude();
|
|
|
|
IC.roll = (*sm_list_itr)->_getRoll();
|
|
|
|
IC.elevation = (*sm_list_itr)->_getPitch();
|
|
|
|
IC.azimuth = (*sm_list_itr)->_getHeading();
|
|
|
|
IC.alt = (*sm_list_itr)->_getAltitude();
|
|
|
|
IC.speed = (*sm_list_itr)->_getSpeed() * SG_KT_TO_FPS;
|
|
|
|
IC.speed_down_fps = -(*sm_list_itr)->_getVS_fps();
|
|
|
|
IC.speed_east_fps = (*sm_list_itr)->_get_speed_east_fps();
|
|
|
|
IC.speed_north_fps = (*sm_list_itr)->_get_speed_north_fps();
|
|
|
|
|
|
|
|
++sm_list_itr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*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 ;
|
2007-06-07 22:48:37 +00:00
|
|
|
cout << "parent speed fps in" << IC.speed << "sm speed in " << sm->speed << endl ;*/
|
2004-09-07 19:10:10 +00:00
|
|
|
|
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
|
|
|
|
2007-06-07 22:48:37 +00:00
|
|
|
in[0] = sm->x_offset;
|
|
|
|
in[1] = sm->y_offset;
|
|
|
|
in[2] = sm->z_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
|
|
|
// set up the transform matrix
|
2004-09-09 08:40:08 +00:00
|
|
|
trans[0][0] = cosRy * cosRz;
|
|
|
|
trans[0][1] = -1 * cosRx * sinRz + sinRx * sinRy * cosRz ;
|
|
|
|
trans[0][2] = sinRx * sinRz + cosRx * sinRy * cosRz;
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2004-09-09 08:40:08 +00:00
|
|
|
trans[1][0] = cosRy * sinRz;
|
|
|
|
trans[1][1] = cosRx * cosRz + sinRx * sinRy * sinRz;
|
|
|
|
trans[1][2] = -1 * sinRx * cosRx + cosRx * sinRy * sinRz;
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2004-09-09 08:40:08 +00:00
|
|
|
trans[2][0] = -1 * sinRy;
|
|
|
|
trans[2][1] = sinRx * cosRy;
|
|
|
|
trans[2][2] = cosRx * cosRy;
|
2004-09-07 19:10:10 +00:00
|
|
|
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
// multiply the input and transform matrices
|
|
|
|
out[0] = in[0] * trans[0][0] + in[1] * trans[0][1] + in[2] * trans[0][2];
|
|
|
|
out[1] = in[0] * trans[1][0] + in[1] * trans[1][1] + in[2] * trans[1][2];
|
|
|
|
out[2] = in[0] * trans[2][0] + in[1] * trans[2][1] + in[2] * trans[2][2];
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
// convert ft to degrees of latitude
|
|
|
|
out[0] = out[0] / (366468.96 - 3717.12 * cos(IC.lat * SG_DEGREES_TO_RADIANS));
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
// convert ft to degrees of longitude
|
|
|
|
out[1] = out[1] / (365228.16 * cos(IC.lat * SG_DEGREES_TO_RADIANS));
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
// set submodel initial position
|
|
|
|
IC.lat += out[0];
|
|
|
|
IC.lon += out[1];
|
|
|
|
IC.alt += out[2];
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
// get aircraft velocity vector angles in XZ and XY planes
|
2004-09-09 08:40:08 +00:00
|
|
|
//double alpha = _user_alpha_node->getDoubleValue();
|
|
|
|
//double velXZ = IC.elevation - alpha * cosRx;
|
|
|
|
//double velXY = IC.azimuth - (IC.elevation - alpha * sinRx);
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
// Get submodel initial velocity vector angles in XZ and XY planes.
|
|
|
|
// This needs to be fixed. This vector should be added to aircraft's vector.
|
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) {
|
2007-06-07 16:30:26 +00:00
|
|
|
IC.azimuth = atan2(IC.total_speed_east , IC.total_speed_north) * SG_RADIANS_TO_DEGREES;
|
|
|
|
// 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
|
|
|
}
|
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()
|
|
|
|
{
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Loading AI submodels ");
|
2007-05-12 10:39:56 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
sm_list = ai->get_ai_list();
|
2004-09-01 21:05:04 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
if (sm_list.empty()) {
|
2008-03-22 09:31:06 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Unable to read AI submodel list");
|
2007-03-30 22:51:52 +00:00
|
|
|
return;
|
|
|
|
}
|
2004-09-14 08:27:55 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
sm_list_iterator sm_list_itr = sm_list.begin();
|
|
|
|
sm_list_iterator end = sm_list.end();
|
|
|
|
|
|
|
|
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();
|
|
|
|
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
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
double FGSubmodelMgr::getRange(double lat, double lon, double lat2, double lon2) const
|
|
|
|
{
|
|
|
|
double course, distance, az2;
|
|
|
|
|
|
|
|
//calculate the bearing and range of the second pos from the first
|
|
|
|
geo_inverse_wgs_84(lat, lon, lat2, lon2, &course, &az2, &distance);
|
|
|
|
distance *= SG_METER_TO_NM;
|
|
|
|
return distance;
|
|
|
|
}
|
2007-05-12 10:39:56 +00:00
|
|
|
|
|
|
|
void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
|
|
|
|
{
|
|
|
|
SGPropertyNode root;
|
|
|
|
|
|
|
|
SGPath config(globals->get_fg_root());
|
|
|
|
config.append(path);
|
2007-06-10 18:24:48 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: path " << path);
|
2007-05-12 10:39:56 +00:00
|
|
|
try {
|
|
|
|
SG_LOG(SG_GENERAL, 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 &) {
|
2008-03-22 09:31:06 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
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);
|
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);
|
|
|
|
sm->speed_node = fgGetNode(entry_node->getStringValue("speed-node", "none"), false);
|
2007-06-07 16:30:26 +00:00
|
|
|
sm->submodel = entry_node->getStringValue("submodel-path", "");
|
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", "");
|
2007-05-12 10:39:56 +00:00
|
|
|
//cout << "sm->contents_node " << sm->contents_node << endl;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-06-24 07:57:45 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: trigger " << sm->trigger_node->getBoolValue() );
|
2007-12-21 23:37:05 +00:00
|
|
|
|
2007-05-12 10:39:56 +00:00
|
|
|
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);
|
|
|
|
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)));
|
|
|
|
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());
|
|
|
|
//cout << " set submodel path " << submodel << endl;
|
|
|
|
|
2007-12-21 23:37:05 +00:00
|
|
|
string force_path = sm->force_path;
|
|
|
|
sm->prop->setStringValue("force_path", force_path.c_str());
|
|
|
|
//cout << "set force_path " << force_path << endl;
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
SGPath config(globals->get_fg_root());
|
|
|
|
config.append(path);
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
|
|
|
"Submodels: path " << path);
|
|
|
|
try {
|
|
|
|
SG_LOG(SG_GENERAL, 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 &) {
|
2008-03-22 09:31:06 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
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);
|
|
|
|
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-node", "none"), false);
|
|
|
|
sm->submodel = entry_node->getStringValue("submodel-path", "");
|
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", "");
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
//cout << "sm->contents_node " << sm->contents_node << endl;
|
|
|
|
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)));
|
|
|
|
string name = sm->name;
|
|
|
|
sm->prop->setStringValue("name", name.c_str());
|
|
|
|
|
|
|
|
string submodel = sm->submodel;
|
|
|
|
sm->prop->setStringValue("submodel", submodel.c_str());
|
|
|
|
// cout << " set submodel path " << submodel<< endl;
|
|
|
|
|
2007-12-21 23:37:05 +00:00
|
|
|
string force_path = sm->force_path;
|
|
|
|
sm->prop->setStringValue("force_path", force_path.c_str());
|
|
|
|
//cout << "set force_path " << force_path << endl;
|
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Loading sub submodels");
|
|
|
|
|
2007-05-12 10:39:56 +00:00
|
|
|
submodel_iterator = submodels.begin();
|
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
while (submodel_iterator != submodels.end()) {
|
|
|
|
string submodel = (*submodel_iterator)->submodel;
|
|
|
|
if (!submodel.empty()) {
|
|
|
|
//int id = (*submodel_iterator)->id;
|
|
|
|
bool serviceable = true;
|
2007-06-24 07:57:45 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "found path sub sub "
|
|
|
|
<< submodel
|
|
|
|
<< " index " << index
|
|
|
|
<< "name " << (*submodel_iterator)->name);
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
(*submodel_iterator)->sub_id = index;
|
|
|
|
setSubData(index, submodel, serviceable);
|
|
|
|
}
|
|
|
|
|
|
|
|
++submodel_iterator;
|
|
|
|
}
|
|
|
|
|
|
|
|
subsubmodel_iterator = subsubmodels.begin();
|
|
|
|
|
|
|
|
while (subsubmodel_iterator != subsubmodels.end()) {
|
|
|
|
submodels.push_back(*subsubmodel_iterator);
|
|
|
|
++subsubmodel_iterator;
|
|
|
|
}
|
|
|
|
|
|
|
|
submodel_iterator = submodels.begin();
|
|
|
|
|
|
|
|
while (submodel_iterator != submodels.end()) {
|
|
|
|
int id = (*submodel_iterator)->id;
|
2007-12-21 23:37:05 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,"after pushback "
|
2007-06-24 07:57:45 +00:00
|
|
|
<< " id " << id
|
|
|
|
<< " name " << (*submodel_iterator)->name
|
|
|
|
<< " sub id " << (*submodel_iterator)->sub_id);
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
++submodel_iterator;
|
|
|
|
}
|
2007-05-12 10:39:56 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
// end of submodel.cxx
|