66 int32_t divisions = params.
lod > 1
71 auto& vertices = result.vertices;
72 auto& indices = result.indices;
73 auto& primitives = result.primitives;
75 const int32_t total_patches = _control_points.size() / _patch_size;
78 for (int32_t id_patch = 0; id_patch < total_patches; ++id_patch)
80 const auto first = _control_points.cbegin() + _patch_size * id_patch;
81 const auto last = _control_points.cbegin() + _patch_size * (id_patch+1);
82 const std::vector<Vertex> patches_points(first, last);
84 std::vector<glm::vec3> patches_positions;
88 patches_positions.reserve(_patch_size);
90 for (
auto& it : patches_points)
92 patches_positions.push_back(it.position);
96 for (int32_t i = 0; i <= divisions; ++i)
98 float u = i / (float)divisions;
100 for (int32_t j = 0; j <= divisions; ++j)
102 float v = j / (float)divisions;
110 glm::vec3 tangent = calculateDerivateU<glm::vec3>(patches_positions, u, v);
111 glm::vec3 bitangent = calculateDerivateV<glm::vec3>(patches_positions, u, v);
113 if (length(tangent) > 0 && length(bitangent) > 0) [[likely]]
115 vertex.
normal = glm::normalize(glm::cross(tangent, bitangent));
129 if (length(tangent) == 0 && length(bitangent) != 0)
131 vertex.
tangent = glm::normalize(glm::cross(vertex.
normal, bitangent));
134 else if (length(bitangent) == 0 && length(tangent) != 0)
141 assert(
false &&
"Tangent space failed !");
155 vertices.push_back(vertex);
178 const size_t vertices_per_edge = (divisions + 1);
179 const size_t vertices_per_edge_pow_2 = vertices_per_edge * vertices_per_edge;
181 const size_t indices_per_patch = divisions * divisions * 6;
183 indices.reserve(total_patches * indices_per_patch);
185 for (int32_t k = 0; k < total_patches; ++k)
187 for (int32_t j = 0; j < divisions; ++j)
189 for (int32_t i = 0; i < divisions; ++i)
191 size_t a = k * vertices_per_edge_pow_2 + j * vertices_per_edge + i;
192 size_t b = a + vertices_per_edge;
196 indices.push_back(x);
197 indices.push_back(b);
198 indices.push_back(a);
200 indices.push_back(y);
201 indices.push_back(b);
202 indices.push_back(x);
209 primitives = {{0, indices.size()}};
213 primitives.reserve(total_patches);
215 for (int32_t id_patch = 0; id_patch < total_patches; ++id_patch)
217 primitives.push_back({id_patch * indices_per_patch, indices_per_patch});
230 if (_patch_type == BezierPatchType::Biquadratic)
232 assert(control_points.size() == 9);
234 std::vector<T> v_curve;
237 for (int32_t i = 0; i < 3; ++i)
241 control_points[3 + i],
242 control_points[6 + i],
245 v_curve.push_back(Bezier::evaluateCurve<util::BezierCurveType::Quadratic, T>(points, v));
248 return Bezier::evaluateDerivativeCurve<util::BezierCurveType::Quadratic, T>(v_curve, u);
252 assert(control_points.size() == 16);
254 std::vector<T> v_curve;
257 for (int32_t i = 0; i < 4; ++i)
261 control_points[4 + i],
262 control_points[8 + i],
263 control_points[12 + i]
266 v_curve.push_back(Bezier::evaluateCurve<util::BezierCurveType::Cubic, T>(points, v));
269 return Bezier::evaluateDerivativeCurve<util::BezierCurveType::Cubic, T>(v_curve, u);
281 if (_patch_type == BezierPatchType::Biquadratic)
283 assert(control_points.size() == 9);
285 std::vector<T> u_curve;
288 for (int32_t i = 0; i < 3; ++i)
290 u_curve.push_back(Bezier::evaluateCurve<util::BezierCurveType::Quadratic, T>({control_points.data() + 3 * i, 3u}, u));
293 return Bezier::evaluateDerivativeCurve<util::BezierCurveType::Quadratic, T>(u_curve, v);
297 assert(control_points.size() == 16);
299 std::vector<T> u_curve;
302 for (int32_t i = 0; i < 4; ++i)
304 u_curve.push_back(Bezier::evaluateCurve<util::BezierCurveType::Cubic, T>({control_points.data() + 4 * i, 4u}, u));
307 return Bezier::evaluateDerivativeCurve<util::BezierCurveType::Cubic, T>(u_curve, v);
315 T
calculatePatch(
const std::vector<T>& control_points,
const float u,
const float v)
319 int32_t patch_edge_size = (int32_t)_patch_type;
321 std::vector<T> curve;
322 curve.reserve(patch_edge_size);
324 for (int32_t i = 0; i < patch_edge_size; ++i)
326 const auto first = control_points.cbegin() + patch_edge_size*i;
327 const auto last = control_points.cbegin() + patch_edge_size*(i+1);
328 const std::vector<T> patches_points(first, last);
330 if (_patch_type == BezierPatchType::Biquadratic)
332 curve.push_back(Bezier::evaluateCurve<util::BezierCurveType::Quadratic, T>(patches_points, u));
336 curve.push_back(Bezier::evaluateCurve<util::BezierCurveType::Cubic, T>(patches_points, u));
340 if (_patch_type == BezierPatchType::Biquadratic)
342 return Bezier::evaluateCurve<util::BezierCurveType::Quadratic, T>(curve, v);
346 return Bezier::evaluateCurve<util::BezierCurveType::Cubic, T>(curve, v);