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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
#pragma once
#include "glGrib/Field.h"
#include <bits/stdc++.h>
namespace glGrib
{
class FieldStream : public Field
{
public:
explicit FieldStream (const Field::Privatizer) { }
void setup (const Field::Privatizer, Loader *, const OptionsField &, float = 0) override;
FieldStream (const FieldStream &) = delete;
Field::kind getKind () const
{
return Field::STREAM;
}
FieldStream * 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 () / 2;
}
private:
class streamline_data_t
{
public:
std::vector<float> lonlat; // Position
std::vector<float> values; // Field value
std::vector<float> length; // Distance
struct
{
float x = 0.0f, y = 0.0f, z = 0.0f;
} last;
void push (const glm::vec3 & xyz, const float d = 1.0f)
{
push (xyz.x, xyz.y, xyz.z, d);
}
void push (const float x, const float y, const float z, const float d = 1.)
{
double D = 0.0f;
float lon = 0.0f, lat = 2 * M_PI;
if (d > 0)
{
lat = std::asin (z);
lon = atan2 (y, x);
int sz = size (), ilast = sz - 1;
if (sz > 0)
{
if ((last.x != 0.0f) || (last.y != 0.0f) || (last.z != 0.0f))
{
float dx = x - last.x;
float dy = y - last.y;
float dz = z - last.z;
D = length[ilast] + std::sqrt (dx * dx + dy * dy + dz * dz) / d;
}
}
}
last.x = x;
last.y = y;
last.z = z;
lonlat.push_back (lon);
lonlat.push_back (lat);
values.push_back (d);
length.push_back (D);
}
void pop ()
{
lonlat.pop_back ();
lonlat.pop_back ();
values.pop_back ();
length.pop_back ();
}
void clear ()
{
lonlat.clear ();
values.clear ();
length.clear ();
}
int size () const
{
return values.size ();
}
};
class streamline_t
{
public:
streamline_t () : VAID (this) {}
explicit streamline_t (const streamline_t & stream) : VAID (this)
{
d = stream.d;
}
void setupVertexAttributes () const;
void setup (const streamline_data_t &, GLint [], GLint [], GLint []);
void clear ()
{
VAID.clear ();
}
void render (const bool &, const float &, const glGrib::View &) const;
struct
{
OpenGLBufferPtr<float> vertexbuffer, normalbuffer, distancebuffer;
GLuint size;
GLint vertexLonLat_attr[3];
GLint norm_attr[2];
GLint dist_attr[2];
} d;
OpenGLVertexArray<streamline_t> VAID;
};
class stream_seen_t : public std::set<int>
{
public:
bool has (const int & k)
{
return end () != find (k);
}
bool operator[] (const int & k)
{
return has (k);
}
void add (const int & k)
{
insert (k);
}
void del (const int & k)
{
erase (k);
}
};
void getFirstPoint (int, const BufferPtr<float> &, const BufferPtr<float> &,
glm::vec2 &, glm::vec2 &, glm::vec2 &,
std::valarray<float> &, std::valarray<float> &,
int &, int &, const const_GeometryPtr &);
void computeStreamLine (int, const BufferPtr<float> &,
const BufferPtr<float> &, streamline_data_t *,
const const_GeometryPtr &);
void computeStreamLineDir (int, const BufferPtr<float> &, const BufferPtr<float> &,
const glm::vec2 &, const glm::vec2 &,
stream_seen_t &, float, std::valarray<float>,
std::vector<glm::vec3> &, const const_GeometryPtr &);
struct
{
std::vector<streamline_t> stream;
float normmax;
double time0 = 0.0f;
} d;
};
}
|