Correctly compute the positions of locations on the surface of irregular (i.e. mesh) bodies.
parent
8151e02ef3
commit
28d7af9428
|
@ -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)
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue