29 for (
const int curve_i : segment) {
30 const IndexRange points = points_by_curve[curve_i].drop_back(1);
31 for (
const int point_i : points) {
32 const float3 &p1 = positions[point_i];
33 const float3 &p2 = positions[point_i + 1];
35 r_segment_lengths[point_i] =
length;
49 for (
const int curve_i : segment) {
50 const IndexRange points = points_by_curve[curve_i].drop_back(1);
51 for (
const int point_i : points) {
52 const float3 &p1 = positions[point_i];
53 float3 &p2 = positions[point_i + 1];
55 const float goal_length = segment_lenghts[point_i];
56 p2 = p1 + direction * goal_length;
76 const float radius = 0.005f;
77 const int max_collisions = 5;
80 for (
const int curve_i : segment) {
81 const IndexRange points = points_by_curve[curve_i];
85 bool revert_curve =
false;
86 for (
const int point_i : points.drop_front(1)) {
87 const float goal_segment_length_cu = segment_lengths_cu[point_i - 1];
88 const float3 &prev_pos_cu = positions_cu[point_i - 1];
89 const float3 &start_pos_cu = start_positions_cu[point_i];
91 int used_iterations = 0;
92 for ([[maybe_unused]]
const int iteration :
IndexRange(max_collisions)) {
94 const float3 &old_pos_cu = positions_cu[point_i];
95 if (start_pos_cu == old_pos_cu) {
105 const float3 pos_diff_su = old_pos_su - start_pos_su;
106 float max_ray_length_su;
111 hit.dist = max_ray_length_su + radius;
119 if (hit.index == -1) {
122 const float3 hit_pos_su = hit.co;
123 const float3 hit_normal_su = hit.no;
124 if (
math::dot(hit_normal_su, ray_direction_su) > 0.0f) {
138 const float3 plane_pos_cu = hit_pos_cu + hit_normal_cu * radius;
139 const float3 plane_normal_cu = hit_normal_cu;
143 const float3 collided_segment_cu = plane_pos_cu - prev_pos_cu;
144 const float3 slide_normal_cu = plane_normal_cu *
145 math::dot(collided_segment_cu, plane_normal_cu);
146 const float3 slide_direction_cu = collided_segment_cu - slide_normal_cu;
148 float slide_direction_length_cu;
150 slide_direction_cu, slide_direction_length_cu);
153 if (
pow2f(goal_segment_length_cu) > slide_normal_length_sq_cu) {
155 const float slide_distance_cu = std::sqrt(
pow2f(goal_segment_length_cu) -
156 slide_normal_length_sq_cu) -
157 slide_direction_length_cu;
158 positions_cu[point_i] = plane_pos_cu +
159 normalized_slide_direction_cu * slide_distance_cu;
164 positions_cu[point_i] = prev_pos_cu +
math::normalize(old_pos_su - prev_pos_cu) *
165 goal_segment_length_cu;
168 if (used_iterations == max_collisions) {
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ BVHTREE_FROM_CORNER_TRIS
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
MINLINE float pow2f(float x)
#define BLI_SCOPED_DEFER(function_to_defer)
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr void copy_from(Span< T > values) const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
void foreach_segment(Fn &&fn) const
void solve_length_constraints(OffsetIndices< int > points_by_curve, const IndexMask &curve_selection, Span< float > segment_lenghts, MutableSpan< float3 > positions)
void solve_length_and_collision_constraints(OffsetIndices< int > points_by_curve, const IndexMask &curve_selection, Span< float > segment_lengths, Span< float3 > start_positions, const Mesh &surface, const bke::CurvesSurfaceTransforms &transforms, MutableSpan< float3 > positions)
void compute_segment_lengths(OffsetIndices< int > points_by_curve, Span< float3 > positions, const IndexMask &curve_selection, MutableSpan< float > r_segment_lengths)
T length_squared(const VecBase< T, Size > &a)
T distance(const T &a, const T &b)
QuaternionBase< T > normalize_and_get_length(const QuaternionBase< T > &q, T &out_length)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
BVHTree_RayCastCallback raycast_callback