neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
mesh.hpp
Go to the documentation of this file.
1// i_mesh.hpp
2/*
3 neogfx C++ App/Game Engine
4 Copyright (c) 2015, 2020 Leigh Johnston. All Rights Reserved.
5
6 This program is free software: you can redistribute it and / or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19#pragma once
20
21#include <neogfx/neogfx.hpp>
22#include <neolib/core/uuid.hpp>
26#include <neogfx/game/i_ecs.hpp>
28
29namespace neogfx::game
30{
31 struct mesh
32 {
33 vertices vertices; // todo: neolib::vector not std::vector (modify neolib::vector copy ctor to make plugin compatible; use ref_ptr<i_vector> here?)
34 vertices_2d uv; // todo: neolib::vector not std::vector (modify neolib::vector copy ctor to make plugin compatible; use ref_ptr<i_vector> here?)
35 faces faces; // todo: neolib::vector not std::vector (modify neolib::vector copy ctor to make plugin compatible; use ref_ptr<i_vector> here?)
36
38 {
39 static const neolib::uuid& id()
40 {
41 static const neolib::uuid sId = { 0x5a6608ed, 0x2809, 0x4c1f, 0x9620, { 0xa6, 0xf1, 0x77, 0xab, 0x9c, 0x2a } };
42 return sId;
43 }
44 static const i_string& name()
45 {
46 static const string sName = "Mesh";
47 return sName;
48 }
49 static uint32_t field_count()
50 {
51 return 3;
52 }
53 static component_data_field_type field_type(uint32_t aFieldIndex)
54 {
55 switch (aFieldIndex)
56 {
57 case 0:
58 return component_data_field_type::Vec3 | component_data_field_type::Array;
59 case 1:
60 return component_data_field_type::Vec2 | component_data_field_type::Array;
61 case 2:
62 return component_data_field_type::Face | component_data_field_type::Array;
63 default:
64 throw invalid_field_index();
65 }
66 }
67 static const i_string& field_name(uint32_t aFieldIndex)
68 {
69 static const string sFieldNames[] =
70 {
71 "Vertices",
72 "UV",
73 "Faces"
74 };
75 return sFieldNames[aFieldIndex];
76 }
77 };
78 };
79
80 inline mesh operator*(const mat44& aLhs, const mesh& aRhs)
81 {
82 return mesh{ aLhs * aRhs.vertices, aRhs.uv, aRhs.faces };
83 }
84
85 inline rect bounding_rect(const vertices& aVertices, const mat44& aTransformation = mat44::identity())
86 {
87 if (aVertices.empty())
88 return rect{};
89 point topLeft{ aTransformation * aVertices[0] };
90 point bottomRight;
91 for (auto const& v : aVertices)
92 {
93 auto const tv = aTransformation * v;
94 topLeft.x = std::min<coordinate>(topLeft.x, tv.x);
95 topLeft.y = std::min<coordinate>(topLeft.y, tv.y);
96 topLeft.z = std::min<coordinate>(topLeft.z, tv.z);
97 bottomRight.x = std::max<coordinate>(bottomRight.x, tv.x);
98 bottomRight.y = std::max<coordinate>(bottomRight.y, tv.y);
99 bottomRight.z = std::max<coordinate>(bottomRight.z, tv.z);
100 }
101 return rect{ topLeft, bottomRight };
102 }
103
104 template <typename Container, typename T>
105 inline rect bounding_rect(const Container& aVertices, const basic_matrix<T, 4, 4>& aTransformation = basic_matrix<T, 4, 4>::identity())
106 {
107 if (aVertices.empty())
108 return rect{};
109 point topLeft{ aTransformation * aVertices[0].xyz };
110 point bottomRight;
111 for (auto const& v : aVertices)
112 {
113 auto const tv = aTransformation * v.xyz;
114 topLeft.x = std::min<coordinate>(topLeft.x, tv.x);
115 topLeft.y = std::min<coordinate>(topLeft.y, tv.y);
116 bottomRight.x = std::max<coordinate>(bottomRight.x, tv.x);
117 bottomRight.y = std::max<coordinate>(bottomRight.y, tv.y);
118 }
119 return rect{ topLeft, bottomRight };
120 }
121
122 inline rect bounding_rect(const vertices& aVertices, const faces& aFaces, const mat44& aTransformation = mat44::identity(), vertices::size_type aOffset = 0)
123 {
124 if (aVertices.empty())
125 return rect{};
126 point topLeft{ aTransformation * aVertices[static_cast<vertices::size_type>(aFaces[0][static_cast<uint32_t>(0)]) + aOffset] };
127 point bottomRight = topLeft;
128 for (auto const& f : aFaces)
129 {
130 for (faces::size_type fv = 0; fv < 3; ++fv)
131 {
132 auto const& v = aTransformation * aVertices[static_cast<vertices::size_type>(f[static_cast<uint32_t>(fv)]) + aOffset];
133 topLeft.x = std::min<coordinate>(topLeft.x, v.x);
134 topLeft.y = std::min<coordinate>(topLeft.y, v.y);
135 bottomRight.x = std::max<coordinate>(bottomRight.x, v.x);
136 bottomRight.y = std::max<coordinate>(bottomRight.y, v.y);
137 }
138 }
139 return rect{ topLeft, bottomRight };
140 }
141
142 template <typename Container, typename T>
143 inline rect bounding_rect(const Container& aVertices, const faces& aFaces, const basic_matrix<T, 4, 4>& aTransformation = basic_matrix<T, 4, 4>::identity(), vertices::size_type aOffset = 0)
144 {
145 if (aVertices.empty())
146 return rect{};
147 point topLeft{ aTransformation * aVertices[static_cast<typename Container::size_type>(aFaces[0][static_cast<uint32_t>(0)]) + aOffset].xyz };
148 point bottomRight = topLeft;
149 for (auto const& f : aFaces)
150 {
151 for (faces::size_type fv = 0; fv < 3; ++fv)
152 {
153 auto const& v = aTransformation * aVertices[static_cast<typename Container::size_type>(f[static_cast<uint32_t>(fv)]) + aOffset].xyz;
154 topLeft.x = std::min<coordinate>(topLeft.x, v.x);
155 topLeft.y = std::min<coordinate>(topLeft.y, v.y);
156 bottomRight.x = std::max<coordinate>(bottomRight.x, v.x);
157 bottomRight.y = std::max<coordinate>(bottomRight.y, v.y);
158 }
159 }
160 return rect{ topLeft, bottomRight };
161 }
162
163 inline rect bounding_rect(const mesh& aMesh, const mat44& aTransformation = mat44::identity())
164 {
165 return bounding_rect(aMesh.vertices);
166 }
167
168 inline faces default_faces(uint32_t aVertexCount, uint32_t aOffset = 0u)
169 {
170 faces faces;
171 for (uint32_t i = aOffset; i < aVertexCount + aOffset; i += 3u)
172 faces.push_back(face{ i, i + 1u, i + 2u });
173 return faces;
174 }
175
176 inline faces default_faces(const vertices& aVertices, uint32_t aOffset = 0u)
177 {
178 return default_faces(static_cast<uint32_t>(aVertices.size()), aOffset);
179 }
180}
coordinate_type x
coordinate_type z
coordinate_type y
static const std::enable_if_t< Rows==Columns, SFINAE > & identity()
vec3u32 face
Definition i_ecs.hpp:35
faces default_faces(uint32_t aVertexCount, uint32_t aOffset=0u)
Definition mesh.hpp:168
mesh operator*(const mat44 &aLhs, const mesh &aRhs)
Definition mesh.hpp:80
std::vector< face > faces
Definition i_ecs.hpp:36
rect bounding_rect(const vertices &aVertices, const mat44 &aTransformation=mat44::identity())
Definition mesh.hpp:85
vec3_list vertices
vec2_list vertices_2d
static const neolib::uuid & id()
Definition mesh.hpp:39
static uint32_t field_count()
Definition mesh.hpp:49
static component_data_field_type field_type(uint32_t aFieldIndex)
Definition mesh.hpp:53
static const i_string & field_name(uint32_t aFieldIndex)
Definition mesh.hpp:67
static const i_string & name()
Definition mesh.hpp:44
vertices_2d uv
Definition mesh.hpp:34
vertices vertices
Definition mesh.hpp:33