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
|
|
|
// submodel.cxx - models a releasable submodel.
|
|
|
|
// Written by Dave Culp, started Aug 2004
|
|
|
|
//
|
|
|
|
// This file is in the Public Domain and comes with no warranty.
|
|
|
|
|
|
|
|
#include "submodel.hxx"
|
2004-08-26 08:38:43 +00:00
|
|
|
|
|
|
|
#include <simgear/structure/exception.hxx>
|
|
|
|
#include <simgear/misc/sg_path.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
|
|
|
#include <Main/fg_props.hxx>
|
|
|
|
#include <Main/util.hxx>
|
|
|
|
#include <AIModel/AIManager.hxx>
|
|
|
|
|
|
|
|
|
2004-10-22 09:58:24 +00:00
|
|
|
const double FGSubmodelMgr::lbs_to_slugs = 0.031080950172;
|
2004-09-22 08:47:05 +00:00
|
|
|
|
2004-10-22 09:58:24 +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
|
|
|
{
|
2004-09-07 19:10:10 +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
|
|
|
x_offset = y_offset = 0.0;
|
|
|
|
z_offset = -4.0;
|
|
|
|
pitch_offset = 2.0;
|
|
|
|
yaw_offset = 0.0;
|
2004-09-07 19:10:10 +00:00
|
|
|
|
|
|
|
out[0] = out[1] = out[2] = 0;
|
|
|
|
in[3] = out[3] = 1;
|
2004-09-27 14:24:20 +00:00
|
|
|
string contents_node;
|
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
|
|
|
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
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-10-22 09:58:24 +00:00
|
|
|
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
|
|
|
{
|
2004-08-26 08:38:43 +00:00
|
|
|
load();
|
|
|
|
_serviceable_node = fgGetNode("/sim/systems/submodels/serviceable", 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
|
|
|
|
|
|
|
_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
|
|
|
|
2004-09-14 08:27:55 +00:00
|
|
|
_user_speed_down_fps_node = fgGetNode("/velocities/speed-down-fps",true);
|
|
|
|
_user_speed_east_fps_node = fgGetNode("/velocities/speed-east-fps",true);
|
2004-09-22 08:47:05 +00:00
|
|
|
_user_speed_north_fps_node = fgGetNode("/velocities/speed-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
|
|
|
ai = (FGAIManager*)globals->get_subsystem("ai_model");
|
2004-09-07 19:10:10 +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
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-10-22 09:58:24 +00:00
|
|
|
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
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-10-22 09:58:24 +00:00
|
|
|
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
|
|
|
{
|
2004-08-30 11:13:29 +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
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-10-22 09:58:24 +00:00
|
|
|
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
|
|
|
{
|
2004-08-26 08:38:43 +00:00
|
|
|
if (!(_serviceable_node->getBoolValue())) return;
|
2004-08-26 12:27:39 +00:00
|
|
|
int i=-1;
|
2004-08-26 08:38:43 +00:00
|
|
|
submodel_iterator = submodels.begin();
|
|
|
|
while(submodel_iterator != submodels.end()) {
|
2004-08-26 12:27:39 +00:00
|
|
|
i++;
|
2004-08-26 08:38:43 +00:00
|
|
|
if ((*submodel_iterator)->trigger->getBoolValue()) {
|
2004-08-30 09:15:04 +00:00
|
|
|
if ((*submodel_iterator)->count != 0) {
|
2004-08-26 08:38:43 +00:00
|
|
|
release( (*submodel_iterator), dt);
|
|
|
|
}
|
2004-09-09 08:40:08 +00:00
|
|
|
} else {
|
|
|
|
(*submodel_iterator)->first_time = true;
|
|
|
|
}
|
2004-08-26 08:38:43 +00:00
|
|
|
++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
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2004-10-22 09:58:24 +00:00
|
|
|
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
|
|
|
{
|
2004-08-26 08:38:43 +00:00
|
|
|
sm->timer += dt;
|
|
|
|
if (sm->timer < sm->delay) return false;
|
|
|
|
sm->timer = 0.0;
|
|
|
|
|
2004-09-09 08:40:08 +00:00
|
|
|
if (sm->first_time) {
|
|
|
|
dt = 0.0;
|
|
|
|
sm->first_time = false;
|
|
|
|
}
|
|
|
|
|
2004-09-07 19:10:10 +00:00
|
|
|
transform(sm); // calculate submodel's initial conditions in world-coordinates
|
2004-08-26 08:38:43 +00:00
|
|
|
|
2004-09-07 09:53:23 +00:00
|
|
|
FGAIModelEntity entity;
|
|
|
|
|
|
|
|
entity.path = sm->model.c_str();
|
|
|
|
entity.latitude = IC.lat;
|
|
|
|
entity.longitude = IC.lon;
|
|
|
|
entity.altitude = IC.alt;
|
|
|
|
entity.azimuth = IC.azimuth;
|
|
|
|
entity.elevation = IC.elevation;
|
2004-09-17 16:32:58 +00:00
|
|
|
entity.roll = IC.roll;
|
2004-09-07 09:53:23 +00:00
|
|
|
entity.speed = IC.speed;
|
|
|
|
entity.eda = sm->drag_area;
|
|
|
|
entity.life = sm->life;
|
|
|
|
entity.buoyancy = sm->buoyancy;
|
|
|
|
entity.wind_from_east = IC.wind_from_east;
|
|
|
|
entity.wind_from_north = IC.wind_from_north;
|
|
|
|
entity.wind = sm->wind;
|
2004-09-22 08:47:05 +00:00
|
|
|
entity.cd = sm->cd;
|
2004-09-27 14:24:20 +00:00
|
|
|
entity.mass = IC.mass;
|
2004-09-08 13:21:40 +00:00
|
|
|
ai->createBallistic( &entity );
|
2004-09-09 08:40:08 +00:00
|
|
|
|
2004-08-30 09:15:04 +00:00
|
|
|
if (sm->count > 0) (sm->count)--;
|
2004-08-26 12:27:39 +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
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2004-08-26 08:38:43 +00:00
|
|
|
void
|
2004-10-22 09:58:24 +00:00
|
|
|
FGSubmodelMgr::load ()
|
2004-08-26 08:38:43 +00:00
|
|
|
{
|
2004-09-27 14:24:20 +00:00
|
|
|
|
2004-08-26 08:38:43 +00:00
|
|
|
int i;
|
|
|
|
SGPropertyNode *path = fgGetNode("/sim/systems/submodels/path");
|
|
|
|
SGPropertyNode root;
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
SGPath config( globals->get_fg_root() );
|
|
|
|
config.append( path->getStringValue() );
|
|
|
|
|
|
|
|
try {
|
|
|
|
readProperties(config.str(), &root);
|
|
|
|
} catch (const sg_exception &e) {
|
|
|
|
SG_LOG(SG_GENERAL, SG_ALERT,
|
|
|
|
"Unable to read submodels file: ");
|
|
|
|
cout << config.str() << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int count = root.nChildren();
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
// cout << "Reading submodel " << i << endl;
|
2004-08-30 11:13:29 +00:00
|
|
|
SGPropertyNode *prop;
|
2004-08-26 08:38:43 +00:00
|
|
|
submodel* sm = new submodel;
|
|
|
|
SGPropertyNode * entry_node = root.getChild(i);
|
|
|
|
sm->trigger = fgGetNode(entry_node->getStringValue("trigger", "none"), true);
|
|
|
|
sm->name = entry_node->getStringValue("name", "none_defined");
|
2004-08-26 12:27:39 +00:00
|
|
|
sm->model = entry_node->getStringValue("model", "Models/Geometry/rocket.ac");
|
2004-09-22 08:47:05 +00:00
|
|
|
sm->speed = entry_node->getDoubleValue("speed", 2329.4 );
|
2004-08-26 08:38:43 +00:00
|
|
|
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);
|
2004-09-07 19:10:10 +00:00
|
|
|
sm->y_offset = entry_node->getDoubleValue("y-offset", 0.0);
|
2004-08-26 08:38:43 +00:00
|
|
|
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);
|
2004-09-22 08:47:05 +00:00
|
|
|
sm->drag_area = entry_node->getDoubleValue("eda", 0.034);
|
2004-08-30 09:11:59 +00:00
|
|
|
sm->life = entry_node->getDoubleValue("life", 900.0);
|
2004-09-01 21:05:04 +00:00
|
|
|
sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
|
2004-09-05 09:45:34 +00:00
|
|
|
sm->wind = entry_node->getBoolValue ("wind", false);
|
2004-09-09 08:40:08 +00:00
|
|
|
sm->first_time = false;
|
2004-10-02 14:30:18 +00:00
|
|
|
sm->cd = entry_node->getDoubleValue("cd", 0.193);
|
2004-09-22 08:47:05 +00:00
|
|
|
sm->weight = entry_node->getDoubleValue("weight", 0.25);
|
2004-10-02 14:30:18 +00:00
|
|
|
sm->contents_node = fgGetNode(entry_node->getStringValue("contents", "none"), true);
|
2004-08-26 08:38:43 +00:00
|
|
|
|
|
|
|
sm->trigger->setBoolValue(false);
|
2004-08-26 16:25:54 +00:00
|
|
|
sm->timer = sm->delay;
|
2004-09-27 14:24:20 +00:00
|
|
|
|
|
|
|
sm->contents = sm->contents_node->getDoubleValue();
|
|
|
|
|
2004-08-30 11:13:29 +00:00
|
|
|
sm->prop = fgGetNode("/systems/submodels/submodel", i, true);
|
|
|
|
sm->prop->tie("count", SGRawValuePointer<int>(&(sm->count)));
|
|
|
|
|
2004-09-27 14:24:20 +00:00
|
|
|
// sm->prop->tie("contents", SGRawValuePointer<double>(&(sm->contents)));
|
|
|
|
// sm->prop->tie("contents path", SGRawValuePointer<const char *>(&(sm->contents_node)));
|
2004-08-30 11:13:29 +00:00
|
|
|
submodels.push_back( sm );
|
2004-08-26 12:27:39 +00:00
|
|
|
}
|
2004-08-26 08:38:43 +00:00
|
|
|
|
|
|
|
submodel_iterator = submodels.begin();
|
2004-09-09 08:40:08 +00:00
|
|
|
|
2004-08-26 08:38:43 +00:00
|
|
|
}
|
|
|
|
|
2004-08-26 12:27:39 +00:00
|
|
|
|
2004-08-26 08:38:43 +00:00
|
|
|
void
|
2004-10-22 09:58:24 +00:00
|
|
|
FGSubmodelMgr::transform( submodel* sm)
|
2004-08-26 08:38:43 +00:00
|
|
|
{
|
2004-09-07 19:10:10 +00:00
|
|
|
|
2004-09-27 14:24:20 +00:00
|
|
|
// get initial conditions
|
|
|
|
|
|
|
|
// get the weight of the contents (lbs) and convert to mass (slugs)
|
|
|
|
sm->contents = sm->contents_node->getDoubleValue();
|
|
|
|
|
|
|
|
IC.mass = (sm->weight + sm->contents) * lbs_to_slugs;;
|
|
|
|
// cout << IC.mass << endl;
|
|
|
|
|
|
|
|
// set contents to 0 in the parent
|
|
|
|
sm->contents_node->setDoubleValue(0);
|
2004-09-07 19:10:10 +00:00
|
|
|
|
|
|
|
IC.lat = _user_lat_node->getDoubleValue();
|
2004-09-22 08:47:05 +00:00
|
|
|
IC.lon = _user_lon_node->getDoubleValue();
|
2004-09-07 19:10:10 +00:00
|
|
|
IC.alt = _user_alt_node->getDoubleValue();
|
2004-09-17 16:32:58 +00:00
|
|
|
IC.roll = _user_roll_node->getDoubleValue(); // rotation about x axis
|
|
|
|
IC.elevation = _user_pitch_node->getDoubleValue(); // rotation about y axis
|
2004-09-07 19:10:10 +00:00
|
|
|
IC.azimuth = _user_heading_node->getDoubleValue(); // rotation about z axis
|
|
|
|
|
2004-09-09 08:40:08 +00:00
|
|
|
IC.speed = _user_speed_node->getDoubleValue();
|
2004-09-05 09:45:34 +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
|
|
|
|
2004-09-14 08:27:55 +00:00
|
|
|
IC.speed_down_fps = _user_speed_down_fps_node->getDoubleValue();
|
|
|
|
IC.speed_east_fps = _user_speed_east_fps_node->getDoubleValue();
|
2004-09-17 16:32:58 +00:00
|
|
|
IC.speed_north_fps = _user_speed_north_fps_node->getDoubleValue();
|
2004-09-14 08:27:55 +00:00
|
|
|
|
|
|
|
|
2004-09-07 19:10:10 +00:00
|
|
|
in[0] = sm->x_offset;
|
|
|
|
in[1] = sm->y_offset;
|
|
|
|
in[2] = sm->z_offset;
|
2004-09-27 14:24:20 +00:00
|
|
|
|
2004-09-22 08:47:05 +00:00
|
|
|
|
2004-09-07 19:10:10 +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);
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
|
|
|
// multiply the input and transform matrices
|
2004-08-26 08:38:43 +00:00
|
|
|
|
2004-09-09 08:40:08 +00:00
|
|
|
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
|
|
|
|
2004-09-09 08:40:08 +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
|
|
|
|
2004-09-09 08:40:08 +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
|
|
|
|
2004-09-09 08:40:08 +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
|
|
|
|
2004-09-09 08:40:08 +00:00
|
|
|
// get aircraft velocity vector angles in XZ and XY planes
|
|
|
|
//double alpha = _user_alpha_node->getDoubleValue();
|
|
|
|
//double velXZ = IC.elevation - alpha * cosRx;
|
|
|
|
//double velXY = IC.azimuth - (IC.elevation - alpha * sinRx);
|
|
|
|
|
|
|
|
// 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.
|
2004-09-17 16:32:58 +00:00
|
|
|
IC.elevation += (sm->yaw_offset * sinRx) + (sm->pitch_offset * cosRx);
|
2004-09-09 08:40:08 +00:00
|
|
|
IC.azimuth += (sm->yaw_offset * cosRx) - (sm->pitch_offset * sinRx);
|
|
|
|
|
|
|
|
// For now assume vector is close to airplane's vector. This needs to be fixed.
|
2004-09-14 08:27:55 +00:00
|
|
|
//IC.speed += ;
|
|
|
|
|
|
|
|
// calcuate the total speed north
|
|
|
|
|
|
|
|
IC.total_speed_north = sm->speed * cos(IC.elevation*SG_DEGREES_TO_RADIANS)*
|
|
|
|
cos(IC.azimuth*SG_DEGREES_TO_RADIANS) + IC.speed_north_fps;
|
|
|
|
|
|
|
|
// calculate the total speed east
|
|
|
|
|
|
|
|
IC.total_speed_east = sm->speed * cos(IC.elevation*SG_DEGREES_TO_RADIANS)*
|
|
|
|
sin(IC.azimuth*SG_DEGREES_TO_RADIANS) + IC.speed_east_fps;
|
|
|
|
|
|
|
|
// calculate the total speed down
|
|
|
|
|
|
|
|
IC.total_speed_down = sm->speed * -sin(IC.elevation*SG_DEGREES_TO_RADIANS) +
|
|
|
|
IC.speed_down_fps;
|
|
|
|
|
|
|
|
// re-calculate speed, elevation and azimuth
|
|
|
|
|
|
|
|
IC.speed = sqrt( IC.total_speed_north * IC.total_speed_north +
|
2004-09-22 08:47:05 +00:00
|
|
|
IC.total_speed_east * IC.total_speed_east +
|
|
|
|
IC.total_speed_down * IC.total_speed_down);
|
|
|
|
|
2004-09-14 08:27:55 +00:00
|
|
|
IC.azimuth = atan(IC.total_speed_east/IC.total_speed_north) * SG_RADIANS_TO_DEGREES;
|
|
|
|
|
|
|
|
// rationalise the output
|
|
|
|
|
|
|
|
if (IC.total_speed_north <= 0){
|
|
|
|
IC.azimuth = 180 + IC.azimuth;
|
2004-09-22 08:47:05 +00:00
|
|
|
}
|
2004-09-14 08:27:55 +00:00
|
|
|
else{
|
|
|
|
if(IC.total_speed_east <= 0){
|
|
|
|
IC.azimuth = 360 + IC.azimuth;
|
2004-09-22 08:47:05 +00:00
|
|
|
}
|
2004-09-14 08:27:55 +00:00
|
|
|
}
|
2004-09-22 08:47:05 +00:00
|
|
|
|
2004-09-17 16:32:58 +00:00
|
|
|
IC.elevation = -atan(IC.total_speed_down/sqrt(IC.total_speed_north *
|
|
|
|
IC.total_speed_north +
|
|
|
|
IC.total_speed_east * IC.total_speed_east)) * SG_RADIANS_TO_DEGREES;
|
2004-09-07 19:10:10 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-10-22 09:58:24 +00:00
|
|
|
FGSubmodelMgr::updatelat(double lat)
|
2004-09-07 19:10:10 +00:00
|
|
|
{
|
|
|
|
double latitude = lat;
|
|
|
|
ft_per_deg_latitude = 366468.96 - 3717.12 * cos(latitude / SG_RADIANS_TO_DEGREES);
|
|
|
|
ft_per_deg_longitude = 365228.16 * cos(latitude / SG_RADIANS_TO_DEGREES);
|
2004-09-05 09:45:34 +00:00
|
|
|
}
|
2004-08-26 12:27:39 +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
|
|
|
// end of submodel.cxx
|
2004-09-01 21:05:04 +00:00
|
|
|
|
2004-09-14 08:27:55 +00:00
|
|
|
|
2004-09-17 16:32:58 +00:00
|
|
|
|
2004-09-27 14:24:20 +00:00
|
|
|
|