Program Listing for File mesh.h
↰ Return to documentation for file (src/core/mesh.h)
#pragma once
#include <memory> // for unique_ptr
#include <utility> // for move, swap
#include <vector> // for vector
#include "mesh.h"
#include "primitives/edge.h" // for Edge
#include "primitives/face.h" // for Face
#include "primitives/polygon.h" // for RegularPolygon
#include "primitives/triangle.h" // for Triangle
#include "tal/arrays.h" // for Vector3Array
#include "tal/mesh.h" // for PrimitiveMesh
#include "tal/vector3.h" // for Vector3
namespace sota {
enum class TesselationMode { Iterative = 0, Recursive };
enum class Orientation { Plane = 0, Polyhedron };
class SotaMesh : public PrimitiveMesh {
GDCLASS(SotaMesh, PrimitiveMesh)
public:
SotaMesh(std::unique_ptr<RegularPolygon> base_polygon) : _base_ngon(std::move(base_polygon)) { _base_ngon->check(); }
void set_divisions(const int p_divisions);
int get_divisions() const;
void set_id(int p_id) { _id = p_id; }
int get_id() const { return _id; }
void init();
void update();
const RegularPolygon& base() const { return *_base_ngon.get(); }
void set_base(std::unique_ptr<RegularPolygon> base) { _base_ngon = std::move(base); }
#ifdef SOTA_GDEXTENSION
Array _create_mesh_array() const override;
#else
void _create_mesh_array(Array& result) const override;
#endif
void recalculate_all_except_vertices();
void calculate_normals();
Vector3Array get_vertices() const;
std::vector<Vector3>& get_normals() { return normals_; }
void set_vertices(Vector3Array vertices);
void set_orientation(Orientation p_orientation) { _orientation = p_orientation; }
void set_tesselation_mode(TesselationMode p_tesselation_mode) { _tesselation_mode = p_tesselation_mode; }
Orientation get_orientation() const { return _orientation; }
TesselationMode get_tesselation_mode() const { return _tesselation_mode; }
Vector3 get_center() const { return _base_ngon->center(); }
float get_R() const { return _base_ngon->center().distance_to(_base_ngon->points()[0]); }
float get_r() const {
auto points = _base_ngon->points();
Vector3 side_center = (points[0] + points[1]) / 2;
return _base_ngon->center().distance_to(side_center);
}
Vector3 get_base_normal_direction(Vector3 point) const {
return _orientation == Orientation::Plane ? _base_ngon->normal() : point.normalized();
}
protected:
int _id{0};
int _divisions{1};
std::unique_ptr<RegularPolygon> _base_ngon;
Orientation _orientation{Orientation::Plane};
TesselationMode _tesselation_mode{TesselationMode::Iterative};
Vector3Array vertices_;
std::vector<Vector3> normals_;
TangentsArray tangents_;
ColorsArray colors_;
Vector2Array tex_uv1_;
Vector2Array tex_uv2_;
IntArray indices_;
ByteArray color_custom0_;
ByteArray color_custom1_;
ByteArray color_custom2_;
ByteArray color_custom3_;
IntArray bones_;
WeightsArray weights_;
static void _bind_methods();
virtual void init_impl() = 0;
void calculate_tangents();
void calculate_colors();
virtual void calculate_tex_uv1() = 0;
virtual void calculate_tex_uv2();
void calculate_indices();
void calculate_color_custom();
void calculate_bones_weights();
void tesselate_into_triangles(Vector3 a, Vector3 b, Vector3 c, int level);
// negative offset means direction negative to base hex normal
void add_face_to_base_edge(Edge e, float offset) {
auto c = e.a + get_base_normal_direction(e.a) * offset;
auto d = e.b + get_base_normal_direction(e.b) * offset;
Edge edge1 = Edge{.a = e.a, .b = e.b};
Edge edge2 = Edge{.a = c, .b = d};
if (offset < 0) {
std::swap(edge1, edge2);
}
auto [first_triangle, second_triangle] = Face(edge1, edge2).get_triangles();
vertices_.append_array(first_triangle.to_godot_array());
vertices_.append_array(second_triangle.to_godot_array());
}
void add_faces(float offset) {
for (auto& v : vertices_) {
if (_orientation == Orientation::Polyhedron) {
v += v.normalized() * offset;
} else if (_orientation == Orientation::Plane) {
v += _base_ngon->normal() * offset;
}
}
const int n = _base_ngon->points().size();
for (int i = 0; i < n; ++i) {
auto corner_points = _base_ngon->points();
add_face_to_base_edge(Edge{.a = corner_points[i], .b = corner_points[(i + 1) % n]}, offset);
}
}
private:
Vector3Array normals_to_godot_fmt() const;
};
} // namespace sota