Replace invalid use of memcpy in curveplot
- Vertex is not trivially copyable, therefore memcpy is not allowed. - Put local classes and functions into unnamed namespace. - Remove using namespace std, using namespace Eigen. - Prefer C++-style casts. - Use C++17 std::clamp where appropriate. - Use logger for debuggingpull/1277/head
parent
2069f1ce68
commit
657604c69a
|
@ -34,22 +34,24 @@
|
|||
#define USE_VERTEX_BUFFER 1
|
||||
#endif
|
||||
|
||||
#include "glsupport.h"
|
||||
#include "curveplot.h"
|
||||
#include "shadermanager.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace Eigen;
|
||||
|
||||
static const unsigned int SubdivisionFactor = 8;
|
||||
static const double InvSubdivisionFactor = 1.0 / (double) SubdivisionFactor;
|
||||
|
||||
|
||||
|
||||
#if DEBUG_ADAPTIVE_SPLINE
|
||||
static float SplineColors[10][3] = {
|
||||
#include <celutil/logger.h>
|
||||
#endif
|
||||
#include "curveplot.h"
|
||||
#include "glsupport.h"
|
||||
#include "shadermanager.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr unsigned int SubdivisionFactor = 8;
|
||||
constexpr double InvSubdivisionFactor = 1.0 / static_cast<double>(SubdivisionFactor);
|
||||
|
||||
#if DEBUG_ADAPTIVE_SPLINE
|
||||
constexpr float SplineColors[10][3] = {
|
||||
{ 0, 0, 1 },
|
||||
{ 0, 1, 1 },
|
||||
{ 0, 1, 0 },
|
||||
|
@ -62,24 +64,21 @@ static float SplineColors[10][3] = {
|
|||
{ 1.0f, 1.0f, 0.5f },
|
||||
};
|
||||
|
||||
static unsigned int SegmentCounts[32];
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_VECTORIZE
|
||||
// Vectorization should be enabled for improved performance.
|
||||
unsigned int SegmentCounts[32];
|
||||
#endif
|
||||
|
||||
// Convert a 3-vector to a 4-vector by adding a zero
|
||||
static inline Vector4d zeroExtend(const Vector3d& v)
|
||||
inline Eigen::Vector4d
|
||||
zeroExtend(const Eigen::Vector3d& v)
|
||||
{
|
||||
return Vector4d(v.x(), v.y(), v.z(), 0.0);
|
||||
return Eigen::Vector4d(v.x(), v.y(), v.z(), 0.0);
|
||||
}
|
||||
|
||||
|
||||
class HighPrec_Frustum
|
||||
{
|
||||
public:
|
||||
HighPrec_Frustum(double nearZ, double farZ, const Vector3d planeNormals[]) :
|
||||
HighPrec_Frustum(double nearZ, double farZ, const Eigen::Vector3d planeNormals[]) :
|
||||
m_nearZ(nearZ),
|
||||
m_farZ(farZ)
|
||||
{
|
||||
|
@ -89,7 +88,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
inline bool cullSphere(const Vector3d& center,
|
||||
inline bool cullSphere(const Eigen::Vector3d& center,
|
||||
double radius) const
|
||||
{
|
||||
return (center.z() - radius > m_nearZ ||
|
||||
|
@ -100,7 +99,7 @@ public:
|
|||
center.dot(m_planeNormals[3].head(3)) < -radius);
|
||||
}
|
||||
|
||||
inline bool cullSphere(const Vector4d& center,
|
||||
inline bool cullSphere(const Eigen::Vector4d& center,
|
||||
double radius) const
|
||||
{
|
||||
return (center.z() - radius > m_nearZ ||
|
||||
|
@ -117,16 +116,17 @@ public:
|
|||
private:
|
||||
double m_nearZ;
|
||||
double m_farZ;
|
||||
Vector4d m_planeNormals[4];
|
||||
Eigen::Vector4d m_planeNormals[4];
|
||||
};
|
||||
|
||||
|
||||
static inline Matrix4d cubicHermiteCoefficients(const Vector4d& p0,
|
||||
const Vector4d& p1,
|
||||
const Vector4d& v0,
|
||||
const Vector4d& v1)
|
||||
inline Eigen::Matrix4d
|
||||
cubicHermiteCoefficients(const Eigen::Vector4d& p0,
|
||||
const Eigen::Vector4d& p1,
|
||||
const Eigen::Vector4d& v0,
|
||||
const Eigen::Vector4d& v1)
|
||||
{
|
||||
Matrix4d coeff;
|
||||
Eigen::Matrix4d coeff;
|
||||
coeff.col(0) = p0;
|
||||
coeff.col(1) = v0;
|
||||
coeff.col(2) = 3.0 * (p1 - p0) - (2.0 * v0 + v1);
|
||||
|
@ -136,25 +136,6 @@ static inline Matrix4d cubicHermiteCoefficients(const Vector4d& p0,
|
|||
}
|
||||
|
||||
|
||||
// Test a point to see if it lies within the frustum defined by
|
||||
// planes z=nearZ, z=farZ, and the four side planes with specified
|
||||
// normals.
|
||||
#if 0
|
||||
static inline bool frustumCull(const Vector4d& curvePoint,
|
||||
double curveBoundingRadius,
|
||||
double nearZ, double farZ,
|
||||
const Vector4d viewFrustumPlaneNormals[])
|
||||
{
|
||||
return (curvePoint.z() - curveBoundingRadius > nearZ ||
|
||||
curvePoint.z() + curveBoundingRadius < farZ ||
|
||||
curvePoint.dot(viewFrustumPlaneNormals[0]) < -curveBoundingRadius ||
|
||||
curvePoint.dot(viewFrustumPlaneNormals[1]) < -curveBoundingRadius ||
|
||||
curvePoint.dot(viewFrustumPlaneNormals[2]) < -curveBoundingRadius ||
|
||||
curvePoint.dot(viewFrustumPlaneNormals[3]) < -curveBoundingRadius);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
class HighPrec_VertexBuffer
|
||||
{
|
||||
public:
|
||||
|
@ -189,26 +170,33 @@ public:
|
|||
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
|
||||
int stride = lineAsTriangles ? sizeof(Vertex) : sizeof(Vertex) * 2;
|
||||
int stride = lineAsTriangles ? sizeof(Vertex) : sizeof(Vertex) * 2;
|
||||
|
||||
Vector4f* vertexBase = vbobj ? (Vector4f*) offsetof(Vertex, position) : &data[0].position;
|
||||
const Eigen::Vector4f* vertexBase = vbobj
|
||||
? reinterpret_cast<const Eigen::Vector4f*>(offsetof(Vertex, position))
|
||||
: &data[0].position;
|
||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||
3, GL_FLOAT, GL_FALSE, stride, vertexBase);
|
||||
|
||||
Vector4f* colorBase = vbobj ? (Vector4f*) offsetof(Vertex, color) : &data[0].color;
|
||||
const Eigen::Vector4f* colorBase = vbobj
|
||||
? reinterpret_cast<const Eigen::Vector4f*>(offsetof(Vertex, color))
|
||||
: &data[0].color;
|
||||
glVertexAttribPointer(CelestiaGLProgram::ColorAttributeIndex,
|
||||
4, GL_FLOAT, GL_FALSE, stride, colorBase);
|
||||
if (lineAsTriangles)
|
||||
{
|
||||
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex);
|
||||
|
||||
float* scaleBase = vbobj ? (float*) offsetof(Vertex, scale) : &data[0].scale;
|
||||
const float* scaleBase = vbobj
|
||||
? reinterpret_cast<const float*>(offsetof(Vertex, scale))
|
||||
: &data[0].scale;
|
||||
glVertexAttribPointer(CelestiaGLProgram::ScaleFactorAttributeIndex,
|
||||
1, GL_FLOAT, GL_FALSE, stride, scaleBase);
|
||||
|
||||
Vector4f* nextVertexBase = vbobj ? (Vector4f*) (offsetof(Vertex, position) + (2 * sizeof(Vertex))) : &data[2].position;
|
||||
const Eigen::Vector4f* nextVertexBase = vbobj
|
||||
? reinterpret_cast<const Eigen::Vector4f*>(offsetof(Vertex, position) + (2 * sizeof(Vertex)))
|
||||
: &data[2].position;
|
||||
glVertexAttribPointer(CelestiaGLProgram::NextVCoordAttributeIndex,
|
||||
4, GL_FLOAT, GL_FALSE, stride, nextVertexBase);
|
||||
}
|
||||
|
@ -230,10 +218,10 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
inline void vertex(const Vector3d& v)
|
||||
inline void vertex(const Eigen::Vector3d& v)
|
||||
{
|
||||
#if USE_VERTEX_BUFFER
|
||||
Vector3f pos = v.cast<float>();
|
||||
Eigen::Vector3f pos = v.cast<float>();
|
||||
int index = currentPosition * 2;
|
||||
data[index].position.segment<3>(0) = pos;
|
||||
data[index].color = color;
|
||||
|
@ -261,15 +249,15 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
inline void vertex(const Vector4d& v)
|
||||
inline void vertex(const Eigen::Vector4d& v)
|
||||
{
|
||||
vertex(v, color);
|
||||
}
|
||||
|
||||
inline void vertex(const Vector4d& v, const Vector4f& color)
|
||||
inline void vertex(const Eigen::Vector4d& v, const Eigen::Vector4f& color)
|
||||
{
|
||||
#if USE_VERTEX_BUFFER
|
||||
Vector4f pos = v.cast<float>();
|
||||
Eigen::Vector4f pos = v.cast<float>();
|
||||
int index = currentPosition * 2;
|
||||
data[index].position = pos;
|
||||
data[index].color = color;
|
||||
|
@ -311,7 +299,8 @@ public:
|
|||
if (currentStripLength > 1)
|
||||
{
|
||||
int index = currentPosition * 2;
|
||||
memcpy(&data[index], &data[index - 4], 2 * sizeof(Vertex));
|
||||
data[index] = data[index - 4];
|
||||
data[index + 1] = data[index - 3];
|
||||
currentPosition += 1;
|
||||
stripLengths.push_back(currentStripLength);
|
||||
}
|
||||
|
@ -340,9 +329,8 @@ public:
|
|||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertex) * currentPosition * 2, data);
|
||||
|
||||
unsigned int startIndex = 0;
|
||||
for (vector<unsigned int>::const_iterator iter = stripLengths.begin(); iter != stripLengths.end(); ++iter)
|
||||
for (unsigned int lineCount : stripLengths)
|
||||
{
|
||||
int lineCount = *iter;
|
||||
if (lineAsTriangles)
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, startIndex * 2, lineCount * 2);
|
||||
else
|
||||
|
@ -373,7 +361,7 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
void setColor(const Vector4f &aColor)
|
||||
void setColor(const Eigen::Vector4f &aColor)
|
||||
{
|
||||
#if USE_VERTEX_BUFFER
|
||||
color = aColor;
|
||||
|
@ -387,15 +375,16 @@ private:
|
|||
unsigned int capacity;
|
||||
struct Vertex
|
||||
{
|
||||
Vector4f position;
|
||||
Vector4f color;
|
||||
Eigen::Vector4f position;
|
||||
Eigen::Vector4f color;
|
||||
float scale;
|
||||
};
|
||||
|
||||
Vertex* data;
|
||||
GLuint vbobj;
|
||||
unsigned int currentStripLength;
|
||||
vector<unsigned int> stripLengths;
|
||||
Vector4f color;
|
||||
std::vector<unsigned int> stripLengths;
|
||||
Eigen::Vector4f color;
|
||||
bool lineAsTriangles;
|
||||
};
|
||||
|
||||
|
@ -424,7 +413,7 @@ public:
|
|||
// curve was culled and we need to start a new primitive sequence
|
||||
// with glBegin().
|
||||
bool renderCubic(bool restartCurve,
|
||||
const Matrix4d& coeff,
|
||||
const Eigen::Matrix4d& coeff,
|
||||
double t0, double t1,
|
||||
double curveBoundingRadius,
|
||||
int depth) const
|
||||
|
@ -440,14 +429,14 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
Vector4d lastP = coeff * Vector4d(1.0, t0, t0 * t0, t0 * t0 * t0);
|
||||
Eigen::Vector4d lastP = coeff * Eigen::Vector4d(1.0, t0, t0 * t0, t0 * t0 * t0);
|
||||
|
||||
for (unsigned int i = 1; i <= SubdivisionFactor; i++)
|
||||
{
|
||||
double t = t0 + dt * i;
|
||||
Vector4d p = coeff * Vector4d(1.0, t, t * t, t * t * t);
|
||||
Eigen::Vector4d p = coeff * Eigen::Vector4d(1.0, t, t * t, t * t * t);
|
||||
|
||||
double minDistance = max(-m_viewFrustum.nearZ(), abs(p.z()) - segmentBoundingRadius);
|
||||
double minDistance = std::max(-m_viewFrustum.nearZ(), std::abs(p.z()) - segmentBoundingRadius);
|
||||
|
||||
if (segmentBoundingRadius >= m_subdivisionThreshold * minDistance)
|
||||
{
|
||||
|
@ -494,9 +483,9 @@ public:
|
|||
// curve was culled and we need to start a new primitive sequence
|
||||
// with glBegin().
|
||||
bool renderCubicFaded(bool restartCurve,
|
||||
const Matrix4d& coeff,
|
||||
const Eigen::Matrix4d& coeff,
|
||||
double t0, double t1,
|
||||
const Vector4f& color,
|
||||
const Eigen::Vector4f& color,
|
||||
double fadeStart, double fadeRate,
|
||||
double curveBoundingRadius,
|
||||
int depth) const
|
||||
|
@ -512,18 +501,18 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
Vector4d lastP = coeff * Vector4d(1.0, t0, t0 * t0, t0 * t0 * t0);
|
||||
Eigen::Vector4d lastP = coeff * Eigen::Vector4d(1.0, t0, t0 * t0, t0 * t0 * t0);
|
||||
double lastOpacity = (t0 - fadeStart) * fadeRate;
|
||||
lastOpacity = max(0.0, min(1.0, lastOpacity)); // clamp
|
||||
lastOpacity = std::clamp(lastOpacity, 0.0, 1.0);
|
||||
|
||||
for (unsigned int i = 1; i <= SubdivisionFactor; i++)
|
||||
{
|
||||
double t = t0 + dt * i;
|
||||
Vector4d p = coeff * Vector4d(1.0, t, t * t, t * t * t);
|
||||
Eigen::Vector4d p = coeff * Eigen::Vector4d(1.0, t, t * t, t * t * t);
|
||||
double opacity = (t - fadeStart) * fadeRate;
|
||||
opacity = max(0.0, min(1.0, opacity)); // clamp
|
||||
opacity = std::clamp(opacity, 0.0, 1.0);
|
||||
|
||||
double minDistance = max(-m_viewFrustum.nearZ(), abs(p.z()) - segmentBoundingRadius);
|
||||
double minDistance = std::max(-m_viewFrustum.nearZ(), std::abs(p.z()) - segmentBoundingRadius);
|
||||
|
||||
if (segmentBoundingRadius >= m_subdivisionThreshold * minDistance)
|
||||
{
|
||||
|
@ -557,11 +546,11 @@ public:
|
|||
if (restartCurve)
|
||||
{
|
||||
m_vbuf.begin();
|
||||
m_vbuf.vertex(lastP, Vector4f(color.x(), color.y(), color.z(), color.w() * float(lastOpacity)));
|
||||
m_vbuf.vertex(lastP, Eigen::Vector4f(color.x(), color.y(), color.z(), color.w() * float(lastOpacity)));
|
||||
restartCurve = false;
|
||||
}
|
||||
|
||||
m_vbuf.vertex(p, Vector4f(color.x(), color.y(), color.z(), color.w() * float(opacity)));
|
||||
m_vbuf.vertex(p, Eigen::Vector4f(color.x(), color.y(), color.z(), color.w() * float(opacity)));
|
||||
}
|
||||
lastP = p;
|
||||
lastOpacity = opacity;
|
||||
|
@ -577,8 +566,12 @@ private:
|
|||
};
|
||||
|
||||
|
||||
HighPrec_VertexBuffer vbuf;
|
||||
|
||||
static HighPrec_VertexBuffer vbuf;
|
||||
|
||||
|
||||
|
||||
} // end unnamed namespace
|
||||
|
||||
|
||||
CurvePlot::CurvePlot()
|
||||
|
@ -623,22 +616,24 @@ CurvePlot::addSample(const CurvePlotSample& sample)
|
|||
{
|
||||
const CurvePlotSample& lastSample = m_samples[m_samples.size() - 2];
|
||||
double dt = sample.t - lastSample.t;
|
||||
Matrix4d coeff = cubicHermiteCoefficients(zeroExtend(lastSample.position),
|
||||
zeroExtend(sample.position),
|
||||
zeroExtend(lastSample.velocity * dt),
|
||||
zeroExtend(sample.velocity * dt));
|
||||
Vector4d extents = coeff.cwiseAbs() * Vector4d(0.0, 1.0, 1.0, 1.0);
|
||||
Eigen::Matrix4d coeff = cubicHermiteCoefficients(
|
||||
zeroExtend(lastSample.position),
|
||||
zeroExtend(sample.position),
|
||||
zeroExtend(lastSample.velocity * dt),
|
||||
zeroExtend(sample.velocity * dt));
|
||||
Eigen::Vector4d extents = coeff.cwiseAbs() * Eigen::Vector4d(0.0, 1.0, 1.0, 1.0);
|
||||
m_samples[m_samples.size() - 1].boundingRadius = extents.norm();
|
||||
}
|
||||
else
|
||||
{
|
||||
const CurvePlotSample& nextSample = m_samples[1];
|
||||
double dt = nextSample.t - sample.t;
|
||||
Matrix4d coeff = cubicHermiteCoefficients(zeroExtend(sample.position),
|
||||
zeroExtend(nextSample.position),
|
||||
zeroExtend(sample.velocity * dt),
|
||||
zeroExtend(nextSample.velocity * dt));
|
||||
Vector4d extents = coeff.cwiseAbs() * Vector4d(0.0, 1.0, 1.0, 1.0);
|
||||
Eigen::Matrix4d coeff = cubicHermiteCoefficients(
|
||||
zeroExtend(sample.position),
|
||||
zeroExtend(nextSample.position),
|
||||
zeroExtend(sample.velocity * dt),
|
||||
zeroExtend(nextSample.velocity * dt));
|
||||
Eigen::Vector4d extents = coeff.cwiseAbs() * Eigen::Vector4d(0.0, 1.0, 1.0, 1.0);
|
||||
m_samples[1].boundingRadius = extents.norm();
|
||||
}
|
||||
}
|
||||
|
@ -688,21 +683,21 @@ CurvePlot::setDuration(double duration)
|
|||
* @param subdivisionThreshold the threashhold for subdivision
|
||||
*/
|
||||
void
|
||||
CurvePlot::render(const Affine3d& modelview,
|
||||
CurvePlot::render(const Eigen::Affine3d& modelview,
|
||||
double nearZ,
|
||||
double farZ,
|
||||
const Vector3d viewFrustumPlaneNormals[],
|
||||
const Eigen::Vector3d viewFrustumPlaneNormals[],
|
||||
double subdivisionThreshold,
|
||||
const Vector4f& color,
|
||||
const Eigen::Vector4f& color,
|
||||
bool lineAsTriangles) const
|
||||
{
|
||||
// Flag to indicate whether we need to issue a glBegin()
|
||||
bool restartCurve = true;
|
||||
|
||||
const Vector3d& p0_ = m_samples[0].position;
|
||||
const Vector3d& v0_ = m_samples[0].velocity;
|
||||
Vector4d p0 = modelview * Vector4d(p0_.x(), p0_.y(), p0_.z(), 1.0);
|
||||
Vector4d v0 = modelview * Vector4d(v0_.x(), v0_.y(), v0_.z(), 0.0);
|
||||
const Eigen::Vector3d& p0_ = m_samples[0].position;
|
||||
const Eigen::Vector3d& v0_ = m_samples[0].velocity;
|
||||
Eigen::Vector4d p0 = modelview * Eigen::Vector4d(p0_.x(), p0_.y(), p0_.z(), 1.0);
|
||||
Eigen::Vector4d v0 = modelview * Eigen::Vector4d(v0_.x(), v0_.y(), v0_.z(), 0.0);
|
||||
|
||||
HighPrec_Frustum viewFrustum(nearZ, farZ, viewFrustumPlaneNormals);
|
||||
HighPrec_RenderContext rc(vbuf, viewFrustum, subdivisionThreshold);
|
||||
|
@ -719,10 +714,10 @@ CurvePlot::render(const Affine3d& modelview,
|
|||
for (unsigned int i = 1; i < m_samples.size(); i++)
|
||||
{
|
||||
// Transform the points into camera space.
|
||||
const Vector3d& p1_ = m_samples[i].position;
|
||||
const Vector3d& v1_ = m_samples[i].velocity;
|
||||
Vector4d p1 = modelview * Vector4d(p1_.x(), p1_.y(), p1_.z(), 1.0);
|
||||
Vector4d v1 = modelview * Vector4d(v1_.x(), v1_.y(), v1_.z(), 0.0);
|
||||
const Eigen::Vector3d& p1_ = m_samples[i].position;
|
||||
const Eigen::Vector3d& v1_ = m_samples[i].velocity;
|
||||
Eigen::Vector4d p1 = modelview * Eigen::Vector4d(p1_.x(), p1_.y(), p1_.z(), 1.0);
|
||||
Eigen::Vector4d v1 = modelview * Eigen::Vector4d(v1_.x(), v1_.y(), v1_.z(), 0.0);
|
||||
|
||||
// O(t) is an approximating function for this segment of
|
||||
// the orbit, with 0 <= t <= 1
|
||||
|
@ -738,7 +733,7 @@ CurvePlot::render(const Affine3d& modelview,
|
|||
// render it. Otherwise, it should be a performance win
|
||||
// to do a sphere-frustum cull test before subdividing and
|
||||
// rendering segment.
|
||||
double minDistance = abs(p0.z()) - curveBoundingRadius;
|
||||
double minDistance = std::abs(p0.z()) - curveBoundingRadius;
|
||||
|
||||
// Render close segments as splines with adaptive subdivision. The
|
||||
// subdivisions eliminates kinks between line segments and also
|
||||
|
@ -763,7 +758,7 @@ CurvePlot::render(const Affine3d& modelview,
|
|||
else
|
||||
{
|
||||
double dt = m_samples[i].t - m_samples[i - 1].t;
|
||||
Matrix4d coeff = cubicHermiteCoefficients(p0, p1, v0 * dt, v1 * dt);
|
||||
Eigen::Matrix4d coeff = cubicHermiteCoefficients(p0, p1, v0 * dt, v1 * dt);
|
||||
|
||||
restartCurve = rc.renderCubic(restartCurve, coeff, 0.0, 1.0, curveBoundingRadius, 1);
|
||||
}
|
||||
|
@ -810,12 +805,12 @@ CurvePlot::render(const Affine3d& modelview,
|
|||
vbuf.flush();
|
||||
vbuf.finish();
|
||||
|
||||
#if DEBUG_ADAPTIVE_SPLINE3
|
||||
#if DEBUG_ADAPTIVE_SPLINE
|
||||
for (unsigned int i = 0; SegmentCounts[i] != 0 || i < 3; i++)
|
||||
{
|
||||
clog << i << ":" << SegmentCounts[i] << ", ";
|
||||
celestia::util::GetLogger()->debug("{}: {}, ", i, SegmentCounts[i]);
|
||||
}
|
||||
clog << endl;
|
||||
celestia::util::GetLogger()->debug("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -831,14 +826,14 @@ CurvePlot::render(const Affine3d& modelview,
|
|||
* @param endTime the end of the time interval
|
||||
*/
|
||||
void
|
||||
CurvePlot::render(const Affine3d& modelview,
|
||||
CurvePlot::render(const Eigen::Affine3d& modelview,
|
||||
double nearZ,
|
||||
double farZ,
|
||||
const Vector3d viewFrustumPlaneNormals[],
|
||||
const Eigen::Vector3d viewFrustumPlaneNormals[],
|
||||
double subdivisionThreshold,
|
||||
double startTime,
|
||||
double endTime,
|
||||
const Vector4f& color,
|
||||
const Eigen::Vector4f& color,
|
||||
bool lineAsTriangles) const
|
||||
{
|
||||
// Flag to indicate whether we need to issue a glBegin()
|
||||
|
@ -856,10 +851,10 @@ CurvePlot::render(const Affine3d& modelview,
|
|||
if (startSample > 0)
|
||||
startSample--;
|
||||
|
||||
const Vector3d& p0_ = m_samples[startSample].position;
|
||||
const Vector3d& v0_ = m_samples[startSample].velocity;
|
||||
Vector4d p0 = modelview * Vector4d(p0_.x(), p0_.y(), p0_.z(), 1.0);
|
||||
Vector4d v0 = modelview * Vector4d(v0_.x(), v0_.y(), v0_.z(), 0.0);
|
||||
const Eigen::Vector3d& p0_ = m_samples[startSample].position;
|
||||
const Eigen::Vector3d& v0_ = m_samples[startSample].velocity;
|
||||
Eigen::Vector4d p0 = modelview * Eigen::Vector4d(p0_.x(), p0_.y(), p0_.z(), 1.0);
|
||||
Eigen::Vector4d v0 = modelview * Eigen::Vector4d(v0_.x(), v0_.y(), v0_.z(), 0.0);
|
||||
|
||||
HighPrec_Frustum viewFrustum(nearZ, farZ, viewFrustumPlaneNormals);
|
||||
HighPrec_RenderContext rc(vbuf, viewFrustum, subdivisionThreshold);
|
||||
|
@ -874,10 +869,10 @@ CurvePlot::render(const Affine3d& modelview,
|
|||
for (unsigned int i = startSample + 1; i < m_samples.size() && !lastSegment; i++)
|
||||
{
|
||||
// Transform the points into camera space.
|
||||
const Vector3d& p1_ = m_samples[i].position;
|
||||
const Vector3d& v1_ = m_samples[i].velocity;
|
||||
Vector4d p1 = modelview * Vector4d(p1_.x(), p1_.y(), p1_.z(), 1.0);
|
||||
Vector4d v1 = modelview * Vector4d(v1_.x(), v1_.y(), v1_.z(), 0.0);
|
||||
const Eigen::Vector3d& p1_ = m_samples[i].position;
|
||||
const Eigen::Vector3d& v1_ = m_samples[i].velocity;
|
||||
Eigen::Vector4d p1 = modelview * Eigen::Vector4d(p1_.x(), p1_.y(), p1_.z(), 1.0);
|
||||
Eigen::Vector4d v1 = modelview * Eigen::Vector4d(v1_.x(), v1_.y(), v1_.z(), 0.0);
|
||||
|
||||
if (endTime <= m_samples[i].t)
|
||||
{
|
||||
|
@ -926,7 +921,7 @@ CurvePlot::render(const Affine3d& modelview,
|
|||
if (firstSegment)
|
||||
{
|
||||
t0 = (startTime - m_samples[i - 1].t) / dt;
|
||||
t0 = std::max(0.0, std::min(1.0, t0));
|
||||
t0 = std::clamp(t0, 0.0, 1.0);
|
||||
firstSegment = false;
|
||||
}
|
||||
|
||||
|
@ -935,7 +930,7 @@ CurvePlot::render(const Affine3d& modelview,
|
|||
t1 = (endTime - m_samples[i - 1].t) / dt;
|
||||
}
|
||||
|
||||
Matrix4d coeff = cubicHermiteCoefficients(p0, p1, v0 * dt, v1 * dt);
|
||||
Eigen::Matrix4d coeff = cubicHermiteCoefficients(p0, p1, v0 * dt, v1 * dt);
|
||||
restartCurve = rc.renderCubic(restartCurve, coeff, t0, t1, curveBoundingRadius, 1);
|
||||
}
|
||||
}
|
||||
|
@ -1005,7 +1000,7 @@ CurvePlot::renderFaded(const Eigen::Affine3d& modelview,
|
|||
double subdivisionThreshold,
|
||||
double startTime,
|
||||
double endTime,
|
||||
const Vector4f& color,
|
||||
const Eigen::Vector4f& color,
|
||||
double fadeStartTime,
|
||||
double fadeEndTime,
|
||||
bool lineAsTriangles) const
|
||||
|
@ -1028,12 +1023,12 @@ CurvePlot::renderFaded(const Eigen::Affine3d& modelview,
|
|||
double fadeDuration = fadeEndTime - fadeStartTime;
|
||||
double fadeRate = 1.0 / fadeDuration;
|
||||
|
||||
const Vector3d& p0_ = m_samples[startSample].position;
|
||||
const Vector3d& v0_ = m_samples[startSample].velocity;
|
||||
Vector4d p0 = modelview * Vector4d(p0_.x(), p0_.y(), p0_.z(), 1.0);
|
||||
Vector4d v0 = modelview * Vector4d(v0_.x(), v0_.y(), v0_.z(), 0.0);
|
||||
const Eigen::Vector3d& p0_ = m_samples[startSample].position;
|
||||
const Eigen::Vector3d& v0_ = m_samples[startSample].velocity;
|
||||
Eigen::Vector4d p0 = modelview * Eigen::Vector4d(p0_.x(), p0_.y(), p0_.z(), 1.0);
|
||||
Eigen::Vector4d v0 = modelview * Eigen::Vector4d(v0_.x(), v0_.y(), v0_.z(), 0.0);
|
||||
double opacity0 = (m_samples[startSample].t - fadeStartTime) * fadeRate;
|
||||
opacity0 = max(0.0, min(1.0, opacity0));
|
||||
opacity0 = std::clamp(opacity0, 0.0, 1.0);
|
||||
|
||||
HighPrec_Frustum viewFrustum(nearZ, farZ, viewFrustumPlaneNormals);
|
||||
HighPrec_RenderContext rc(vbuf, viewFrustum, subdivisionThreshold);
|
||||
|
@ -1047,12 +1042,12 @@ CurvePlot::renderFaded(const Eigen::Affine3d& modelview,
|
|||
for (unsigned int i = startSample + 1; i < m_samples.size() && !lastSegment; i++)
|
||||
{
|
||||
// Transform the points into camera space.
|
||||
const Vector3d& p1_ = m_samples[i].position;
|
||||
const Vector3d& v1_ = m_samples[i].velocity;
|
||||
Vector4d p1 = modelview * Vector4d(p1_.x(), p1_.y(), p1_.z(), 1.0);
|
||||
Vector4d v1 = modelview * Vector4d(v1_.x(), v1_.y(), v1_.z(), 0.0);
|
||||
const Eigen::Vector3d& p1_ = m_samples[i].position;
|
||||
const Eigen::Vector3d& v1_ = m_samples[i].velocity;
|
||||
Eigen::Vector4d p1 = modelview * Eigen::Vector4d(p1_.x(), p1_.y(), p1_.z(), 1.0);
|
||||
Eigen::Vector4d v1 = modelview * Eigen::Vector4d(v1_.x(), v1_.y(), v1_.z(), 0.0);
|
||||
double opacity1 = (m_samples[i].t - fadeStartTime) * fadeRate;
|
||||
opacity1 = max(0.0, min(1.0, opacity1));
|
||||
opacity1 = std::clamp(opacity1, 0.0, 1.0);
|
||||
|
||||
if (endTime <= m_samples[i].t)
|
||||
{
|
||||
|
@ -1073,7 +1068,7 @@ CurvePlot::renderFaded(const Eigen::Affine3d& modelview,
|
|||
// render it. Otherwise, it should be a performance win
|
||||
// to do a sphere-frustum cull test before subdividing and
|
||||
// rendering segment.
|
||||
double minDistance = abs(p0.z()) - curveBoundingRadius;
|
||||
double minDistance = std::abs(p0.z()) - curveBoundingRadius;
|
||||
|
||||
// Render close segments as splines with adaptive subdivision. The
|
||||
// subdivisions eliminates kinks between line segments and also
|
||||
|
@ -1101,7 +1096,7 @@ CurvePlot::renderFaded(const Eigen::Affine3d& modelview,
|
|||
if (firstSegment)
|
||||
{
|
||||
t0 = (startTime - m_samples[i - 1].t) / dt;
|
||||
t0 = std::max(0.0, std::min(1.0, t0));
|
||||
t0 = std::clamp(t0, 0.0, 1.0);
|
||||
firstSegment = false;
|
||||
}
|
||||
|
||||
|
@ -1110,7 +1105,7 @@ CurvePlot::renderFaded(const Eigen::Affine3d& modelview,
|
|||
t1 = (endTime - m_samples[i - 1].t) / dt;
|
||||
}
|
||||
|
||||
Matrix4d coeff = cubicHermiteCoefficients(p0, p1, v0 * dt, v1 * dt);
|
||||
Eigen::Matrix4d coeff = cubicHermiteCoefficients(p0, p1, v0 * dt, v1 * dt);
|
||||
restartCurve = rc.renderCubicFaded(restartCurve, coeff,
|
||||
t0, t1,
|
||||
color,
|
||||
|
@ -1139,10 +1134,16 @@ CurvePlot::renderFaded(const Eigen::Affine3d& modelview,
|
|||
if (restartCurve)
|
||||
{
|
||||
vbuf.begin();
|
||||
vbuf.vertex(p0, Vector4f(color.x(), color.y(), color.z(), color.w() * float(opacity0)));
|
||||
vbuf.vertex(p0, Eigen::Vector4f(color.x(),
|
||||
color.y(),
|
||||
color.z(),
|
||||
color.w() * static_cast<float>(opacity0)));
|
||||
restartCurve = false;
|
||||
}
|
||||
vbuf.vertex(p1, Vector4f(color.x(), color.y(), color.z(), color.w() * float(opacity1)));
|
||||
vbuf.vertex(p1, Eigen::Vector4f(color.x(),
|
||||
color.y(),
|
||||
color.z(),
|
||||
color.w() * static_cast<float>(opacity1)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,11 +30,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
|
||||
class HighPrec_Frustum;
|
||||
|
||||
class CurvePlotSample
|
||||
{
|
||||
public:
|
||||
|
@ -110,7 +110,7 @@ class CurvePlot
|
|||
|
||||
private:
|
||||
std::deque<CurvePlotSample> m_samples;
|
||||
|
||||
|
||||
double m_duration{ 0.0 };
|
||||
|
||||
unsigned int m_lastUsed{ 0 };
|
||||
|
|
Loading…
Reference in New Issue