#pragma once #if !defined(MIJIN_GEO_GEOMETRY_TRAITS_HPP_INCLUDED) #define MIJIN_GEO_GEOMETRY_TRAITS_HPP_INCLUDED 1 #include #include namespace mijin { template struct Vector2Traits; template concept Vector2 = requires(const std::decay_t constObject, std::decay_t nonConstObject) { { mijin::Vector2Traits>{}.getX(constObject) } -> std::convertible_to; { mijin::Vector2Traits>{}.getY(constObject) } -> std::convertible_to; { mijin::Vector2Traits>{}.setX(nonConstObject, 0.f) }; { mijin::Vector2Traits>{}.setY(nonConstObject, 0.f) }; }; template struct Vector3Traits; template concept Vector3 = requires(const std::decay_t constObject, std::decay_t nonConstObject) { { mijin::Vector3Traits>{}.getX(constObject) } -> std::convertible_to; { mijin::Vector3Traits>{}.getY(constObject) } -> std::convertible_to; { mijin::Vector3Traits>{}.getZ(constObject) } -> std::convertible_to; { mijin::Vector3Traits>{}.setX(nonConstObject, 0.f) }; { mijin::Vector3Traits>{}.setY(nonConstObject, 0.f) }; { mijin::Vector3Traits>{}.setZ(nonConstObject, 0.f) }; }; template struct Vector4Traits; template concept Vector4 = requires(const std::decay_t constObject, std::decay_t nonConstObject) { { mijin::Vector4Traits>{}.getX(constObject) } -> std::convertible_to; { mijin::Vector4Traits>{}.getY(constObject) } -> std::convertible_to; { mijin::Vector4Traits>{}.getZ(constObject) } -> std::convertible_to; { mijin::Vector4Traits>{}.getW(constObject) } -> std::convertible_to; { mijin::Vector4Traits>{}.setX(nonConstObject, 0.f) }; { mijin::Vector4Traits>{}.setY(nonConstObject, 0.f) }; { mijin::Vector4Traits>{}.setZ(nonConstObject, 0.f) }; { mijin::Vector4Traits>{}.setW(nonConstObject, 0.f) }; }; template concept Index = std::convertible_to; template concept Vector2Iterator = requires(T object) { { std::iterator_traits::value_type } -> Vector2; }; template concept Vector3Iterator = requires(T object) { { std::iterator_traits::value_type } -> Vector3; }; template concept Vector4Iterator = requires(T object) { { std::iterator_traits::value_type } -> Vector4; }; template concept Vector2Range = std::ranges::random_access_range && Vector2>; template concept Vector3Range = std::ranges::random_access_range && Vector3>; template concept Vector4Range = std::ranges::random_access_range && Vector4>; template concept IndexRange = std::ranges::random_access_range && Index>; template struct Mesh3DTraits; template concept Mesh3D = requires(const T constObject, T nonConstObject, mijin::Mesh3DTraits::index_t index, mijin::Mesh3DTraits::vector3_t vec3Value) { { typename mijin::Mesh3DTraits::index_t() } -> Index; { typename mijin::Mesh3DTraits::vector3_t() } -> Vector3; { mijin::Mesh3DTraits{}.getNumFaces(constObject) } -> std::convertible_to; { mijin::Mesh3DTraits{}.getNumVertices(constObject) } -> std::convertible_to; { mijin::Mesh3DTraits{}.getFaceNumVertices(constObject, index) } -> std::convertible_to; { mijin::Mesh3DTraits{}.getPosition(constObject, index, index) } -> Vector3; { mijin::Mesh3DTraits{}.setPosition(nonConstObject, index, index, vec3Value) }; }; template concept Mesh3DWithNormals = Mesh3D && requires(const T constObject, T nonConstObject, mijin::Mesh3DTraits::index_t index, mijin::Mesh3DTraits::vector3_t vec3Value) { { mijin::Mesh3DTraits{}.getNormal(constObject, index, index) } -> Vector3; { mijin::Mesh3DTraits{}.setNormal(nonConstObject, index, index, vec3Value) }; }; template concept Mesh3DWithTangents = Mesh3D && requires(const T constObject, T nonConstObject, mijin::Mesh3DTraits::index_t index, mijin::Mesh3DTraits::vector4_t vec4Value) { { typename mijin::Mesh3DTraits::vector4_t() } -> Vector4; { mijin::Mesh3DTraits{}.getTangent(constObject, index, index) } -> Vector4; { mijin::Mesh3DTraits{}.setTangent(nonConstObject, index, index, vec4Value) }; }; template concept Mesh3DWithTexCoords = Mesh3D && requires(const T constObject, T nonConstObject, mijin::Mesh3DTraits::index_t index, mijin::Mesh3DTraits::vector2_t vec2Value) { { mijin::Mesh3DTraits{}.getTexCoord(constObject, index, index) } -> Vector2; { mijin::Mesh3DTraits{}.setTexCoord(nonConstObject, index, index, vec2Value) }; }; template concept FullMesh3D = Mesh3DWithNormals && Mesh3DWithTangents && Mesh3DWithTexCoords; } #endif // MIJIN_GEO_GEOMETRY_TRAITS_HPP_INCLUDED