1
0
Fork 0

David Culp:

Here is an update for the submodel system.  This will allow submodels to be
defined for any aircraft, and there are no default submodels.  To use this
submodel system you need to set up a binding (slight change in property name
from last one, but you can use any property name you like, as long as it
matches the name in the submodels.xml file, see below):

 <button n="0">
  <desc>Trigger</desc>
  <binding>
   <command>property-assign</command>
   <property>/systems/submodels/trigger</property>
   <value type="bool">true</value>
  </binding>
  <mod-up>
   <binding>
    <command>property-assign</command>
    <property>/systems/submodels/trigger</property>
    <value type="bool">false</value>
   </binding>
  </mod-up>
 </button>


Then in your *-set.xml file you need to define a path to the configuration
file (similar to the way the electrical system is now done):

<sim>
 ...
  <systems>
   <electrical>
    <path>Aircraft/Generic/generic-electrical.xml</path>
   </electrical>
   <submodels>
    <serviceable type="bool">true</serviceable>
    <path>Aircraft/FW190/submodels.xml</path>
   </submodels>
  </systems>
 ...
</sim>


Then you put the submodel configuration file in your aircraft's directory.
I've attached a file, submodels.xml, that can be used to define a gun that
works just like the former one did.


There are two things remaining to be done.  One is to change the function
SubmodelSystem::transform() to properly position the submodel.  This will
require some complicated matrix code that I might borrow from Yasim.
This commit is contained in:
ehofman 2004-08-26 08:38:43 +00:00
parent 5a8f277b88
commit c4aa3fa661
2 changed files with 128 additions and 42 deletions

View file

@ -4,6 +4,10 @@
// This file is in the Public Domain and comes with no warranty.
#include "submodel.hxx"
#include <simgear/structure/exception.hxx>
#include <simgear/misc/sg_path.hxx>
#include <Main/fg_props.hxx>
#include <Main/util.hxx>
#include <AIModel/AIManager.hxx>
@ -11,7 +15,6 @@
SubmodelSystem::SubmodelSystem ()
{
firing = false;
x_offset = y_offset = 0.0;
z_offset = -4.0;
pitch_offset = 2.0;
@ -25,13 +28,9 @@ SubmodelSystem::~SubmodelSystem ()
void
SubmodelSystem::init ()
{
_serviceable_node = fgGetNode("/systems/submodel/serviceable", true);
load();
_serviceable_node = fgGetNode("/sim/systems/submodels/serviceable", true);
_trigger_node = fgGetNode("/systems/submodel/trigger", true);
_trigger_node->setBoolValue(false);
_amount_node = fgGetNode("/systems/submodel/amount", true);
_user_lat_node = fgGetNode("/position/latitude-deg", true);
_user_lon_node = fgGetNode("/position/longitude-deg", true);
_user_alt_node = fgGetNode("/position/altitude-ft", true);
@ -43,9 +42,6 @@ SubmodelSystem::init ()
_user_speed_node = fgGetNode("/velocities/uBody-fps", true);
elapsed_time = 0.0;
initial_velocity = 2750.0; // feet per second, .50 caliber
ai = (FGAIManager*)globals->get_subsystem("ai_model");
}
@ -62,39 +58,95 @@ SubmodelSystem::unbind ()
void
SubmodelSystem::update (double dt)
{
if (_trigger_node->getBoolValue()) {
if (_serviceable_node->getBoolValue()) {
if (_amount_node->getIntValue() > 0) {
firing = true;
release(dt);
}
}
} else {
if (firing){
firing = false;
elapsed_time = 0.0;
}
if (!(_serviceable_node->getBoolValue())) return;
submodel_iterator = submodels.begin();
while(submodel_iterator != submodels.end()) {
if ((*submodel_iterator)->trigger->getBoolValue()) {
if ((*submodel_iterator)->count > 0) {
release( (*submodel_iterator), dt);
}
}
++submodel_iterator;
}
}
bool
SubmodelSystem::release (double dt)
SubmodelSystem::release (submodel* sm, double dt)
{
// releases a submodel every 0.25 seconds
elapsed_time += dt;
if (elapsed_time < 0.25) return false;
elapsed_time = 0.0;
sm->timer += dt;
if (sm->timer < sm->delay) return false;
sm->timer = 0.0;
int rval = ai->createBallistic( "Models/Geometry/tracer.ac",
_user_lat_node->getDoubleValue(),
_user_lon_node->getDoubleValue(),
_user_alt_node->getDoubleValue() + z_offset,
_user_heading_node->getDoubleValue() + yaw_offset,
_user_pitch_node->getDoubleValue() + pitch_offset,
_user_speed_node->getDoubleValue() + initial_velocity );
transform(sm); // calculate submodel's initial conditions in world-coordinates
_amount_node->setIntValue( _amount_node->getIntValue() - 1);
int rval = ai->createBallistic( sm->model, IC.lat, IC.lon, IC.alt, IC.azimuth,
IC.elevation, IC.speed );
sm->count--;
return true;
}
void
SubmodelSystem::load ()
{
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;
submodel* sm = new submodel;
submodels.push_back( sm );
SGPropertyNode * entry_node = root.getChild(i);
sm->trigger = fgGetNode(entry_node->getStringValue("trigger", "none"), true);
sm->name = entry_node->getStringValue("name", "none_defined");
sm->model = entry_node->getStringValue("model", "Models/Geometry/tracer.ac");
sm->speed = entry_node->getDoubleValue("speed", 0.0);
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->trigger->setBoolValue(false);
sm->timer = 0.0;
}
submodel_iterator = submodels.begin();
// cout << submodels.size() << " submodels read." << endl;
}
void
SubmodelSystem::transform( submodel* sm)
{
IC.lat = _user_lat_node->getDoubleValue();
IC.lon = _user_lon_node->getDoubleValue();
IC.alt = _user_alt_node->getDoubleValue();
IC.azimuth = _user_heading_node->getDoubleValue() + sm->yaw_offset;
IC.elevation = _user_pitch_node->getDoubleValue() + sm->pitch_offset;
IC.speed = _user_speed_node->getDoubleValue() + sm->speed;
}
// end of submodel.cxx

View file

@ -14,6 +14,10 @@
#include <simgear/props/props.hxx>
#include <simgear/structure/subsystem_mgr.hxx>
#include <AIModel/AIManager.hxx>
#include <vector>
#include <string>
SG_USING_STD(vector);
SG_USING_STD(string);
class SubmodelSystem : public SGSubsystem
@ -21,24 +25,56 @@ class SubmodelSystem : public SGSubsystem
public:
typedef struct {
SGPropertyNode_ptr trigger;
string name;
string model;
double speed;
bool slaved;
bool repeat;
double delay;
double timer;
int count;
double x_offset;
double y_offset;
double z_offset;
double yaw_offset;
double pitch_offset;
} submodel;
typedef struct {
double lat;
double lon;
double alt;
double azimuth;
double elevation;
double speed;
} IC_struct;
SubmodelSystem ();
~SubmodelSystem ();
void load ();
void init ();
void bind ();
void unbind ();
void update (double dt);
bool release (double dt);
bool release (submodel* sm, double dt);
void transform (submodel* sm);
private:
typedef vector <submodel*> submodel_vector_type;
typedef submodel_vector_type::iterator submodel_vector_iterator;
submodel_vector_type submodels;
submodel_vector_iterator submodel_iterator;
double x_offset, y_offset, z_offset;
double pitch_offset, yaw_offset;
SGPropertyNode_ptr _serviceable_node;
SGPropertyNode_ptr _trigger_node;
SGPropertyNode_ptr _amount_node;
SGPropertyNode_ptr _user_lat_node;
SGPropertyNode_ptr _user_lon_node;
SGPropertyNode_ptr _user_heading_node;
@ -48,10 +84,8 @@ private:
SGPropertyNode_ptr _user_yaw_node;
SGPropertyNode_ptr _user_speed_node;
double elapsed_time;
FGAIManager* ai;
double initial_velocity;
bool firing;
IC_struct IC;
};
#endif // __SYSTEMS_SUBMODEL_HXX