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:
parent
17ff8ec4a6
commit
83b414482f
7 changed files with 124 additions and 30 deletions
|
@ -108,8 +108,8 @@ void FGClouds::buildLayer(SGCloudField *layer, string name, double alt, double c
|
||||||
int CloudVarietyCount = 0;
|
int CloudVarietyCount = 0;
|
||||||
double totalCount = 0.0;
|
double totalCount = 0.0;
|
||||||
|
|
||||||
SGPropertyNode *cloud_def_root = fgGetNode("/environment/config/cloudlayers/clouds", false);
|
SGPropertyNode *cloud_def_root = fgGetNode("/environment/cloudlayers/clouds", false);
|
||||||
SGPropertyNode *layer_def_root = fgGetNode("/environment/config/cloudlayers/layers", false);
|
SGPropertyNode *layer_def_root = fgGetNode("/environment/cloudlayers/layers", false);
|
||||||
|
|
||||||
layer->clear();
|
layer->clear();
|
||||||
// when we don't generate clouds the layer is rendered in 2D
|
// 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");
|
string station = fgGetString("/environment/metar/station-id", "XXXX");
|
||||||
|
|
||||||
// fetch station elevation if exists
|
// fetch station elevation if exists
|
||||||
FGAirport a = globals->get_airports()->search( station );
|
if( station == "XXXX" )
|
||||||
station_elevation_ft = a.getElevation();
|
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++) {
|
for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) {
|
||||||
thesky->get_cloud_layer(iLayer)->get_layer3D()->clear();
|
thesky->get_cloud_layer(iLayer)->get_layer3D()->clear();
|
||||||
|
|
|
@ -383,7 +383,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static SGSkyColor scolor;
|
static SGSkyColor scolor;
|
||||||
FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
|
// FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
|
||||||
|
|
||||||
scolor.sky_color = l->sky_color();
|
scolor.sky_color = l->sky_color();
|
||||||
scolor.fog_color = l->adj_fog_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_aircraft_model()->select( true );
|
||||||
globals->get_model_mgr()->draw();
|
globals->get_model_mgr()->draw();
|
||||||
globals->get_aircraft_model()->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 );
|
FGTileMgr::set_tile_filter( true );
|
||||||
sgSetModelFilter( true );
|
sgSetModelFilter( true );
|
||||||
globals->get_aircraft_model()->select( true );
|
globals->get_aircraft_model()->select( true );
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
#include <simgear/scene/model/placement.hxx>
|
#include <simgear/scene/model/placement.hxx>
|
||||||
|
#include <simgear/scene/model/shadowvolume.hxx>
|
||||||
|
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
@ -133,6 +134,10 @@ FGAircraftModel::draw ()
|
||||||
_selector->select(0);
|
_selector->select(0);
|
||||||
} else {
|
} else {
|
||||||
_selector->select(1);
|
_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,7 +146,7 @@ void MPPlayer::Close(void) {
|
||||||
|
|
||||||
// Flush the model loader so that it erases the model from its list of
|
// Flush the model loader so that it erases the model from its list of
|
||||||
// models.
|
// models.
|
||||||
globals->get_model_lib()->flush1();
|
// globals->get_model_lib()->flush1();
|
||||||
|
|
||||||
// Assume that plib/ssg deletes the model and transform as their
|
// Assume that plib/ssg deletes the model and transform as their
|
||||||
// refcounts should be zero.
|
// refcounts should be zero.
|
||||||
|
@ -263,10 +263,6 @@ void MPPlayer::LoadModel(void) {
|
||||||
// Add model to transform
|
// Add model to transform
|
||||||
m_ModelTrans->addKid( m_Model );
|
m_ModelTrans->addKid( m_Model );
|
||||||
|
|
||||||
// Optimise model and transform
|
|
||||||
ssgFlatten( m_Model );
|
|
||||||
ssgStripify( m_ModelTrans );
|
|
||||||
|
|
||||||
// Place on scene under aircraft branch
|
// Place on scene under aircraft branch
|
||||||
globals->get_scenery()->get_aircraft_branch()->addKid( m_ModelTrans );
|
globals->get_scenery()->get_aircraft_branch()->addKid( m_ModelTrans );
|
||||||
globals->get_scenery()->register_placement_transform( m_ModelTrans);
|
globals->get_scenery()->register_placement_transform( m_ModelTrans);
|
||||||
|
|
|
@ -84,7 +84,7 @@ void FGReplay::init() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void FGReplay::bind() {
|
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
|
static SGPropertyNode *replay_master
|
||||||
= fgGetNode( "/sim/freeze/replay", true );
|
= fgGetNode( "/sim/freeze/replay", true );
|
||||||
|
|
||||||
|
if( disable_replay->getBoolValue() )
|
||||||
|
return;
|
||||||
|
|
||||||
if ( replay_master->getBoolValue() ) {
|
if ( replay_master->getBoolValue() ) {
|
||||||
// don't record the replay session
|
// don't record the replay session
|
||||||
return;
|
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_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 );
|
result.fdm.A_Z_pilot = weight( fdm1.A_Z_pilot, fdm2.A_Z_pilot, ratio );
|
||||||
|
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
// Engine status
|
// Engine status
|
||||||
for ( i = 0; i < fdm1.num_engines; ++i ) {
|
for ( i = 0; i < fdm1.num_engines; ++i ) {
|
||||||
|
|
|
@ -94,6 +94,7 @@ private:
|
||||||
replay_list_type short_term;
|
replay_list_type short_term;
|
||||||
replay_list_type medium_term;
|
replay_list_type medium_term;
|
||||||
replay_list_type long_term;
|
replay_list_type long_term;
|
||||||
|
SGPropertyNode_ptr disable_replay;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -240,6 +240,85 @@ FGHitList::FGHitList() :
|
||||||
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
|
Find the intersection of an infinite line with a leaf the line being
|
||||||
defined by a point and direction.
|
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[0], leaf->getVertex( i1 ) );
|
||||||
sgdSetVec3( tri[1], leaf->getVertex( i2 ) );
|
sgdSetVec3( tri[1], leaf->getVertex( i2 ) );
|
||||||
sgdSetVec3( tri[2], leaf->getVertex( i3 ) );
|
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 ) )
|
if( isZeroAreaTri( tri ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -292,11 +385,12 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||||
if( fgdPointInTriangle( point, tri ) ) {
|
if( fgdPointInTriangle( point, tri ) ) {
|
||||||
// transform point into passed into desired coordinate frame
|
// transform point into passed into desired coordinate frame
|
||||||
sgdXformPnt3( point, point, m );
|
sgdXformPnt3( point, point, m );
|
||||||
sgdXformPnt4(plane,plane,m);
|
sgdXformPnt4(plane,plane,m);
|
||||||
add(leaf,i,point,plane);
|
add(leaf,i,point,plane);
|
||||||
num_hits++;
|
num_hits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return num_hits;
|
return num_hits;
|
||||||
}
|
}
|
||||||
|
@ -443,18 +537,18 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
||||||
&& !kid->getBSphere()->isEmpty() )
|
&& !kid->getBSphere()->isEmpty() )
|
||||||
{
|
{
|
||||||
sgdVec3 center;
|
sgdVec3 center;
|
||||||
|
const sgFloat *BSCenter = kid->getBSphere()->getCenter();
|
||||||
sgdSetVec3( center,
|
sgdSetVec3( center,
|
||||||
kid->getBSphere()->getCenter()[0],
|
BSCenter[0],
|
||||||
kid->getBSphere()->getCenter()[1],
|
BSCenter[1],
|
||||||
kid->getBSphere()->getCenter()[2] );
|
BSCenter[2] );
|
||||||
sgdXformPnt3( center, m ) ;
|
sgdXformPnt3( center, m ) ;
|
||||||
|
|
||||||
// sgdClosestPointToLineDistSquared( center, orig, dir )
|
// sgdClosestPointToLineDistSquared( center, orig, dir )
|
||||||
// inlined here because because of profiling results
|
// inlined here because because of profiling results
|
||||||
sgdVec3 u, u1, v;
|
sgdVec3 u, u1, v;
|
||||||
sgdSubVec3(u, center, orig);
|
sgdSubVec3(u, center, orig);
|
||||||
sgdScaleVec3( u1, dir, sgdScalarProductVec3(u,dir)
|
sgdScaleVec3( u1, dir, sgdScalarProductVec3(u,dir) );
|
||||||
/ sgdScalarProductVec3(dir,dir) );
|
|
||||||
sgdSubVec3(v, u, u1);
|
sgdSubVec3(v, u, u1);
|
||||||
|
|
||||||
// double because of possible overflow
|
// double because of possible overflow
|
||||||
|
@ -533,6 +627,7 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
|
||||||
sgdCopyVec3(orig, view_pos );
|
sgdCopyVec3(orig, view_pos );
|
||||||
sgdCopyVec3(dir, abs_view_pos );
|
sgdCopyVec3(dir, abs_view_pos );
|
||||||
|
|
||||||
|
sgdNormaliseVec3( dir );
|
||||||
hit_list->Intersect( globals->get_scenery()->get_terrain_branch(),
|
hit_list->Intersect( globals->get_scenery()->get_terrain_branch(),
|
||||||
orig, dir );
|
orig, dir );
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue