27 static const double cam[9] =
39 eye[0] = cam[0]; eye[1] = cam[1]; eye[2] = cam[2];
40 dir[0] = cam[3]; dir[1] = cam[4]; dir[2] = cam[5];
41 up [0] = cam[6]; up [1] = cam[7]; up [2] = cam[8];
61 double old_dir[3] = { dir[0], dir[1], dir[2] };
62 double c = cos(angle), s = sin(angle);
76 -left[0], up[0], -dir[0], 0.0,
77 -left[1], up[1], -dir[1], 0.0,
78 -left[2], up[2], -dir[2], 0.0,
82 return glm::make_mat4(mat);
91 -left[0], -left[1], -left[2], 0.0,
92 up[0], up[1], up[2], 0.0,
93 -dir[0], -dir[1], -dir[2], 0.0,
97 return glm::make_mat4(mat_t);
102 glm::mat4 rotmtx = RotMatrix();
103 return glm::translate(rotmtx, glm::vec3(-eye[0], -eye[1], -eye[2]));
109 "camera " << eye[0] <<
' ' << eye[1] <<
' ' << eye[2] <<
"\n"
110 " " << dir[0] <<
' ' << dir[1] <<
' ' << dir[2] <<
"\n"
111 " " << up[0] <<
' ' << up[1] <<
' ' << up[2] <<
'\n'
117 translmat = glm::mat4(1.0);
118 rotmat = glm::mat4(1.0);
119 rotmat = glm::rotate(rotmat, glm::radians(-60.f), glm::vec3(1.f, 0.f, 0.f));
120 rotmat = glm::rotate(rotmat, glm::radians(-40.f), glm::vec3(0.f, 0.f, 1.f));
121 xscale = yscale = zscale = 1;
122 spinning = print = movie = 0;
123 OrthogonalProjection = 0;
132 background = BG_WHITE;
134 _use_cust_l0_pos =
false;
146 const double (&p)[4][3],
const double (&cv)[4],
147 const double minv,
const double maxv)
151 c[0] = c[1] = c[2] = 0.0;
152 for (
int j = 0; j < 3; j++)
154 c[0] += p[j][0]; c[1] += p[j][1]; c[2] += p[j][2];
156 c[0] /= 3.0; c[1] /= 3.0; c[2] /= 3.0;
158 double l = cut_lambda;
162 for (
int j = 0; j < 3; j++)
164 q[j][0] = l*p[j][0] + (1.0-l)*c[0];
165 q[j][1] = l*p[j][1] + (1.0-l)*c[1];
166 q[j][2] = l*p[j][2] + (1.0-l)*c[2];
173 for (
int k = 0; k < 3; k++)
175 d[0][k] = p[0][k]; d[1][k] = p[1][k]; d[2][k] = q[1][k]; d[3][k] = q[0][k];
177 DrawQuad(buff, d, cvv, minv, maxv);
180 for (
int k = 0; k < 3; k++)
182 d[0][k] = p[1][k]; d[1][k] = p[2][k]; d[2][k] = q[2][k]; d[3][k] = q[1][k];
184 DrawQuad(buff, d, cvv, minv, maxv);
187 for (
int k = 0; k < 3; k++)
189 d[0][k] = p[2][k]; d[1][k] = p[0][k]; d[2][k] = q[0][k]; d[3][k] = q[2][k];
191 DrawQuad(buff, d, cvv, minv, maxv);
197 const double (&p)[4][3],
const double (&cv)[4],
198 const double minv,
const double maxv)
202 c[0] = c[1] = c[2] = 0.0;
203 for (
int j = 0; j < 4; j++)
205 c[0] += p[j][0]; c[1] += p[j][1]; c[2] += p[j][2];
207 c[0] /= 4.0; c[1] /= 4.0; c[2] /= 4.0;
209 double l = cut_lambda;
213 for (
int j = 0; j < 4; j++)
215 q[j][0] = l*p[j][0] + (1.0-l)*c[0];
216 q[j][1] = l*p[j][1] + (1.0-l)*c[1];
217 q[j][2] = l*p[j][2] + (1.0-l)*c[2];
224 for (
int k = 0; k < 3; k++)
226 d[0][k] = p[0][k]; d[1][k] = p[1][k]; d[2][k] = q[1][k]; d[3][k] = q[0][k];
228 DrawQuad(buff, d, cvv, minv, maxv);
231 for (
int k = 0; k < 3; k++)
233 d[0][k] = p[1][k]; d[1][k] = p[2][k]; d[2][k] = q[2][k]; d[3][k] = q[1][k];
235 DrawQuad(buff, d, cvv, minv, maxv);
238 for (
int k = 0; k < 3; k++)
240 d[0][k] = p[2][k]; d[1][k] = p[3][k]; d[2][k] = q[3][k]; d[3][k] = q[2][k];
242 DrawQuad(buff, d, cvv, minv, maxv);
245 for (
int k = 0; k < 3; k++)
247 d[0][k] = p[3][k]; d[1][k] = p[0][k]; d[2][k] = q[0][k]; d[3][k] = q[3][k];
249 DrawQuad(buff, d, cvv, minv, maxv);
255 const double (&pts)[4][3],
const double (&cv)[4],
256 const double minv,
const double maxv)
264 std::array<float, 2> texcoord[3];
265 std::array<float, 3> fpts[3];
266 std::array<float, 3> fnorm = {(float) nor[0], (
float) nor[1], (float) nor[2]};
268 for (
int i = 0; i < 3; i++)
270 float pal_coord = palette.GetColorCoord(cv[i], minv, maxv);
271 texcoord[i] = { pal_coord, 1.0 };
272 fpts[i] = {(float) pts[i][0], (
float) pts[i][1], (float) pts[i][2]};
275 {fpts[0], fnorm, texcoord[0]},
276 {fpts[1], fnorm, texcoord[1]},
277 {fpts[2], fnorm, texcoord[2]});
282 const double (&pts)[4][3],
const double (&cv)[4],
283 const double minv,
const double maxv)
291 std::array<float, 2> texcoord[4];
292 std::array<float, 3> fpts[4];
293 std::array<float, 3> fnorm = {(float) nor[0], (
float) nor[1], (float) nor[2]};
295 for (
int i = 0; i < 4; i++)
297 float pal_coord = palette.GetColorCoord(cv[i], minv, maxv);
298 texcoord[i] = { pal_coord, 1.0 };
299 fpts[i] = {(float) pts[i][0], (
float) pts[i][1], (float) pts[i][2]};
302 {fpts[0], fnorm, texcoord[0]},
303 {fpts[1], fnorm, texcoord[1]},
304 {fpts[2], fnorm, texcoord[2]},
305 {fpts[3], fnorm, texcoord[3]});
310 DenseMatrix &normals,
311 const int n,
const Array<int> &ind,
const double minv,
312 const double maxv,
const int normals_opt)
317 if (normals_opt == 1 || normals_opt == -2)
319 normals.SetSize(3, pts.Width());
321 for (
int i = 0; i < ind.Size(); i += n)
326 &pts(0, ind[i+2]), na);
329 &pts(0, ind[i+2]), &pts(0, ind[i+3]), na);
332 for (
int k = 0; k < 3; k++)
334 normals(k, ind[i+j]) += na[k];
339 if (normals_opt != 0 && normals_opt != -1)
342 std::vector<gl3::VertexNormTex> vertices;
343 std::vector<int> indices;
344 vertices.reserve(pts.Size());
345 indices.reserve(ind.Size());
346 for (
int i = 0; i < pts.Width(); i++)
348 vertices.emplace_back(
351 {(float) pts(0, i), (float) pts(1, i), (float) pts(2, i)},
352 {(float) normals(0, i), (float) normals(1, i), (float) normals(2, i)},
353 {(float) palette.GetColorCoord(vals(i), minv, maxv), 1.0 }
358 for (
int i = 0; i < ind.Size(); i++)
360 indices.emplace_back(ind[i]);
365 for (
int i = ind.Size()-1; i >= 0; i--)
367 indices.emplace_back(ind[i]);
389 for (
int i = 0; i < ind.Size(); i += n)
394 &pts(0, ind[i+2]), na);
397 &pts(0, ind[i+2]), &pts(0, ind[i+3]), na);
400 if (normals_opt == 0)
405 MySetColor(poly, vals(ind[i+j]), minv, maxv);
412 for (j = n-1; j >= 0; j--)
414 MySetColor(poly, vals(ind[i+j]), minv, maxv);
427 #ifdef GLVIS_USE_LIBPNG
428 const bool palette_smooth = palette.GetSmoothSetting();
440 const int palette_size = palette.GetNumColors();
441 vector<array<float,4>> palette_data(palette_size);
444 palette.GetColorTexture(), 0,
448 palette_data.data());
450 glGetTexImage(GL_TEXTURE_2D, 0,
452 GL_FLOAT, palette_data.data());
454 const double *palette_data_raw = palette.GetData();
455 for (
int i = 0; i < palette_size; ++i)
457 for (
int j = 0; j < 3; ++j)
459 palette_data[i][j] = (float) palette_data_raw[j + 3*i];
461 palette_data[i][3] = 1.0f;
469 palette_data.data());
470 auto palette_tex = bld.
addTexture(sampler, palette_img);
474 { 1.f, 1.f, 1.f, 1.f },
479 #else // GLVIS_USE_LIBPNG
483 { 0.f, 1.f, .5f, 1.f },
488 #endif // GLVIS_USE_LIBPNG
526 auto palette_lines_mat =
528 "PaletteLines Material",
531 return palette_lines_mat;
537 auto new_node = bld.
addNode(nodeName);
543 new_node, { (float)xscale, (
float)zscale, (float)yscale });
545 new_node, { float(-xscale*(bb.x[0]+bb.x[1])/2),
546 float(-zscale*bb.z[0]),
547 float(yscale*(bb.y[0]+bb.y[1])/2)
553 void minmax(
const float *data,
size_t components,
size_t stride,
size_t count,
554 vector<float> &mins, vector<float> &maxs)
558 mins.assign(components, +numeric_limits<float>::infinity());
559 maxs.assign(components, -numeric_limits<float>::infinity());
562 mins.resize(components);
563 maxs.resize(components);
564 for (
size_t c = 0; c != components; ++c)
566 const auto entry = data[c];
570 if (count == 1) {
return; }
571 for (
size_t i = 1; i != count; ++i)
574 for (
size_t c = 0; c != components; ++c)
576 const auto entry = data[c];
577 if (entry < mins[c]) { mins[c] = entry; }
578 else if (entry > maxs[c]) { maxs[c] = entry; }
589 int num_buf = 0, buf_layout = -1;
593 if (buf && buf->
count() != 0)
597 cout <<
"triangles: layout = " << layout <<
", # vertices = "
598 << buf->
count() <<
'\n';
601 int num_ibuf = 0, ibuf_layout = -1;
605 gl_drawable.indexed_buffers[layout][1].get();
609 ibuf_layout = layout;
610 cout <<
"indexed triangles: layout = " << layout <<
", # vertices = "
615 if (num_buf + num_ibuf == 0) {
return 0; }
617 if (num_buf + num_ibuf > 1)
619 cout <<
"glTF export: skipping" << num_buf + num_ibuf - 1
620 <<
" triangle buffer(s).\n";
624 const vector<int> *surf_indices =
nullptr;
627 surf_buf = surf_ibuf = gl_drawable.indexed_buffers[ibuf_layout][1].get();
629 buf_layout = ibuf_layout;
633 surf_buf = gl_drawable.buffers[buf_layout][1].get();
635 const size_t surf_vertices_count = surf_buf->
count();
636 const size_t surf_vertices_stride = surf_buf->
getStride();
637 const float *surf_vertices_data =
638 reinterpret_cast<const float *
>(surf_buf->
getData());
639 vector<float> vmins, vmaxs;
640 int components = surf_vertices_stride/
sizeof(float);
650 minmax(surf_vertices_data, components, surf_vertices_stride/
sizeof(
float),
651 surf_vertices_count, vmins, vmaxs);
656 surf_indices_buf_view =
659 surf_indices->data(),
660 surf_indices->size()*
sizeof(int),
666 auto surf_vertices_buf_view =
670 surf_vertices_count*surf_vertices_stride,
671 surf_vertices_stride,
675 auto surf_vertices_buf_view =
680 surf_vertices_stride,
689 auto surf_vert_data =
690 reinterpret_cast<const gl3::Vertex *
>(surf_vertices_data);
691 for (
size_t i = 0; i != surf_vertices_count; ++i)
693 auto &v = surf_vert_data[i];
701 auto surf_vert_data =
703 for (
size_t i = 0; i != surf_vertices_count; ++i)
705 auto &v = surf_vert_data[i];
708 { v.
coord[0], v.coord[2], -v.coord[1] },
709 { v.norm[0], v.norm[2], -v.norm[1] }
717 auto surf_vert_data =
719 for (
size_t i = 0; i != surf_vertices_count; ++i)
721 auto &v = surf_vert_data[i];
724 { v.
coord[0], v.coord[2], -v.coord[1] },
725 { v.norm[0], v.norm[2], -v.norm[1] },
734 cout <<
"glTF export: coorditate switch for layout " << buf_layout
735 <<
" is not implemented here:" << MFEM_LOCATION;
738 surf_vertices_count*surf_vertices_stride);
748 surf_indices_buf_view,
751 surf_indices->size(),
754 auto surf_vertices_pos_acc =
756 surf_vertices_buf_view,
760 { vmins[0], vmins[2], -vmaxs[1] },
761 { vmaxs[0], vmaxs[2], -vmins[1] });
762 unsigned floatOffset = 3;
764 const bool have_normals =
770 surf_vertices_nor_acc =
772 surf_vertices_buf_view,
773 floatOffset*
sizeof(
float),
780 const bool have_texcoords =
785 surf_vertices_tex_acc =
787 surf_vertices_buf_view,
788 floatOffset*
sizeof(
float),
790 { vmins[floatOffset], vmins[floatOffset+1] },
791 { vmaxs[floatOffset], vmaxs[floatOffset+1] });
796 surf_vertices_pos_acc,
797 surf_vertices_nor_acc,
798 surf_vertices_tex_acc,
802 return surf_indices ? surf_indices->size()/3 : surf_vertices_count/3;
811 int num_buf = 0, buf_layout = -1;
815 if (buf && buf->
count() != 0)
819 cout <<
"lines: layout = " << layout <<
", # vertices = "
820 << buf->
count() <<
'\n';
827 gl_drawable.indexed_buffers[layout][0].get();
832 cout <<
"indexed lines: layout = " << layout <<
", # vertices = "
837 if (num_buf + num_ibuf == 0) {
return 0; }
840 cout <<
"glTF export: indexed lines are not implemented.\n";
843 if (num_buf + num_ibuf > 1)
845 cout <<
"glTF export: skipping" << num_buf + num_ibuf - 1
846 <<
" line buffer(s).\n";
849 gl_drawable.buffers[buf_layout][0].get();
850 const size_t lines_vertices_count = lines_buf->
count();
851 const size_t lines_vertices_stride = lines_buf->
getStride();
852 const float *lines_vertices_data =
853 reinterpret_cast<const float *
>(lines_buf->
getData());
854 vector<float> vmins, vmaxs;
855 int components = lines_vertices_stride/
sizeof(float);
865 minmax(lines_vertices_data, components, lines_vertices_stride/
sizeof(
float),
866 lines_vertices_count, vmins, vmaxs);
869 auto lines_vertices_buf_view =
873 lines_vertices_count*lines_vertices_stride,
874 lines_vertices_stride,
878 auto lines_vertices_buf_view =
883 lines_vertices_stride,
892 auto lines_vert_data =
893 reinterpret_cast<const gl3::Vertex *
>(lines_vertices_data);
894 for (
size_t i = 0; i != lines_vertices_count; ++i)
896 auto &v = lines_vert_data[i];
904 auto lines_vert_data =
906 for (
size_t i = 0; i != lines_vertices_count; ++i)
908 auto &v = lines_vert_data[i];
911 { v.
coord[0], v.coord[2], -v.coord[1] }, v.color
919 auto lines_vert_data =
921 for (
size_t i = 0; i != lines_vertices_count; ++i)
923 auto &v = lines_vert_data[i];
926 { v.
coord[0], v.coord[2], -v.coord[1] }, v.texCoord
934 cout <<
"glTF export: coorditate switch for layout " << buf_layout
935 <<
" is not implemented here:" << MFEM_LOCATION;
938 lines_vertices_count*lines_vertices_stride);
943 auto lines_vertices_pos_acc =
945 lines_vertices_buf_view,
947 lines_vertices_count,
949 { vmins[0], vmins[2], -vmaxs[1] },
950 { vmaxs[0], vmaxs[2], -vmins[1] });
951 unsigned floatOffset = 3;
956 lines_vertices_col_acc =
958 lines_vertices_buf_view,
959 floatOffset*
sizeof(
float),
961 lines_vertices_count,
969 lines_vertices_tex_acc =
971 lines_vertices_buf_view,
972 floatOffset*
sizeof(
float),
973 lines_vertices_count,
974 { vmins[floatOffset], vmins[floatOffset+1] },
975 { vmaxs[floatOffset], vmaxs[floatOffset+1] });
980 lines_vertices_pos_acc,
981 lines_vertices_tex_acc,
982 lines_vertices_col_acc,
985 return lines_vertices_count/2;
997 if (light_mat_idx == 4)
999 for (
int i = 0; i < 3; i++)
1011 if (_use_cust_l0_pos)
1013 params.
lights[0].position = _l0_pos;
1025 _use_cust_l0_pos =
false;
1032 _use_cust_l0_pos =
true;
1037 if (background == BG_BLK)
1039 background = BG_WHITE;
1044 background = BG_BLK;
1053 rot_tmp.
mult(cam.TransposeRotMatrix());
1054 rot_tmp.
rotate(angle, x, y, z);
1055 rot_tmp.
mult(cam.RotMatrix());
1056 rot_tmp.
mult(rotmat);
1057 rotmat = rot_tmp.
mtx;
1062 rotmat = glm::rotate<float>(rotmat, glm::radians(angle), glm::vec3(x,y,z));
1069 rot_tmp.
mult(cam.TransposeRotMatrix());
1070 rot_tmp.
rotate(angley, 0.0, 1.0, 0.0);
1071 rot_tmp.
rotate(anglex, 1.0, 0.0, 0.0);
1072 rot_tmp.
mult(cam.RotMatrix());
1073 rot_tmp.
mult(rotmat);
1074 rotmat = rot_tmp.
mtx;
1083 trans_tmp.
mult(translmat);
1084 translmat = trans_tmp.
mtx;
1103 translmat = tmp_mtx.
mtx;
1104 tmp_mtx.
rotate(-60.f, 1.f, 0.f, 0.f);
1105 tmp_mtx.
rotate(-40.f, 0.f, 0.f, 1.f);
1106 rotmat = tmp_mtx.
mtx;
1111 translmat = glm::mat4(1.0);
1112 rotmat = glm::mat4(1.0);
1119 translmat = tmp_mtx.
mtx;
1120 tmp_mtx.
rotate(-theta, 1.f, 0.f, 0.f);
1121 tmp_mtx.
rotate(-phi, 0.f, 0.f, 1.f);
1122 rotmat = tmp_mtx.
mtx;
1127 if (OrthogonalProjection)
1129 ViewScale *= factor;
1133 double va = ViewAngle * ( M_PI / 360.0 );
1134 ViewAngle = atan( tan( va ) / factor ) * (360.0 / M_PI);
1142 modelView.
mult(cam.TranslateMatrix());
1143 modelView.
mult(translmat);
1144 modelView.
mult(rotmat);
1145 modelView.
scale(xscale, yscale, zscale);
1146 modelView.
translate(-(bb.x[0]+bb.x[1])/2, -(bb.y[0]+bb.y[1])/2,
1147 -(bb.z[0]+bb.z[1])/2);
1148 return modelView.
mtx;
gl3::RenderParams GetMeshDrawParams()
std::array< float, 3 > coord
int ProjectVector(double v[], const double n[])
void identity()
Sets the matrix to the identity matrix.
int AddTriangles(glTF_Builder &bld, glTF_Builder::mesh_id mesh, glTF_Builder::buffer_id buffer, glTF_Builder::material_id material, const gl3::GlDrawable &gl_drawable)
void setClearColor(float r, float g, float b, float a)
void translate(double x, double y, double z)
Applies a translation transform to the matrix.
material_id addMaterial(const std::string &materialName, const pbr_matallic_roughness &pbrMetallicRoughness, bool doubleSided=false)
void addNodeScale(node_id node, vec3f scale)
int Normalize(double v[])
accessor_id addAccessorVec3f(buffer_view_id bufferView, size_t byteOffset, size_t count, vec3f min, vec3f max)
buffer_view_id addBufferView(buffer_id buffer, const void *data, size_t byteLength, size_t byteStride, size_t byteAlign, target_type target)
virtual size_t count() const =0
Gets the number of vertices contained in the buffer.
void Set(const double cam[])
sampler_id addSampler(mag_filter magFilter=mag_filter::NEAREST, min_filter minFilter=min_filter::NEAREST, wrap_type wrapS=wrap_type::CLAMP_TO_EDGE, wrap_type wrapT=wrap_type::CLAMP_TO_EDGE)
gl3::MeshRenderer & getRenderer()
int AddLines(glTF_Builder &bld, glTF_Builder::mesh_id mesh, glTF_Builder::buffer_id buffer, glTF_Builder::material_id material, const gl3::GlDrawable &gl_drawable)
void Translate(double x, double y, double z=0.0)
void TiltLeftRight(double angle)
void appendToBufferView(buffer_view_id bufferView, const void *data, size_t byteLength)
void addMeshLines(mesh_id mesh, accessor_id vertexPositions, accessor_id vertexTexcoords0, accessor_id vertexColors0, material_id material)
void glNormal3dv(const double *d)
void TurnUpDown(double angle)
void addNodeTranslation(node_id node, vec3f translation)
void DrawPatch(gl3::GlDrawable &buff, const mfem::DenseMatrix &pts, mfem::Vector &vals, mfem::DenseMatrix &normals, const int n, const mfem::Array< int > &ind, const double minv, const double maxv, const int normals_opt=0)
void addMeshTriangles(mesh_id mesh, accessor_id vertexPositions, accessor_id vertexNormals, accessor_id vertexTexCoords0, accessor_id vertexIndices, material_id material)
glTF_Builder::node_id AddModelNode(glTF_Builder &bld, const std::string &nodeName)
std::array< float, 4 > light_amb_scene
std::array< float, 3 > coord
glm::mat4 TranslateMatrix()
int Compute3DUnitNormal(const double p1[], const double p2[], const double p3[], double nor[])
glTF_Builder::material_id AddBlackMaterial(glTF_Builder &bld)
std::array< Light, LIGHTS_MAX > lights
texture_id addTexture(sampler_id sampler, image_id source)
void PreRotate(double angle, double x, double y, double z)
static bool useLegacyTextureFmts()
std::array< float, 3 > coord
glTF_Builder::material_id AddPaletteLinesMaterial(glTF_Builder &bld, glTF_Builder::material_id palette_mat)
void glNormal3d(double nx, double ny, double nz)
std::array< float, 3 > coord
void DrawTriangle(gl3::GlDrawable &buff, const double(&pts)[4][3], const double(&cv)[4], const double minv, const double maxv)
void SetLight0CustomPos(std::array< float, 4 > pos)
virtual ~VisualizationScene()
void addTriangleIndexed(const std::vector< Vert > &verts, const std::vector< int > &inds)
std::array< float, 4 > amb_setting[]
GlBuilder createBuilder()
virtual const void * getData() const =0
void SetView(double theta, double phi)
void scale(double x, double y, double z)
Applies a scale transform to the matrix.
virtual size_t getStride() const =0
Gets the stride between vertices.
void rotate(float angle, double x, double y, double z)
Applies a rotation transform to the matrix.
node_id addNode(const std::string &nodeName)
image_id addImage(const std::string &imageName, int width, int height, const color4f *pixels)
std::array< float, 3 > coord
void SetLightMatIdx(unsigned i)
accessor_id addAccessor(buffer_view_id bufferView, size_t byteOffset, component_type componentType, size_t count, tensor_type tensorType)
SdlWindow * GetAppWindow()
Crude fixed-function OpenGL emulation helper.
glm::mat4 GetModelViewMtx()
void DrawQuad(gl3::GlDrawable &buff, const double(&pts)[4][3], const double(&cv)[4], const double minv, const double maxv)
virtual const std::vector< int > & getIndices() const =0
void addQuadIndexed(const std::vector< Vert > &verts, const std::vector< int > &inds)
glTF_Builder::material_id AddPaletteMaterial(glTF_Builder &bld)
glm::mat4 TransposeRotMatrix()
void getMaterialPBRMR(material_id material, pbr_matallic_roughness &pbr_mr_copy)
static constexpr unsigned INVALID_ID
void addTriangle(const Vert &v1, const Vert &v2, const Vert &v3)
void DrawCutTriangle(gl3::GlDrawable &buff, const double(&pts)[4][3], const double(&cv)[4], const double minv, const double maxv)
void glVertex3dv(const double *d)
void TurnLeftRight(double angle)
void addQuad(const Vert &v1, const Vert &v2, const Vert &v3, const Vert &v4)
void LinearCombination(const double a, const double x[], const double b, const double y[], double z[])
std::array< float, 4 > static_color
accessor_id addAccessorVec2f(buffer_view_id bufferView, size_t byteOffset, size_t count, vec2f min, vec2f max)
void DrawCutQuad(gl3::GlDrawable &buff, const double(&pts)[4][3], const double(&cv)[4], const double minv, const double maxv)
void minmax(const float *data, size_t components, size_t stride, size_t count, vector< float > &mins, vector< float > &maxs)
void Rotate(double angle, double x, double y, double z)