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;
|
||||
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
|
||||
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();
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -94,6 +94,7 @@ private:
|
|||
replay_list_type short_term;
|
||||
replay_list_type medium_term;
|
||||
replay_list_type long_term;
|
||||
SGPropertyNode_ptr disable_replay;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -297,6 +390,7 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
|||
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 );
|
||||
|
||||
|
|
Loading…
Reference in a new issue