1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
#pragma once
#include "glGrib/Field.h"
#include "glGrib/String.h"
namespace glGrib
{
class FieldContour : public Field
{
public:
explicit FieldContour (const Field::Privatizer) { }
void setup (const Field::Privatizer, Loader *, const OptionsField &, float = 0) override;
Field::kind getKind () const
{
return Field::CONTOUR;
}
FieldContour * clone () const;
void render (const View &, const OptionsLight &) const override;
bool useColorBar () const override { return true; }
int getSlotMax () const override
{
return (int)opts.path.size ();
}
FieldContour (const FieldContour &) = delete;
private:
class isoline_data_t
{
public:
std::vector<float> lonlat; // Position
std::vector<float> height; // Height
std::vector<float> length; // Distance
double dis_last = 0.;
struct
{
float x = 0.0f, y = 0.0f, z = 0.0f;
} last;
void push (const float x, const float y, const float z, const float h)
{
double D = 0.0f;
float d = std::abs (x) + std::abs (y) + std::abs (z);
float lon = 0.0f, lat = 2 * M_PI;
if (d > 0)
{
int sz = size ();
lat = std::asin (z);
lon = atan2 (y, x);
if (sz > 0)
{
float dx = x - last.x;
float dy = y - last.y;
float dz = z - last.z;
D = dis_last + std::sqrt (dx * dx + dy * dy + dz * dz);
}
}
last.x = x;
last.y = y;
last.z = z;
lonlat.push_back (lon);
lonlat.push_back (lat);
height.push_back (h);
length.push_back (D);
dis_last = D;
}
void pop ()
{
lonlat.pop_back ();
lonlat.pop_back ();
height.pop_back ();
length.pop_back ();
}
void clear ()
{
lonlat.clear ();
height.clear ();
length.clear ();
}
int size () const
{
return length.size ();
}
};
class isoline_t
{
public:
isoline_t () : VAID (this) {}
isoline_t (const isoline_t & iso) : VAID (this)
{
d = iso.d;
}
void setup (const OptionsField &, float, size_t, const Palette &, const isoline_data_t &);
void setupVertexAttributes () const;
void setupLabels (const OptionsField & opts, const isoline_data_t &);
void clear ()
{
VAID.clear ();
}
void render (const glGrib::View & view, const glGrib::OptionsLight & light) const;
struct
{
String3D<0,1> labels;
float level;
bool wide = false;
float width = 0.0f;
bool dash = false;
float length = 0.0f;
OptionColor color;
std::vector<int> pattern;
OpenGLBufferPtr<float> vertexbuffer, heightbuffer, distancebuffer;
GLuint size;
} d;
OpenGLVertexArray<isoline_t> VAID;
};
std::vector<isoline_t> iso;
void processTriangle (int, const BufferPtr<float> &, float,
const BufferPtr<float> &, float, float, float,
bool *, isoline_data_t *, const const_GeometryPtr &);
};
}
|