- Joined
- Mar 28, 2008
- Messages
- 666
- Reaction score
- 20
- Points
- 33
The plan is to develope a MFD mode for Orbiter 2015+ to display a topographic map. To remove the discussion from the "Orbiter Beta" thread I created this developement thread.
The Situation:
The MFD is working, but still now it has some performance issues:
1. The used method "oapiSurfaceElevation" is a bit slow to render the complete map on each "MFD Update". But therefore Enjo had the Idea to
"discretize the map, fill it with calculations, cache them, and then once enough movement has been made in a given direction, (using floor / ceil), shift the map, but query only for the changed part (incoming from the border), and query the cache for the remaining points?"
2. I used the function "skp->LineTo(x...,y...);" to paint a pixel. It's also a bit slow even if I want to paint each pixcel just with the same color. So I need a better way to "render a picture" on the MFD display.
3. Still now, the representation of the elevation is black (low) and white (high) only. So I'm looking for an alogrithm which can give me a colorized picture like this:
And this is how it looks right now:
The very simple experimental method to create this picture is the following which can be called from the update method of the MFD mode:
And the supporting methods from "ORBITERTOOLS":
The Situation:
The MFD is working, but still now it has some performance issues:
1. The used method "oapiSurfaceElevation" is a bit slow to render the complete map on each "MFD Update". But therefore Enjo had the Idea to
"discretize the map, fill it with calculations, cache them, and then once enough movement has been made in a given direction, (using floor / ceil), shift the map, but query only for the changed part (incoming from the border), and query the cache for the remaining points?"
2. I used the function "skp->LineTo(x...,y...);" to paint a pixel. It's also a bit slow even if I want to paint each pixcel just with the same color. So I need a better way to "render a picture" on the MFD display.
3. Still now, the representation of the elevation is black (low) and white (high) only. So I'm looking for an alogrithm which can give me a colorized picture like this:
And this is how it looks right now:
The very simple experimental method to create this picture is the following which can be called from the update method of the MFD mode:
Code:
void SurfaceSpeedMFD::drawTopoMap(oapi::Sketchpad *skp)
{
static double highest = 5000;
static double lowest = -5000;
VESSEL*v = oapiGetFocusInterface();
double lng_Vessel, lat_Vessel, rad;
v->GetEquPos(lng_Vessel,lat_Vessel,rad);
double heading = ORBITERTOOLS::getFlightVectorHeading(v);
const double zoom = 500;
for (int x=-width/2; x<width/2; x++)
{
double lng_left, lat_left, rad;
ORBITERTOOLS::pointRadialDistance(lat_Vessel,lng_Vessel,heading+PI05,x*zoom,v,&lat_left,&lng_left);
skp->MoveTo(x+width/2,0);
for (int y=-height/2; y<height/2; y++)
{
double lng_pixel, lat_pixel;
ORBITERTOOLS::pointRadialDistance(lat_left,lng_left,heading,y*zoom,v,&lat_pixel,&lng_pixel);
double elevation = oapiSurfaceElevation(v->GetGravityRef(),lng_pixel,lat_pixel);
oapi::Pen *elevationPen;
if (elevation > highest) highest = elevation;
if (elevation < lowest) lowest = elevation;
double elevation255 = ((elevation + (0 - lowest)) / ( highest - lowest)) * 255;
elevationPen = oapiCreatePen(1, 1, RGB(elevation255,elevation255,elevation255));
skp->SetPen(elevationPen);
skp->LineTo(x+width/2, height-(y+height/2));
oapiReleasePen(elevationPen);
}
}
}
Code:
static double getFlightVectorHeading(VESSEL *v)
{
VECTOR3 shipAirspeedVector;
v->GetHorizonAirspeedVector(shipAirspeedVector);
normalise(shipAirspeedVector);
double vector = acos(shipAirspeedVector.z/sqrt((shipAirspeedVector.x*shipAirspeedVector.x)+(shipAirspeedVector.z*shipAirspeedVector.z)));
vector = atan2(shipAirspeedVector.x, shipAirspeedVector.z);
//if (vector > 2*PI) vector -= 2*PI;
return vector;
}
static void pointRadialDistance(double lat1, double lon1, double bearing, double distance, VESSEL * v, double *lat2, double *lon2)
{
double rdistance = distance / oapiGetSize(v->GetGravityRef());
* lat2 = asin(sin(lat1) * cos(rdistance) + cos(lat1) * sin (rdistance) * cos(bearing) );
* lon2 = lon1 + atan2( sin (bearing) * sin (rdistance) * cos (lat1), cos (rdistance) - sin(lat1) * sin (* lat2 ));
}
Last edited: