Correctly compute the positions of locations on the surface of irregular (i.e. mesh) bodies.

ver1_5_1
Chris Laurel 2003-06-24 06:31:19 +00:00
parent 8151e02ef3
commit 28d7af9428
7 changed files with 61 additions and 15 deletions

View File

@ -13,6 +13,8 @@
#include <cassert>
#include <celmath/mathlib.h>
#include <celutil/util.h>
#include "mesh.h"
#include "meshmanager.h"
#include "body.h"
using namespace std;
@ -47,7 +49,8 @@ Body::Body(PlanetarySystem* _system) :
satellites(NULL),
classification(Unknown),
altSurfaces(NULL),
locations(NULL)
locations(NULL),
locationsComputed(false)
{
system = _system;
}
@ -496,6 +499,44 @@ vector<Location*>* Body::getLocations() const
}
// Compute the positions of locations on an irregular object using ray-mesh
// intersections. This is not automatically done when a location is added
// because it would force the loading of all meshes for objects with
// defined locations; on-demand (i.e. when the object becomes visible to
// a user) loading of meshes is preferred.
void Body::computeLocations()
{
if (locationsComputed)
return;
locationsComputed = true;
// No work to do if there's no mesh, or if the mesh cannot be loaded
if (mesh == InvalidResource)
return;
Mesh* m = GetMeshManager()->find(mesh);
if (m == NULL)
return;
for (vector<Location*>::const_iterator iter = locations->begin();
iter != locations->end(); iter++)
{
Vec3f v = (*iter)->getPosition();
float alt = v.length() - radius;
if (alt != -radius)
v.normalize();
Ray3d ray(Point3d(v.x, v.y, v.z), Vec3d(-v.x, -v.y, -v.z));
double t = 0.0;
if (m->pick(ray, t))
{
v *= (1.0f - t) * radius + alt;
(*iter)->setPosition(v);
}
}
}
/**** Implementation of PlanetarySystem ****/
PlanetarySystem::PlanetarySystem(Body* _primary) : primary(_primary)

View File

@ -174,6 +174,7 @@ class Body
std::vector<Location*>* getLocations() const;
void addLocation(Location*);
void computeLocations();
private:
std::string name;
@ -208,6 +209,7 @@ class Body
AltSurfaceTable *altSurfaces;
std::vector<Location*>* locations;
mutable bool locationsComputed;
};
#endif // _BODY_H_

View File

@ -86,13 +86,13 @@ void Location::setName(const string& _name)
}
Point3f Location::getPosition() const
Vec3f Location::getPosition() const
{
return position;
}
void Location::setPosition(const Point3f& _position)
void Location::setPosition(const Vec3f& _position)
{
position = _position;
}

View File

@ -24,8 +24,8 @@ class Location
std::string getName() const;
void setName(const std::string&);
Point3f getPosition() const;
void setPosition(const Point3f&);
Vec3f getPosition() const;
void setPosition(const Vec3f&);
float getSize() const;
void setSize(float);
@ -76,7 +76,7 @@ class Location
private:
std::string name;
Point3f position;
Vec3f position;
float size;
float importance;
uint32 featureType;

View File

@ -3262,11 +3262,9 @@ void Renderer::renderLocations(const vector<Location*>& locations,
{
if ((*iter)->getFeatureType() & locationFilter)
{
Point3f off = (*iter)->getPosition();
Point3f off_t = off * mat;
Point3f wpos(position.x + off_t.x * 1.01f,
position.y + off_t.y * 1.01f,
position.z + off_t.z * 1.01f);
Vec3f off = (*iter)->getPosition();
Vec3f off_t = off * mat;
Point3f wpos(position + off_t * 1.01f);
float effSize = (*iter)->getImportance();
if (effSize < 0.0f)
@ -3275,7 +3273,10 @@ void Renderer::renderLocations(const vector<Location*>& locations,
if (pixSize > minFeatureSize)
{
float r = off_t.length();
if (r < scale * 0.99f)
wpos = position + off_t * (scale * 1.01f / r);
float t = 0.0f;
bool hit = testIntersection(Ray3f(origin, wpos - origin),
ellipsoid, t);
@ -3794,7 +3795,7 @@ bool Renderer::testEclipse(const Body& receiver, const Body& caster,
}
void Renderer::renderPlanet(const Body& body,
void Renderer::renderPlanet(Body& body,
Point3f pos,
Vec3f sunDirection,
float distance,
@ -3893,6 +3894,8 @@ void Renderer::renderPlanet(const Body& body,
}
rp.locations = body.getLocations();
if (rp.locations != NULL && (labelMode & LocationLabels) != 0)
body.computeLocations();
// Calculate eclipse circumstances
if ((renderFlags & ShowEclipseShadows) != 0 &&

View File

@ -239,7 +239,7 @@ class Renderer
Color sunColor,
RenderProperties& obj);
void renderPlanet(const Body& body,
void renderPlanet(Body& body,
Point3f pos,
Vec3f sunDirection,
float distance,

View File

@ -65,7 +65,7 @@ static Location* CreateLocation(Hash* locationData,
Vec3f position = body->planetocentricToCartesian((float) longlat.x,
(float) longlat.y,
(float) longlat.z);
location->setPosition(Point3f(0.0f, 0.0f, 0.0f) + position);
location->setPosition(position);
double size = 0.0;
locationData->getNumber("Size", size);