]> git.mxchange.org Git - flightgear.git/commitdiff
Harald JOHNSEN:
authorehofman <ehofman>
Sun, 31 Jul 2005 09:04:18 +0000 (09:04 +0000)
committerehofman <ehofman>
Sun, 31 Jul 2005 09:04:18 +0000 (09:04 +0000)
I did some profiling of the code and found a few interessant things. Some corrections are obvious like the one in the multiplayer code, the fps is no more divided by 2 or 3 when another plane is on screen.

Other things like collision detection and computation of agl can not really be optimized. I changed a few things in hitlist.cxx but this only give a very low increase of fps. The groundcache eats a lot of cpu but I think that the real way to do it is to use a real collision system like OPCODE or something like that.

And I added an option to disable the recording of replay data. It takes more cpu than we can think.

Changes
=======

- panel.cxx :
  moved the computation of the instruments diffuse color outside the texturelayer code
  since this is constant during a frame, this is a big speedup for 2D panels ;

- hitlist.cxx :
  changed the computation of the intersection between ray and triangle, optimized
  the sphere culling by using a normalized direction vector. This can give a
  35% speedup on the computation of elevation in some situations ;

- renderer.cxx, acmodel.cxx :
  call ssgDrawAndCull with plane scene graph in external or internal view,
  calling ssgDrawAndCull with the root scene graph was drawing other players plane
  a second time in multiplayer mode ;

- mplayer.cxx :
  removed the calls to ssgFlatten and ssgStripify because it was degenerating models,
  causing a massive drop in frame rate ;

- replay.cxx :
  added an option to disable the recording of the flight

- fgclouds.cxx :
  changed the path of cloudlayer properties to match preferences.xml ;
  set the altitude of clouds from scenarios to a more correct value if metar is not enabled ;

src/Environment/fgclouds.cxx
src/Main/renderer.cxx
src/Model/acmodel.cxx
src/MultiPlayer/mpplayer.cxx
src/Replay/replay.cxx
src/Replay/replay.hxx
src/Scenery/hitlist.cxx

index b61a5510147dcb78993ce8cbb42861d4738dbd4b..044fb885f50536e85c978441b4ed5ea991ca463e 100644 (file)
@@ -108,8 +108,8 @@ void FGClouds::buildLayer(SGCloudField *layer, string name, double alt, double c
        int CloudVarietyCount = 0;
        double totalCount = 0.0;
 
-       SGPropertyNode *cloud_def_root = fgGetNode("/environment/config/cloudlayers/clouds", false);
-       SGPropertyNode *layer_def_root = fgGetNode("/environment/config/cloudlayers/layers", false);
+       SGPropertyNode *cloud_def_root = fgGetNode("/environment/cloudlayers/clouds", false);
+       SGPropertyNode *layer_def_root = fgGetNode("/environment/cloudlayers/layers", false);
 
        layer->clear();
        // when we don't generate clouds the layer is rendered in 2D
@@ -395,8 +395,12 @@ void FGClouds::buildScenario( string scenario ) {
        string station = fgGetString("/environment/metar/station-id", "XXXX");
 
        // fetch station elevation if exists
-    FGAirport a = globals->get_airports()->search( station );
-    station_elevation_ft = a.getElevation();
+    if( station == "XXXX" )
+        station_elevation_ft = fgGetDouble("/position/ground-elev-m", 0.0);
+    else {
+        FGAirport a = globals->get_airports()->search( station );
+        station_elevation_ft = a.getElevation();
+    }
 
        for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) {
                thesky->get_cloud_layer(iLayer)->get_layer3D()->clear();
index fe79a0425995790e44e904a1e362f10b5832f0be..05b85037b78deab076ebd3e8360f882fd6423835 100644 (file)
@@ -383,7 +383,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
         */
 
         static SGSkyColor scolor;
-        FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
+//        FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
 
         scolor.sky_color   = l->sky_color();
         scolor.fog_color   = l->adj_fog_color();
@@ -711,17 +711,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
         globals->get_aircraft_model()->select( true );
         globals->get_model_mgr()->draw();
         globals->get_aircraft_model()->draw();
-        // If the view is internal, the previous line draw the 
-        //  cockpit with modified near/far clip planes and deselect
-        //  the aircraft in the global scenegraph
-        // Otherwise, it just enables the aircraft: The scenegraph
-        //  must be drawn again to see the plane.
-        ssgBranch *branch = globals->get_scenery()->get_aircraft_branch();
-        // in external view the shadows are drawn before the transparent parts of the ac
-        if( ! is_internal )
-            branch->setTravCallback( SSG_CALLBACK_POSTTRAV, SGShadowVolume::ACpostTravCB);
-        ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
-        branch->setTravCallback( SSG_CALLBACK_POSTTRAV, 0);
+
         FGTileMgr::set_tile_filter( true );
         sgSetModelFilter( true );
         globals->get_aircraft_model()->select( true );
index 662a4a4b81913622c8a4659206978602f7b12f68..e28e100459f94099c4100ddb283d8de593e49fd6 100644 (file)
@@ -17,6 +17,7 @@
 #include <simgear/structure/exception.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/scene/model/placement.hxx>
+#include <simgear/scene/model/shadowvolume.hxx>
 
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
@@ -133,6 +134,10 @@ FGAircraftModel::draw ()
     _selector->select(0);
   } else {
     _selector->select(1);
+    // in external view the shadows are drawn before the transparent parts of the ac
+    _scene->setTravCallback( SSG_CALLBACK_POSTTRAV, SGShadowVolume::ACpostTravCB);
+    ssgCullAndDraw(_scene);
+    _scene->setTravCallback( SSG_CALLBACK_POSTTRAV, 0);
   }
 
 }
index 90a4f8e480fa67e7f3b32a50587922c8f8f74f0e..8a97280a3341ce38616910eeacc1ed08bfb5b118 100644 (file)
@@ -146,7 +146,7 @@ void MPPlayer::Close(void) {
 
         // Flush the model loader so that it erases the model from its list of
         // models.
-        globals->get_model_lib()->flush1();
+//        globals->get_model_lib()->flush1();
 
         // Assume that plib/ssg deletes the model and transform as their
         // refcounts should be zero.
@@ -263,10 +263,6 @@ void MPPlayer::LoadModel(void) {
     // Add model to transform
     m_ModelTrans->addKid( m_Model );
 
-    // Optimise model and transform
-    ssgFlatten( m_Model );
-    ssgStripify( m_ModelTrans );
-
     // Place on scene under aircraft branch
     globals->get_scenery()->get_aircraft_branch()->addKid( m_ModelTrans );
     globals->get_scenery()->register_placement_transform( m_ModelTrans);
index c91b41c487277078842191225e19349051490469..b9475c6ec87d80469be673b4daa40195049b6196 100644 (file)
@@ -84,7 +84,7 @@ void FGReplay::init() {
  */
 
 void FGReplay::bind() {
-    // nothing to bind
+    disable_replay = fgGetNode( "/sim/replay/disable", true );
 }
 
 
@@ -105,6 +105,9 @@ void FGReplay::update( double dt ) {
     static SGPropertyNode *replay_master
         = fgGetNode( "/sim/freeze/replay", true );
 
+    if( disable_replay->getBoolValue() )
+        return;
+
     if ( replay_master->getBoolValue() ) {
         // don't record the replay session
         return;
@@ -259,7 +262,7 @@ static FGReplayData interpolate( double time, FGReplayData f1, FGReplayData f2 )
     result.fdm.A_Y_pilot = weight( fdm1.A_Y_pilot, fdm2.A_Y_pilot, ratio );
     result.fdm.A_Z_pilot = weight( fdm1.A_Z_pilot, fdm2.A_Z_pilot, ratio );
 
-    int i;
+    unsigned int i;
 
     // Engine status
     for ( i = 0; i < fdm1.num_engines; ++i ) {
index 90367beb0e79f66b099c964a23b51c99caf91fa1..a2a8deee7a6f93d64b55c754098f07139e098342 100644 (file)
@@ -94,6 +94,7 @@ private:
     replay_list_type short_term;
     replay_list_type medium_term;
     replay_list_type long_term;
+    SGPropertyNode_ptr disable_replay;
 };
 
 
index fa5781c61799c9d34c8d0608b44d657157f95588..310d06190b89e44569341c75834e6453cb7a9504 100644 (file)
@@ -240,6 +240,85 @@ FGHitList::FGHitList() :
 FGHitList::~FGHitList() {}
 
 
+// http://www.cs.lth.se/home/Tomas_Akenine_Moller/raytri/raytri.c
+// http://little3d.free.fr/ressources/jgt%20Fast,%20Minumum%20Storage%20Ray-Triangle%20Intersection.htm
+// http://www.acm.org/jgt/papers/MollerTrumbore97/
+
+/* Ray-Triangle Intersection Test Routines          */
+/* Different optimizations of my and Ben Trumbore's */
+/* code from journals of graphics tools (JGT)       */
+/* http://www.acm.org/jgt/                          */
+/* by Tomas Moller, May 2000                        */
+
+/* code rewritten to do tests on the sign of the determinant */
+/* the division is at the end in the code                    */
+// cosmetics change by H.J :
+// make u & v locals since we don't use them, use sg functions
+static bool intersect_triangle(const double orig[3], const double dir[3],
+                       const double vert0[3], const double vert1[3], const double vert2[3],
+                       double *t)
+{
+   double u, v;
+   double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
+
+   const SGDfloat eps = 1e-4;
+
+   /* find vectors for two edges sharing vert0 */
+   sgdSubVec3(edge1, vert1, vert0);
+   sgdSubVec3(edge2, vert2, vert0);
+
+   /* begin calculating determinant - also used to calculate U parameter */
+   sgdVectorProductVec3(pvec, dir, edge2);
+
+   /* if determinant is near zero, ray lies in plane of triangle */
+   double det = sgdScalarProductVec3(edge1, pvec);
+
+   if (det > eps)
+   {
+      /* calculate distance from vert0 to ray origin */
+      sgdSubVec3(tvec, orig, vert0);
+
+      /* calculate U parameter and test bounds */
+      u = sgdScalarProductVec3(tvec, pvec);
+      if (u < 0.0 || u > det)
+        return false;
+
+      /* prepare to test V parameter */
+      sgdVectorProductVec3(qvec, tvec, edge1);
+
+      /* calculate V parameter and test bounds */
+      v = sgdScalarProductVec3(dir, qvec);
+      if (v < 0.0 || u + v > det)
+        return false;
+
+   }
+   else if(det < -eps)
+   {
+      /* calculate distance from vert0 to ray origin */
+      sgdSubVec3(tvec, orig, vert0);
+
+      /* calculate U parameter and test bounds */
+      u = sgdScalarProductVec3(tvec, pvec);
+      if (u > 0.0 || u < det)
+        return false;
+
+      /* prepare to test V parameter */
+      sgdVectorProductVec3(qvec, tvec, edge1);
+
+      /* calculate V parameter and test bounds */
+      v = sgdScalarProductVec3(dir, qvec) ;
+      if (v > 0.0 || u + v < det)
+        return false;
+   }
+   else return false;  /* ray is parallell to the plane of the triangle */
+
+   /* calculate t, ray intersects triangle */
+   *t = sgdScalarProductVec3(edge2, qvec) / det;
+
+   return true;
+}
+
+
 /*
 Find the intersection of an infinite line with a leaf the line being
 defined by a point and direction.
@@ -280,7 +359,21 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
         sgdSetVec3( tri[0], leaf->getVertex( i1 ) );
         sgdSetVec3( tri[1], leaf->getVertex( i2 ) );
         sgdSetVec3( tri[2], leaf->getVertex( i3 ) );
-
+#if 1
+        sgdFloat t;
+        if( intersect_triangle( orig, dir, tri[0], tri[1], tri[2], &t) ) {
+            sgdVec4 plane;
+            sgdMakePlane( plane, tri[0], tri[1], tri[2] );
+            // t is the distance to the triangle plane
+            // so P = Orig + t*dir
+            sgdVec3 point;
+            sgdAddScaledVec3( point, orig, dir, t );
+            sgdXformPnt3( point, point, m );
+            sgdXformPnt4(plane,plane,m);
+            add(leaf,i,point,plane);
+            num_hits++;
+        }
+#else
         if( isZeroAreaTri( tri ) )
             continue;
 
@@ -292,11 +385,12 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
             if( fgdPointInTriangle( point, tri ) ) {
                 // transform point into passed into desired coordinate frame
                 sgdXformPnt3( point, point, m );
-               sgdXformPnt4(plane,plane,m);
+                sgdXformPnt4(plane,plane,m);
                 add(leaf,i,point,plane);
                 num_hits++;
             }
         }
+#endif
     }
     return num_hits;
 }
@@ -443,18 +537,18 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
              && !kid->getBSphere()->isEmpty() )
         {
             sgdVec3 center;
+            const sgFloat *BSCenter = kid->getBSphere()->getCenter();
             sgdSetVec3( center,
-                        kid->getBSphere()->getCenter()[0],
-                        kid->getBSphere()->getCenter()[1],
-                        kid->getBSphere()->getCenter()[2] );
+                        BSCenter[0],
+                        BSCenter[1],
+                        BSCenter[2] );
             sgdXformPnt3( center, m ) ;
 
             // sgdClosestPointToLineDistSquared( center, orig, dir )
             // inlined here because because of profiling results
             sgdVec3 u, u1, v;
             sgdSubVec3(u, center, orig);
-            sgdScaleVec3( u1, dir, sgdScalarProductVec3(u,dir)
-                          / sgdScalarProductVec3(dir,dir) );
+            sgdScaleVec3( u1, dir, sgdScalarProductVec3(u,dir)  );
             sgdSubVec3(v, u, u1);
 
             // double because of possible overflow
@@ -533,6 +627,7 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
     sgdCopyVec3(orig, view_pos );
     sgdCopyVec3(dir, abs_view_pos );
 
+    sgdNormaliseVec3( dir );
     hit_list->Intersect( globals->get_scenery()->get_terrain_branch(),
                          orig, dir );