#pragma once #include #include #include #include #include #include #include template using marked_subface_ptr_t = marked_ptr; enum class sign_t : uint8_t { positive = 1, negative = 2, zero = 0 }; static inline sign_t operator*(sign_t a, sign_t b) { if (a == sign_t::zero || b == sign_t::zero) return sign_t::zero; if (a == b) return sign_t::positive; return sign_t::negative; } static inline sign_t sign_by_sdf(double sdf_value) { static constexpr double eps = 0; if (sdf_value > eps) return sign_t::positive; if (sdf_value < -eps) return sign_t::negative; return sign_t::zero; } static inline sign_t sign_by_subface(bool mark) { if (mark) return sign_t::negative; return sign_t::positive; } static inline sign_t operator&(sign_t a, sign_t b) { auto a_sign = static_cast(a); auto b_sign = static_cast(b); return static_cast((a_sign & b_sign & 2) | ((a_sign | b_sign) & 1)); } struct subface; EXTERN_C struct PE_API primitive { virtual void initialize(primitive_data_center_t &) = 0; virtual void destroy() = 0; virtual primitive_type get_type() const = 0; virtual marked_subface_ptr_t *get_subface() const = 0; virtual size_t get_subface_count() const = 0; // sign_t judge_sign_by_subface_sdf(const std::vector &) const; // sign_t judge_sign_by_subface_sdf_sign(const std::vector &) const; dynamic_bitset_mp<> judge_sign_by_subface_sign(stl_vector_mp>) const; // for simple primitive: sphere, cylinder, cone, box // we use world_to_local as OBB and judge inside/outside by [-1, 1]^3 // so we don't need to fetch aabb anymore // aabb fetch_aabb() const; // CAUTION: keep characteristics local_to_world as the first subface's part const internal::transform_block &get_identity_local_to_world() const; void apply_transform(internal::transform_type, Eigen::Vector4d); protected: virtual void initialize(primitive_data_center_t &, const std::vector> &) = 0; };