Improved distance sorting for objects; fixes the case when a small satellite orbiting close to a planet was incorrectly occluded.
parent
83d4556c4f
commit
142ce492aa
|
@ -21,6 +21,7 @@
|
|||
#include <celutil/debug.h>
|
||||
#include <celmath/frustum.h>
|
||||
#include <celmath/distance.h>
|
||||
#include <celmath/intersect.h>
|
||||
#include "gl.h"
|
||||
#include "astro.h"
|
||||
#include "glext.h"
|
||||
|
@ -264,6 +265,44 @@ static float calcPixelSize(float fovY, float windowHeight)
|
|||
}
|
||||
|
||||
|
||||
bool operator<(const RenderListEntry& a, const RenderListEntry& b)
|
||||
{
|
||||
// This comparison functions tries to determine which of two objects is
|
||||
// closer to the viewer. Looking just at the distances of the centers
|
||||
// is not enough, nor is comparing distances to the bounding spheres.
|
||||
// Here we trace a ray from the viewer to the center of the smaller
|
||||
// of the two objects and see which object it intersects first. If the
|
||||
// ray doesn't intersect the larger object at all, it's safe to use
|
||||
// the distance to bounding sphere test.
|
||||
if (a.radius < b.radius)
|
||||
{
|
||||
Vec3f dir = a.position - Point3f(0.0f, 0.0f, 0.0f);
|
||||
float distance;
|
||||
dir.normalize();
|
||||
if (testIntersection(Ray3f(Point3f(0.0f, 0.0f, 0.0f), dir),
|
||||
Spheref(b.position, b.radius),
|
||||
distance))
|
||||
{
|
||||
return a.distance - a.radius < distance;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3f dir = b.position - Point3f(0.0f, 0.0f, 0.0f);
|
||||
float distance;
|
||||
dir.normalize();
|
||||
if (testIntersection(Ray3f(Point3f(0.0f, 0.0f, 0.0f), dir),
|
||||
Spheref(a.position, a.radius),
|
||||
distance))
|
||||
{
|
||||
return distance < b.distance - b.radius;
|
||||
}
|
||||
}
|
||||
|
||||
return a.distance - a.radius < b.distance - b.radius;
|
||||
}
|
||||
|
||||
|
||||
bool Renderer::init(int winWidth, int winHeight)
|
||||
{
|
||||
// Initialize static meshes and textures common to all instances of Renderer
|
||||
|
@ -843,6 +882,7 @@ void Renderer::autoMag(float& faintestMag)
|
|||
|
||||
}
|
||||
|
||||
|
||||
void Renderer::render(const Observer& observer,
|
||||
const Universe& universe,
|
||||
float faintestMagNight,
|
||||
|
@ -3647,7 +3687,7 @@ public:
|
|||
Vec3f viewNormal;
|
||||
|
||||
vector<Renderer::Particle>* glareParticles;
|
||||
vector<Renderer::RenderListEntry>* renderList;
|
||||
vector<RenderListEntry>* renderList;
|
||||
Renderer::StarVertexBuffer* starVertexBuffer;
|
||||
|
||||
float faintestMagNight;
|
||||
|
@ -3759,7 +3799,7 @@ void StarRenderer::process(const Star& star, float distance, float appMag)
|
|||
}
|
||||
else
|
||||
{
|
||||
Renderer::RenderListEntry rle;
|
||||
RenderListEntry rle;
|
||||
rle.star = ☆
|
||||
rle.body = NULL;
|
||||
rle.isCometTail = false;
|
||||
|
|
|
@ -18,6 +18,21 @@
|
|||
#include <celtxf/texturefont.h>
|
||||
|
||||
|
||||
struct RenderListEntry
|
||||
{
|
||||
const Star* star;
|
||||
Body* body;
|
||||
Point3f position;
|
||||
Vec3f sun;
|
||||
float distance;
|
||||
float radius;
|
||||
float nearZ;
|
||||
float farZ;
|
||||
float discSizeInPixels;
|
||||
float appMag;
|
||||
bool isCometTail;
|
||||
};
|
||||
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
|
@ -126,27 +141,6 @@ class Renderer
|
|||
float pad0, pad1, pad2;
|
||||
};
|
||||
|
||||
typedef struct _RenderListEntry
|
||||
{
|
||||
const Star* star;
|
||||
Body* body;
|
||||
Point3f position;
|
||||
Vec3f sun;
|
||||
float distance;
|
||||
float radius;
|
||||
float nearZ;
|
||||
float farZ;
|
||||
float discSizeInPixels;
|
||||
float appMag;
|
||||
bool isCometTail;
|
||||
|
||||
bool operator<(const _RenderListEntry& r) const
|
||||
{
|
||||
return distance - radius < r.distance - r.radius;
|
||||
// return z > r.z;
|
||||
}
|
||||
} RenderListEntry;
|
||||
|
||||
struct EclipseShadow
|
||||
{
|
||||
Point3f origin;
|
||||
|
|
Loading…
Reference in New Issue