Recently, I started tinkering with Celestia 1.2.4 source, and one of the first things I wanted to try was to simulate standing, say at an elevation of 100 meters on Mars, and panning the horizon. At first, I thought this would be quite simple, but now I've changed my opinion, and come to you, Celestia developers, on bended knee, for help.
As a first step toward panning with a level horizon, I added a simple command to one of the menus which asks for an object to look at and places the string in a variable named 'strObjectPath', then executes the following code:
Simulation* sim = appCore->getSimulation();
Observer& observer = sim->getObserver();
double simTime = sim->getTime();
Selection& targetObject = sim->findObjectFromPath(strObjectPath);
Point3f from = observer.getPosition();
Selection& location = sim->getSelection(); // could be Moon, Mars...
Point3f to = targetObject.getPosition(simTime);
//get vector up from center of object to observer on surface
Vec3f up = from - location.getPosition(simTime);
// following lines from 'lookAt' in simulation.cpp
Vec3f n = to - from; n.normalize();
Vec3f v = n ^ up; v.normalize();
Vec3f u = v ^ n;
Quatf orientation(Mat3f(v, u, -n));
sim->setObserverOrientation(orientation);
It seems that this code should give me a level horizon on the selected object, looking at the object in 'strObjectPath'. Well, it certainly "looks at" 'strObjectPath', and it's USUALLY reasonably level, but never PERFECTLY level.
How can I get a level horizon ????