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:
parent
5a8f277b88
commit
c4aa3fa661
2 changed files with 128 additions and 42 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue