]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AICarrier.cxx
Enable Ballistic objects to be slaved to any AI Object.
[flightgear.git] / src / AIModel / AICarrier.cxx
index 4e98e29acc60e299b3119514ffb39bd909a8abfc..b6487519d026c05ea55bc026423f093d30ce9375 100644 (file)
 #include <string>
 #include <vector>
 
-#include <osg/Geode>
-#include <osg/Drawable>
-#include <osg/Transform>
-#include <osg/NodeVisitor>
-#include <osg/TemplatePrimitiveFunctor>
-
 #include <simgear/sg_inlines.h>
 #include <simgear/math/SGMath.hxx>
 #include <simgear/math/sg_geodesy.hxx>
-#include <simgear/scene/util/SGSceneUserData.hxx>
-#include <simgear/scene/bvh/BVHGroup.hxx>
-#include <simgear/scene/bvh/BVHLineGeometry.hxx>
 
 #include <math.h>
 #include <Main/util.hxx>
 
 #include "AICarrier.hxx"
 
-/// Hmm: move that kind of configuration into the model file???
-class LineCollector : public osg::NodeVisitor {
-    struct LinePrimitiveFunctor {
-        LinePrimitiveFunctor() : _lineCollector(0)
-        { }
-        void operator() (const osg::Vec3&, bool)
-        { }
-        void operator() (const osg::Vec3& v1, const osg::Vec3& v2, bool)
-        { if (_lineCollector) _lineCollector->addLine(v1, v2); }
-        void operator() (const osg::Vec3&, const osg::Vec3&, const osg::Vec3&,
-                         bool)
-        { }
-        void operator() (const osg::Vec3&, const osg::Vec3&, const osg::Vec3&,
-                         const osg::Vec3&, bool)
-        { }
-        LineCollector* _lineCollector;
-    };
-    
-public:
-    LineCollector() :
-        osg::NodeVisitor(osg::NodeVisitor::NODE_VISITOR,
-                         osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
-    { }
-    virtual void apply(osg::Geode& geode)
-    {
-        osg::TemplatePrimitiveFunctor<LinePrimitiveFunctor> pf;
-        pf._lineCollector = this;
-        for (unsigned i = 0; i < geode.getNumDrawables(); ++i) {
-            geode.getDrawable(i)->accept(pf);
-        }
-    }
-    virtual void apply(osg::Node& node)
-    {
-        traverse(node);
-    }
-    virtual void apply(osg::Transform& transform)
-    {
-        osg::Matrix matrix = _matrix;
-        if (transform.computeLocalToWorldMatrix(_matrix, this))
-            traverse(transform);
-        _matrix = matrix;
-    }
-    
-    const std::vector<SGLineSegmentf>& getLineSegments() const
-    { return _lineSegments; }
-    
-    void addLine(const osg::Vec3& v1, const osg::Vec3& v2)
-    {
-        // Trick to get the ends in the right order.
-        // Use the x axis in the original coordinate system. Choose the
-        // most negative x-axis as the one pointing forward
-        SGVec3f tv1(_matrix.preMult(v1));
-        SGVec3f tv2(_matrix.preMult(v2));
-        if (tv1[0] > tv2[0])
-            _lineSegments.push_back(SGLineSegmentf(tv1, tv2));
-        else
-            _lineSegments.push_back(SGLineSegmentf(tv2, tv1));
-    }
-
-    void addBVHElements(osg::Node& node, simgear::BVHLineGeometry::Type type)
-    {
-        if (_lineSegments.empty())
-            return;
-
-        SGSceneUserData* userData;
-        userData = SGSceneUserData::getOrCreateSceneUserData(&node);
-
-        simgear::BVHNode* bvNode = userData->getBVHNode();
-        if (!bvNode && _lineSegments.size() == 1) {
-            simgear::BVHLineGeometry* bvLine;
-            bvLine = new simgear::BVHLineGeometry(_lineSegments.front(), type);
-            userData->setBVHNode(bvLine);
-            return;
-        }
-
-        simgear::BVHGroup* group = new simgear::BVHGroup;
-        if (bvNode)
-            group->addChild(bvNode);
-
-        for (unsigned i = 0; i < _lineSegments.size(); ++i) {
-            simgear::BVHLineGeometry* bvLine;
-            bvLine = new simgear::BVHLineGeometry(_lineSegments[i], type);
-            group->addChild(bvLine);
-        }
-        userData->setBVHNode(group);
-    }
-    
-private:
-    osg::Matrix _matrix;
-    std::vector<SGLineSegmentf> _lineSegments;
-};
-
-class FGCarrierVisitor : public osg::NodeVisitor {
-public:
-    FGCarrierVisitor(FGAICarrier* carrier,
-                     const std::list<std::string>& wireObjects,
-                     const std::list<std::string>& catapultObjects) :
-        osg::NodeVisitor(osg::NodeVisitor::NODE_VISITOR,
-                         osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
-        mWireObjects(wireObjects),
-        mCatapultObjects(catapultObjects)
-    { }
-    virtual void apply(osg::Node& node)
-    {
-        if (std::find(mWireObjects.begin(), mWireObjects.end(), node.getName())
-            != mWireObjects.end()) {
-            LineCollector lineCollector;
-            node.accept(lineCollector);
-            simgear::BVHLineGeometry::Type type;
-            type = simgear::BVHLineGeometry::CarrierWire;
-            lineCollector.addBVHElements(node, type);
-        }
-        if (std::find(mCatapultObjects.begin(), mCatapultObjects.end(),
-                      node.getName()) != mCatapultObjects.end()) {
-            LineCollector lineCollector;
-            node.accept(lineCollector);
-            simgear::BVHLineGeometry::Type type;
-            type = simgear::BVHLineGeometry::CarrierCatapult;
-            lineCollector.addBVHElements(node, type);
-        }
-        
-        traverse(node);
-    }
-    
-private:
-    std::list<std::string> mWireObjects;
-    std::list<std::string> mCatapultObjects;
-};
-
 FGAICarrier::FGAICarrier() : FGAIShip(otCarrier) {
 }
 
@@ -195,6 +57,7 @@ void FGAICarrier::readFromScenario(SGPropertyNode* scFileNode) {
   setMaxLong(scFileNode->getDoubleValue("max-long", 0));
   setMinLong(scFileNode->getDoubleValue("min-long", 0));
   setMPControl(scFileNode->getBoolValue("mp-control", false));
+  setAIControl(scFileNode->getBoolValue("ai-control", false));
 
   SGPropertyNode* flols = scFileNode->getChild("flols-pos");
   if (flols) {
@@ -207,22 +70,8 @@ void FGAICarrier::readFromScenario(SGPropertyNode* scFileNode) {
   } else
     flols_off = SGVec3d::zeros();
 
-  std::vector<SGPropertyNode_ptr> props = scFileNode->getChildren("wire");
+  std::vector<SGPropertyNode_ptr> props = scFileNode->getChildren("parking-pos");
   std::vector<SGPropertyNode_ptr>::const_iterator it;
-  for (it = props.begin(); it != props.end(); ++it) {
-    std::string s = (*it)->getStringValue();
-    if (!s.empty())
-      wire_objects.push_back(s);
-  }
-
-  props = scFileNode->getChildren("catapult");
-  for (it = props.begin(); it != props.end(); ++it) {
-    std::string s = (*it)->getStringValue();
-    if (!s.empty())
-      catapult_objects.push_back(s);
-  }
-
-  props = scFileNode->getChildren("parking-pos");
   for (it = props.begin(); it != props.end(); ++it) {
     string name = (*it)->getStringValue("name", "unnamed");
     // Transform to the right coordinate frame, configuration is done in
@@ -273,21 +122,25 @@ void FGAICarrier::setMPControl(bool c) {
     MPControl = c;
 }
 
+void FGAICarrier::setAIControl(bool c) {
+    AIControl = c;
+}
+
 void FGAICarrier::update(double dt) {
     // Now update the position and heading. This will compute new hdg and
     // roll values required for the rotation speed computation.
     FGAIShip::update(dt);
 
     //automatic turn into wind with a target wind of 25 kts otd
-    //SG_LOG(SG_GENERAL, SG_ALERT, "AICarrier: MPControl " << MPControl );
-    if (!MPControl){
+    //SG_LOG(SG_GENERAL, SG_ALERT, "AICarrier: MPControl " << MPControl << " AIControl " << AIControl);
+    if (!MPControl && AIControl){
 
         if(turn_to_launch_hdg){
             TurnToLaunch();
         } else if(turn_to_recovery_hdg ){
             TurnToRecover();
-        } else if(OutsideBox() || returning ) {// check that the carrier is inside 
-            ReturnToBox();                     // the operating box,  
+        } else if(OutsideBox() || returning ) {// check that the carrier is inside
+            ReturnToBox();                     // the operating box,
         } else {
             TurnToBase();
         }
@@ -320,10 +173,10 @@ void FGAICarrier::update(double dt) {
     eyeWrtCarrier = ec2body.transform(eyeWrtCarrier);
     // the eyepoints vector wrt the flols position
     SGVec3d eyeWrtFlols = eyeWrtCarrier - flols_off;
-    
+
     // the distance from the eyepoint to the flols
     dist = norm(eyeWrtFlols);
-    
+
     // now the angle, positive angles are upwards
     if (fabs(dist) < SGLimits<float>::min()) {
       angle = 0;
@@ -332,7 +185,7 @@ void FGAICarrier::update(double dt) {
       sAngle = SGMiscd::min(1, SGMiscd::max(-1, sAngle));
       angle = SGMiscd::rad2deg(asin(sAngle));
     }
-    
+
     // set the value of source
     if ( angle <= 4.35 && angle > 4.01 )
       source = 1;
@@ -387,16 +240,6 @@ bool FGAICarrier::init(bool search_in_AI_path) {
     return true;
 }
 
-void FGAICarrier::initModel(osg::Node *node)
-{
-    // SG_LOG(SG_GENERAL, SG_BULK, "AICarrier::initModel()" );
-    FGAIShip::initModel(node);
-    // process the 3d model here
-    // mark some objects solid, mark the wires ...
-    FGCarrierVisitor carrierVisitor(this, wire_objects, catapult_objects);
-    node->accept(carrierVisitor);
-}
-
 void FGAICarrier::bind() {
     FGAIShip::bind();
 
@@ -421,9 +264,9 @@ void FGAICarrier::bind() {
     props->tie("controls/start-pos-long-deg",
                SGRawValueMethods<SGGeod,double>(pos, &SGGeod::getLongitudeDeg));
     props->tie("controls/mp-control",
-        SGRawValuePointer<bool>(&MPControl));
-    props->tie("velocities/speed-kts",
-                SGRawValuePointer<double>(&speed));
+                SGRawValuePointer<bool>(&MPControl));
+    props->tie("controls/ai-control",
+                SGRawValuePointer<bool>(&AIControl));
     props->tie("environment/surface-wind-speed-true-kts",
                 SGRawValuePointer<double>(&wind_speed_kts));
     props->tie("environment/surface-wind-from-true-degs",
@@ -436,8 +279,8 @@ void FGAICarrier::bind() {
                 SGRawValuePointer<double>(&rel_wind_speed_kts));
     props->tie("environment/in-to-wind",
         SGRawValuePointer<bool>(&in_to_wind));
-    props->tie("controls/flols/wave-off-lights",
-                SGRawValuePointer<bool>(&wave_off_lights));
+    //props->tie("controls/flols/wave-off-lights",
+    //            SGRawValuePointer<bool>(&wave_off_lights));
     props->tie("controls/elevators",
                 SGRawValuePointer<bool>(&elevators));
     props->tie("surface-positions/elevators-pos-norm",
@@ -479,13 +322,12 @@ void FGAICarrier::unbind() {
     props->untie("controls/flols/distance-m");
     props->untie("controls/flols/angle-degs");
     props->untie("controls/turn-to-launch-hdg");
-    props->untie("velocities/speed-kts");
     props->untie("environment/wind-speed-true-kts");
     props->untie("environment/wind-from-true-degs");
     props->untie("environment/rel-wind-from-degs");
     props->untie("environment/rel-wind-speed-kts");
     props->untie("environment/in-to-wind");
-    props->untie("controls/flols/wave-off-lights");
+    //props->untie("controls/flols/wave-off-lights");
     props->untie("controls/elevators");
     props->untie("surface-positions/elevators-pos-norm");
     props->untie("controls/constants/elevators/trans-time-secs");
@@ -495,6 +337,7 @@ void FGAICarrier::unbind() {
     props->untie("controls/constants/jbd/trans-time-s");
     props->untie("controls/jbd-time-constant");
     props->untie("controls/mp-control");
+    props->untie("controls/ai-control");
     props->untie("controls/turn-to-recovery-hdg");
     props->untie("controls/turn-to-base-course");
 }
@@ -556,11 +399,14 @@ void FGAICarrier::UpdateWind( double dt) {
     rel_wind = rel_wind_from_deg - hdg;
     SG_NORMALIZE_RANGE(rel_wind, -180.0, 180.0);
 
+    //set in to wind property
+    InToWind();
+
     //switch the wave-off lights
-    if (InToWind())
-       wave_off_lights = false;
-    else
-       wave_off_lights = true;
+    //if (InToWind())
+    //   wave_off_lights = false;
+    //else
+    //   wave_off_lights = true;
 
     // cout << "rel wind: " << rel_wind << endl;
 
@@ -595,12 +441,12 @@ void FGAICarrier::TurnToRecover(){
     if (wind_speed_kts < 3){
         tgt_heading = base_course + 60;
     } else if (rel_wind < -9 && rel_wind >= -180){
-        tgt_heading = wind_from_deg; 
+        tgt_heading = wind_from_deg;
     } else if (rel_wind > -7 && rel_wind < 45){
         tgt_heading = wind_from_deg + 60;
     } else if (rel_wind >=45 && rel_wind < 180){
         tgt_heading = wind_from_deg + 45;
-    } else 
+    } else
         tgt_heading = hdg;
 
     SG_NORMALIZE_RANGE(tgt_heading, 0.0, 360.0);