1
0
Fork 0

Harald JOHNSEN:

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 ;
This commit is contained in:
ehofman 2005-07-31 09:04:18 +00:00
parent 17ff8ec4a6
commit 83b414482f
7 changed files with 124 additions and 30 deletions

View 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();

View 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 );

View 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);
}
}

View 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);

View 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 ) {

View 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;
};

View 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 );