Cleanup: Sculpt: Use C++ vector types for cloth simulation
This commit is contained in:
@@ -9,7 +9,9 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_matrix.hh"
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
@@ -63,20 +65,15 @@
|
||||
|
||||
namespace blender::ed::sculpt_paint::cloth {
|
||||
|
||||
static void cloth_brush_simulation_location_get(const SculptSession &ss,
|
||||
const Brush *brush,
|
||||
float r_location[3])
|
||||
static float3 cloth_brush_simulation_location_get(const SculptSession &ss, const Brush *brush)
|
||||
{
|
||||
if (!ss.cache || !brush) {
|
||||
zero_v3(r_location);
|
||||
return;
|
||||
return float3(0);
|
||||
}
|
||||
|
||||
if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
|
||||
copy_v3_v3(r_location, ss.cache->initial_location);
|
||||
return;
|
||||
return ss.cache->initial_location;
|
||||
}
|
||||
copy_v3_v3(r_location, ss.cache->location);
|
||||
return ss.cache->location;
|
||||
}
|
||||
|
||||
Vector<bke::pbvh::Node *> brush_affected_nodes_gather(SculptSession &ss, const Brush &brush)
|
||||
@@ -118,8 +115,8 @@ bool is_cloth_deform_brush(const Brush &brush)
|
||||
|
||||
static float cloth_brush_simulation_falloff_get(const Brush &brush,
|
||||
const float radius,
|
||||
const float location[3],
|
||||
const float co[3])
|
||||
const float3 &location,
|
||||
const float3 &co)
|
||||
{
|
||||
if (brush.sculpt_tool != SCULPT_TOOL_CLOTH) {
|
||||
/* All brushes that are not the cloth brush do not use simulation areas. */
|
||||
@@ -131,7 +128,7 @@ static float cloth_brush_simulation_falloff_get(const Brush &brush,
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
const float distance = len_v3v3(location, co);
|
||||
const float distance = math::distance(location, co);
|
||||
const float limit = radius + (radius * brush.cloth_sim_limit);
|
||||
const float falloff = radius + (radius * brush.cloth_sim_limit * brush.cloth_sim_falloff);
|
||||
|
||||
@@ -188,12 +185,13 @@ static void cloth_brush_add_length_constraint(const SculptSession &ss,
|
||||
PBVHVertRef vertex2 = BKE_pbvh_index_to_vertex(*ss.pbvh, v2);
|
||||
|
||||
if (use_persistent) {
|
||||
length_constraint.length = len_v3v3(SCULPT_vertex_persistent_co_get(ss, vertex1),
|
||||
SCULPT_vertex_persistent_co_get(ss, vertex2));
|
||||
length_constraint.length = math::distance(
|
||||
float3(SCULPT_vertex_persistent_co_get(ss, vertex1)),
|
||||
float3(SCULPT_vertex_persistent_co_get(ss, vertex2)));
|
||||
}
|
||||
else {
|
||||
length_constraint.length = len_v3v3(SCULPT_vertex_co_get(ss, vertex1),
|
||||
SCULPT_vertex_co_get(ss, vertex2));
|
||||
length_constraint.length = math::distance(float3(SCULPT_vertex_co_get(ss, vertex1)),
|
||||
float3(SCULPT_vertex_co_get(ss, vertex2)));
|
||||
}
|
||||
length_constraint.strength = 1.0f;
|
||||
|
||||
@@ -275,8 +273,8 @@ static void cloth_brush_add_deformation_constraint(SimulationData &cloth_sim,
|
||||
static void do_cloth_brush_build_constraints_task(Object &ob,
|
||||
const Brush *brush,
|
||||
SimulationData &cloth_sim,
|
||||
float *cloth_sim_initial_location,
|
||||
float cloth_sim_radius,
|
||||
const float3 &cloth_sim_initial_location,
|
||||
const float cloth_sim_radius,
|
||||
bke::pbvh::Node *node)
|
||||
{
|
||||
SculptSession &ss = *ob.sculpt;
|
||||
@@ -315,7 +313,7 @@ static void do_cloth_brush_build_constraints_task(Object &ob,
|
||||
FLT_MAX;
|
||||
|
||||
BKE_pbvh_vertex_iter_begin (*ss.pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
const float len_squared = len_squared_v3v3(vd.co, cloth_sim_initial_location);
|
||||
const float len_squared = math::distance_squared(float3(vd.co), cloth_sim_initial_location);
|
||||
if (len_squared < cloth_sim_radius_squared) {
|
||||
|
||||
SculptVertexNeighborIter ni;
|
||||
@@ -363,7 +361,8 @@ static void do_cloth_brush_build_constraints_task(Object &ob,
|
||||
else if (len_squared < radius_squared) {
|
||||
/* With radial falloff deformation constraints are created with different strengths and
|
||||
* only inside the radius of the brush. */
|
||||
const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss.cache->radius);
|
||||
const float fade = BKE_brush_curve_strength(
|
||||
brush, std::sqrt(len_squared), ss.cache->radius);
|
||||
cloth_brush_add_deformation_constraint(
|
||||
cloth_sim, node_index, vd.index, fade * CLOTH_DEFORMATION_GRAB_STRENGTH);
|
||||
}
|
||||
@@ -398,19 +397,19 @@ static void do_cloth_brush_build_constraints_task(Object &ob,
|
||||
}
|
||||
|
||||
static void cloth_brush_apply_force_to_vertex(SimulationData &cloth_sim,
|
||||
const float force[3],
|
||||
const float3 &force,
|
||||
const int vertex_index)
|
||||
{
|
||||
madd_v3_v3fl(cloth_sim.acceleration[vertex_index], force, 1.0f / cloth_sim.mass);
|
||||
cloth_sim.acceleration[vertex_index] += force / cloth_sim.mass;
|
||||
}
|
||||
|
||||
static void do_cloth_brush_apply_forces_task(Object &ob,
|
||||
const Sculpt &sd,
|
||||
const Brush &brush,
|
||||
const float *offset,
|
||||
const float *grab_delta,
|
||||
float (*imat)[4],
|
||||
float *area_co,
|
||||
const float3 &offset,
|
||||
const float3 &grab_delta,
|
||||
const float4x4 &imat,
|
||||
const float3 &area_co,
|
||||
bke::pbvh::Node *node)
|
||||
{
|
||||
SculptSession &ss = *ob.sculpt;
|
||||
@@ -427,25 +426,25 @@ static void do_cloth_brush_apply_forces_task(Object &ob,
|
||||
const int thread_id = BLI_task_parallel_thread_id(nullptr);
|
||||
|
||||
/* For Pinch Perpendicular Deform Type. */
|
||||
float x_object_space[3];
|
||||
float z_object_space[3];
|
||||
float3 x_object_space;
|
||||
float3 z_object_space;
|
||||
if (brush.cloth_deform_type == BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR) {
|
||||
normalize_v3_v3(x_object_space, imat[0]);
|
||||
normalize_v3_v3(z_object_space, imat[2]);
|
||||
x_object_space = math::normalize(imat.x_axis());
|
||||
z_object_space = math::normalize(imat.z_axis());
|
||||
}
|
||||
|
||||
/* For Plane Force Falloff. */
|
||||
float deform_plane[4];
|
||||
float plane_normal[3];
|
||||
float4 deform_plane;
|
||||
float3 plane_normal;
|
||||
if (use_falloff_plane) {
|
||||
normalize_v3_v3(plane_normal, grab_delta);
|
||||
plane_normal = math::normalize(grab_delta);
|
||||
plane_from_point_normal_v3(deform_plane, area_co, plane_normal);
|
||||
}
|
||||
|
||||
/* Gravity */
|
||||
float gravity[3] = {0.0f};
|
||||
float3 gravity(0);
|
||||
if (ss.cache->supports_gravity) {
|
||||
madd_v3_v3fl(gravity, ss.cache->gravity_direction, -sd.gravity_factor);
|
||||
gravity += ss.cache->gravity_direction * -sd.gravity_factor;
|
||||
}
|
||||
|
||||
auto_mask::NodeData automask_data = auto_mask::node_begin(
|
||||
@@ -454,23 +453,21 @@ static void do_cloth_brush_apply_forces_task(Object &ob,
|
||||
BKE_pbvh_vertex_iter_begin (*ss.pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
auto_mask::node_update(automask_data, vd);
|
||||
|
||||
float force[3];
|
||||
float sim_location[3];
|
||||
cloth_brush_simulation_location_get(ss, &brush, sim_location);
|
||||
float3 force;
|
||||
const float3 sim_location = cloth_brush_simulation_location_get(ss, &brush);
|
||||
const float sim_factor = cloth_brush_simulation_falloff_get(
|
||||
brush, ss.cache->radius, sim_location, cloth_sim.init_pos[vd.index]);
|
||||
|
||||
float current_vertex_location[3];
|
||||
float3 current_vertex_location;
|
||||
if (brush.cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
|
||||
copy_v3_v3(current_vertex_location, ss.cache->cloth_sim->init_pos[vd.index]);
|
||||
current_vertex_location = ss.cache->cloth_sim->init_pos[vd.index];
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(current_vertex_location, vd.co);
|
||||
current_vertex_location = vd.co;
|
||||
}
|
||||
|
||||
/* Apply gravity in the entire simulation area. */
|
||||
float vertex_gravity[3];
|
||||
mul_v3_v3fl(vertex_gravity, gravity, sim_factor);
|
||||
float3 vertex_gravity = gravity * sim_factor;
|
||||
cloth_brush_apply_force_to_vertex(*ss.cache->cloth_sim, vertex_gravity, vd.index);
|
||||
|
||||
/* When using the plane falloff mode the falloff is not constrained by the brush radius. */
|
||||
@@ -478,7 +475,7 @@ static void do_cloth_brush_apply_forces_task(Object &ob,
|
||||
continue;
|
||||
}
|
||||
|
||||
float dist = sqrtf(test.dist);
|
||||
float dist = std::sqrt(test.dist);
|
||||
|
||||
if (use_falloff_plane) {
|
||||
dist = dist_to_plane_v3(current_vertex_location, deform_plane);
|
||||
@@ -496,67 +493,57 @@ static void do_cloth_brush_apply_forces_task(Object &ob,
|
||||
thread_id,
|
||||
&automask_data);
|
||||
|
||||
float brush_disp[3];
|
||||
float3 brush_disp;
|
||||
|
||||
switch (brush.cloth_deform_type) {
|
||||
case BRUSH_CLOTH_DEFORM_DRAG:
|
||||
sub_v3_v3v3(brush_disp, ss.cache->location, ss.cache->last_location);
|
||||
normalize_v3(brush_disp);
|
||||
mul_v3_v3fl(force, brush_disp, fade);
|
||||
brush_disp = math::normalize(ss.cache->location - ss.cache->last_location);
|
||||
force = brush_disp * fade;
|
||||
break;
|
||||
case BRUSH_CLOTH_DEFORM_PUSH:
|
||||
/* Invert the fade to push inwards. */
|
||||
mul_v3_v3fl(force, offset, -fade);
|
||||
force = offset * -fade;
|
||||
break;
|
||||
case BRUSH_CLOTH_DEFORM_GRAB:
|
||||
madd_v3_v3v3fl(cloth_sim.deformation_pos[vd.index],
|
||||
cloth_sim.init_pos[vd.index],
|
||||
ss.cache->grab_delta_symmetry,
|
||||
fade);
|
||||
cloth_sim.deformation_pos[vd.index] = cloth_sim.init_pos[vd.index] +
|
||||
ss.cache->grab_delta_symmetry * fade;
|
||||
if (use_falloff_plane) {
|
||||
cloth_sim.deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
|
||||
cloth_sim.deformation_strength[vd.index] = std::clamp(fade, 0.0f, 1.0f);
|
||||
}
|
||||
else {
|
||||
cloth_sim.deformation_strength[vd.index] = 1.0f;
|
||||
}
|
||||
zero_v3(force);
|
||||
force = float3(0);
|
||||
break;
|
||||
case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
|
||||
copy_v3_v3(cloth_sim.deformation_pos[vd.index], cloth_sim.pos[vd.index]);
|
||||
madd_v3_v3fl(cloth_sim.deformation_pos[vd.index], ss.cache->grab_delta_symmetry, fade);
|
||||
cloth_sim.deformation_pos[vd.index] = cloth_sim.pos[vd.index];
|
||||
cloth_sim.deformation_pos[vd.index] += ss.cache->grab_delta_symmetry * fade;
|
||||
cloth_sim.deformation_strength[vd.index] = fade;
|
||||
zero_v3(force);
|
||||
force = float3(0);
|
||||
break;
|
||||
case BRUSH_CLOTH_DEFORM_PINCH_POINT:
|
||||
if (use_falloff_plane) {
|
||||
float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
|
||||
copy_v3_v3(brush_disp, plane_normal);
|
||||
mul_v3_fl(brush_disp, -distance);
|
||||
brush_disp = math::normalize(plane_normal * -distance);
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(brush_disp, ss.cache->location, vd.co);
|
||||
brush_disp = math::normalize(ss.cache->location - float3(vd.co));
|
||||
}
|
||||
normalize_v3(brush_disp);
|
||||
mul_v3_v3fl(force, brush_disp, fade);
|
||||
force = brush_disp * fade;
|
||||
break;
|
||||
case BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR: {
|
||||
float disp_center[3];
|
||||
float x_disp[3];
|
||||
float z_disp[3];
|
||||
sub_v3_v3v3(disp_center, ss.cache->location, vd.co);
|
||||
normalize_v3(disp_center);
|
||||
mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
|
||||
mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
|
||||
add_v3_v3v3(disp_center, x_disp, z_disp);
|
||||
mul_v3_v3fl(force, disp_center, fade);
|
||||
const float3 disp_center = math::normalize(ss.cache->location - float3(vd.co));
|
||||
const float3 x_disp = x_object_space - math::dot(disp_center, x_object_space);
|
||||
const float3 z_disp = z_object_space - math::dot(disp_center, z_object_space);
|
||||
force = (x_disp + z_disp) * fade;
|
||||
break;
|
||||
}
|
||||
case BRUSH_CLOTH_DEFORM_INFLATE:
|
||||
mul_v3_v3fl(force, vd.no ? vd.no : vd.fno, fade);
|
||||
force = float3(vd.no) * fade;
|
||||
break;
|
||||
case BRUSH_CLOTH_DEFORM_EXPAND:
|
||||
cloth_sim.length_constraint_tweak[vd.index] += fade * 0.1f;
|
||||
zero_v3(force);
|
||||
force = float3(0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -675,12 +662,12 @@ static void cloth_brush_solve_collision(Object &object, SimulationData &cloth_si
|
||||
continue;
|
||||
}
|
||||
|
||||
float collision_disp[3];
|
||||
float movement_disp[3];
|
||||
float3 collision_disp;
|
||||
float3 movement_disp;
|
||||
mul_v3_v3fl(collision_disp, hit.no, 0.005f);
|
||||
sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
|
||||
float friction_plane[4];
|
||||
float pos_on_friction_plane[3];
|
||||
float4 friction_plane;
|
||||
float3 pos_on_friction_plane;
|
||||
plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
|
||||
closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
|
||||
sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
|
||||
@@ -716,8 +703,7 @@ static void do_cloth_brush_solve_simulation_task(Object &ob,
|
||||
BKE_pbvh_vertex_iter_begin (*ss.pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
auto_mask::node_update(automask_data, vd);
|
||||
|
||||
float sim_location[3];
|
||||
cloth_brush_simulation_location_get(ss, brush, sim_location);
|
||||
const float3 sim_location = cloth_brush_simulation_location_get(ss, brush);
|
||||
const float sim_factor = ss.cache ?
|
||||
cloth_brush_simulation_falloff_get(*brush,
|
||||
ss.cache->radius,
|
||||
@@ -729,30 +715,28 @@ static void do_cloth_brush_solve_simulation_task(Object &ob,
|
||||
}
|
||||
|
||||
int i = vd.index;
|
||||
float temp[3];
|
||||
copy_v3_v3(temp, cloth_sim.pos[i]);
|
||||
float3 pos_diff = cloth_sim.pos[i] - cloth_sim.prev_pos[i];
|
||||
|
||||
mul_v3_fl(cloth_sim.acceleration[i], time_step);
|
||||
cloth_sim.prev_pos[i] = cloth_sim.pos[i];
|
||||
|
||||
float pos_diff[3];
|
||||
sub_v3_v3v3(pos_diff, cloth_sim.pos[i], cloth_sim.prev_pos[i]);
|
||||
mul_v3_fl(pos_diff, (1.0f - cloth_sim.damping) * sim_factor);
|
||||
cloth_sim.acceleration[i] *= time_step;
|
||||
|
||||
pos_diff *= (1.0f - cloth_sim.damping) * sim_factor;
|
||||
|
||||
const float mask_v = (1.0f - (vd.mask)) *
|
||||
auto_mask::factor_get(automasking, ss, vd.vertex, &automask_data);
|
||||
|
||||
madd_v3_v3fl(cloth_sim.pos[i], pos_diff, mask_v);
|
||||
madd_v3_v3fl(cloth_sim.pos[i], cloth_sim.acceleration[i], mask_v);
|
||||
cloth_sim.pos[i] += pos_diff * mask_v;
|
||||
cloth_sim.pos[i] += cloth_sim.acceleration[i] * mask_v;
|
||||
|
||||
if (cloth_sim.collider_list != nullptr) {
|
||||
cloth_brush_solve_collision(ob, cloth_sim, i);
|
||||
}
|
||||
|
||||
copy_v3_v3(cloth_sim.last_iteration_pos[i], cloth_sim.pos[i]);
|
||||
cloth_sim.last_iteration_pos[i] = cloth_sim.pos[i];
|
||||
|
||||
copy_v3_v3(cloth_sim.prev_pos[i], temp);
|
||||
copy_v3_v3(cloth_sim.last_iteration_pos[i], cloth_sim.pos[i]);
|
||||
copy_v3_fl(cloth_sim.acceleration[i], 0.0f);
|
||||
cloth_sim.last_iteration_pos[i] = cloth_sim.pos[i];
|
||||
cloth_sim.acceleration[i] = float3(0);
|
||||
|
||||
copy_v3_v3(vd.co, cloth_sim.pos[vd.index]);
|
||||
}
|
||||
@@ -802,27 +786,24 @@ static void cloth_brush_satisfy_constraints(SculptSession &ss,
|
||||
const int v1 = constraint.elem_index_a;
|
||||
const int v2 = constraint.elem_index_b;
|
||||
|
||||
float v1_to_v2[3];
|
||||
sub_v3_v3v3(v1_to_v2, constraint.elem_position_b, constraint.elem_position_a);
|
||||
const float current_distance = len_v3(v1_to_v2);
|
||||
float correction_vector[3];
|
||||
float correction_vector_half[3];
|
||||
float3 v1_to_v2 = float3(constraint.elem_position_b) - float3(constraint.elem_position_a);
|
||||
const float current_distance = math::length(v1_to_v2);
|
||||
float3 correction_vector;
|
||||
float3 correction_vector_half;
|
||||
|
||||
const float constraint_distance = constraint.length +
|
||||
(cloth_sim.length_constraint_tweak[v1] * 0.5f) +
|
||||
(cloth_sim.length_constraint_tweak[v2] * 0.5f);
|
||||
|
||||
if (current_distance > 0.0f) {
|
||||
mul_v3_v3fl(correction_vector,
|
||||
v1_to_v2,
|
||||
CLOTH_SOLVER_DISPLACEMENT_FACTOR *
|
||||
(1.0f - (constraint_distance / current_distance)));
|
||||
correction_vector = v1_to_v2 * CLOTH_SOLVER_DISPLACEMENT_FACTOR *
|
||||
(1.0f - (constraint_distance / current_distance));
|
||||
}
|
||||
else {
|
||||
mul_v3_v3fl(correction_vector, v1_to_v2, CLOTH_SOLVER_DISPLACEMENT_FACTOR);
|
||||
correction_vector = v1_to_v2 * CLOTH_SOLVER_DISPLACEMENT_FACTOR;
|
||||
}
|
||||
|
||||
mul_v3_v3fl(correction_vector_half, correction_vector, 0.5f);
|
||||
correction_vector_half = correction_vector * 0.5f;
|
||||
|
||||
PBVHVertRef vertex1 = BKE_pbvh_index_to_vertex(*ss.pbvh, v1);
|
||||
PBVHVertRef vertex2 = BKE_pbvh_index_to_vertex(*ss.pbvh, v2);
|
||||
@@ -837,8 +818,7 @@ static void cloth_brush_satisfy_constraints(SculptSession &ss,
|
||||
const float mask_v2 = (1.0f - get_vert_mask(ss, cloth_sim, v2)) *
|
||||
auto_mask::factor_get(automasking, ss, vertex2, &automask_data);
|
||||
|
||||
float sim_location[3];
|
||||
cloth_brush_simulation_location_get(ss, brush, sim_location);
|
||||
const float3 sim_location = cloth_brush_simulation_location_get(ss, brush);
|
||||
|
||||
const float sim_factor_v1 = ss.cache ?
|
||||
cloth_brush_simulation_falloff_get(*brush,
|
||||
@@ -862,23 +842,17 @@ static void cloth_brush_satisfy_constraints(SculptSession &ss,
|
||||
|
||||
if (constraint.type == SCULPT_CLOTH_CONSTRAINT_SOFTBODY) {
|
||||
const float softbody_plasticity = brush ? brush->cloth_constraint_softbody_strength : 0.0f;
|
||||
madd_v3_v3fl(cloth_sim.pos[v1],
|
||||
correction_vector_half,
|
||||
1.0f * mask_v1 * sim_factor_v1 * constraint.strength * softbody_plasticity);
|
||||
madd_v3_v3fl(cloth_sim.softbody_pos[v1],
|
||||
correction_vector_half,
|
||||
-1.0f * mask_v1 * sim_factor_v1 * constraint.strength *
|
||||
(1.0f - softbody_plasticity));
|
||||
cloth_sim.pos[v1] += correction_vector_half * (1.0f * mask_v1 * sim_factor_v1 *
|
||||
constraint.strength * softbody_plasticity);
|
||||
cloth_sim.softbody_pos[v1] += correction_vector_half * -1.0f * mask_v1 * sim_factor_v1 *
|
||||
constraint.strength * (1.0f - softbody_plasticity);
|
||||
}
|
||||
else {
|
||||
madd_v3_v3fl(cloth_sim.pos[v1],
|
||||
correction_vector_half,
|
||||
1.0f * mask_v1 * sim_factor_v1 * constraint.strength * deformation_strength);
|
||||
cloth_sim.pos[v1] += correction_vector_half * 1.0f * mask_v1 * sim_factor_v1 *
|
||||
constraint.strength * deformation_strength;
|
||||
if (v1 != v2) {
|
||||
madd_v3_v3fl(cloth_sim.pos[v2],
|
||||
correction_vector_half,
|
||||
-1.0f * mask_v2 * sim_factor_v2 * constraint.strength *
|
||||
deformation_strength);
|
||||
cloth_sim.pos[v2] += correction_vector_half * -1.0f * mask_v2 * sim_factor_v2 *
|
||||
constraint.strength * deformation_strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -911,44 +885,32 @@ static void cloth_brush_apply_brush_foces(const Sculpt &sd,
|
||||
SculptSession &ss = *ob.sculpt;
|
||||
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
|
||||
|
||||
float3 grab_delta;
|
||||
float4x4 mat;
|
||||
float3 area_no;
|
||||
float3 area_co;
|
||||
float3 offset;
|
||||
|
||||
BKE_curvemapping_init(brush.curve);
|
||||
|
||||
/* Initialize the grab delta. */
|
||||
copy_v3_v3(grab_delta, ss.cache->grab_delta_symmetry);
|
||||
normalize_v3(grab_delta);
|
||||
|
||||
if (is_zero_v3(ss.cache->grab_delta_symmetry)) {
|
||||
if (math::is_zero(ss.cache->grab_delta_symmetry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate push offset. */
|
||||
float3 grab_delta = math::normalize(ss.cache->grab_delta_symmetry);
|
||||
|
||||
/* Calculate push offset. */
|
||||
if (brush.cloth_deform_type == BRUSH_CLOTH_DEFORM_PUSH) {
|
||||
mul_v3_v3fl(offset, ss.cache->sculpt_normal_symm, ss.cache->radius);
|
||||
mul_v3_v3(offset, ss.cache->scale);
|
||||
mul_v3_fl(offset, 2.0f);
|
||||
offset = ss.cache->sculpt_normal_symm * ss.cache->radius * ss.cache->scale * 2.0f;
|
||||
}
|
||||
|
||||
float4x4 mat = float4x4::identity();
|
||||
if (brush.cloth_deform_type == BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR ||
|
||||
brush.cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE)
|
||||
{
|
||||
calc_brush_plane(brush, ob, nodes, area_no, area_co);
|
||||
|
||||
/* Initialize stroke local space matrix. */
|
||||
cross_v3_v3v3(mat[0], area_no, ss.cache->grab_delta_symmetry);
|
||||
mat[0][3] = 0.0f;
|
||||
cross_v3_v3v3(mat[1], area_no, mat[0]);
|
||||
mat[1][3] = 0.0f;
|
||||
copy_v3_v3(mat[2], area_no);
|
||||
mat[2][3] = 0.0f;
|
||||
copy_v3_v3(mat[3], ss.cache->location);
|
||||
mat[3][3] = 1.0f;
|
||||
mat.x_axis() = math::cross(area_no, ss.cache->grab_delta_symmetry);
|
||||
mat.y_axis() = math::cross(area_no, mat.x_axis());
|
||||
mat.z_axis() = area_no;
|
||||
mat.location() = ss.cache->location;
|
||||
normalize_m4(mat.ptr());
|
||||
|
||||
/* Update matrix for the cursor preview. */
|
||||
@@ -960,16 +922,12 @@ static void cloth_brush_apply_brush_foces(const Sculpt &sd,
|
||||
if (ELEM(brush.cloth_deform_type, BRUSH_CLOTH_DEFORM_SNAKE_HOOK, BRUSH_CLOTH_DEFORM_GRAB)) {
|
||||
/* Set the deformation strength to 0. Brushes will initialize the strength in the required
|
||||
* area. */
|
||||
const int totverts = SCULPT_vertex_count_get(ss);
|
||||
for (int i = 0; i < totverts; i++) {
|
||||
ss.cache->cloth_sim->deformation_strength[i] = 0.0f;
|
||||
}
|
||||
ss.cache->cloth_sim->deformation_strength.fill(0.0f);
|
||||
}
|
||||
|
||||
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
do_cloth_brush_apply_forces_task(
|
||||
ob, sd, brush, offset, grab_delta, mat.ptr(), area_co, nodes[i]);
|
||||
do_cloth_brush_apply_forces_task(ob, sd, brush, offset, grab_delta, mat, area_co, nodes[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1047,12 +1005,10 @@ std::unique_ptr<SimulationData> brush_simulation_create(Object &ob,
|
||||
}
|
||||
|
||||
void ensure_nodes_constraints(const Sculpt &sd,
|
||||
Object &ob,
|
||||
Span<bke::pbvh::Node *> nodes,
|
||||
const Object &ob,
|
||||
const Span<bke::pbvh::Node *> nodes,
|
||||
SimulationData &cloth_sim,
|
||||
/* Cannot be `const`, because it is assigned to a `non-const`
|
||||
* variable. NOLINTNEXTLINE: readability-non-const-parameter. */
|
||||
float initial_location[3],
|
||||
const float3 &initial_location,
|
||||
const float radius)
|
||||
{
|
||||
const Brush *brush = BKE_paint_brush_for_read(&sd.paint);
|
||||
@@ -1066,7 +1022,7 @@ void ensure_nodes_constraints(const Sculpt &sd,
|
||||
|
||||
for (const int i : nodes.index_range()) {
|
||||
do_cloth_brush_build_constraints_task(
|
||||
ob, brush, cloth_sim, initial_location, radius, nodes[i]);
|
||||
const_cast<Object &>(ob), brush, cloth_sim, initial_location, radius, nodes[i]);
|
||||
}
|
||||
|
||||
cloth_sim.created_length_constraints.clear_and_shrink();
|
||||
@@ -1165,8 +1121,7 @@ static void sculpt_cloth_ensure_constraints_in_simulation_area(const Sculpt &sd,
|
||||
const Brush *brush = BKE_paint_brush_for_read(&sd.paint);
|
||||
const float radius = ss.cache->initial_radius;
|
||||
const float limit = radius + (radius * brush->cloth_sim_limit);
|
||||
float sim_location[3];
|
||||
cloth_brush_simulation_location_get(ss, brush, sim_location);
|
||||
const float3 sim_location = cloth_brush_simulation_location_get(ss, brush);
|
||||
ensure_nodes_constraints(sd, ob, nodes, *ss.cache->cloth_sim, sim_location, limit);
|
||||
}
|
||||
|
||||
@@ -1397,7 +1352,7 @@ static void cloth_filter_apply_forces_task(Object &ob,
|
||||
else {
|
||||
sculpt_gravity[2] = -1.0f;
|
||||
}
|
||||
mul_v3_fl(sculpt_gravity, sd.gravity_factor * filter_strength);
|
||||
sculpt_gravity *= sd.gravity_factor * filter_strength;
|
||||
auto_mask::NodeData automask_data = auto_mask::node_begin(
|
||||
ob, auto_mask::active_cache_get(ss), *node);
|
||||
|
||||
@@ -1443,15 +1398,14 @@ static void cloth_filter_apply_forces_task(Object &ob,
|
||||
force = math::normalize(ss.filter_cache->cloth_sim_pinch_point - float3(vd.co));
|
||||
force *= fade * filter_strength;
|
||||
break;
|
||||
case ClothFilterType::Scale:
|
||||
float3x3 transform = float3x3::identity();
|
||||
scale_m3_fl(transform.ptr(), 1.0f + (fade * filter_strength));
|
||||
case ClothFilterType::Scale: {
|
||||
float3x3 transform = math::from_scale<float3x3>(float3(1.0f + fade * filter_strength));
|
||||
temp = cloth_sim.init_pos[vd.index];
|
||||
temp = transform * temp;
|
||||
disp = temp - cloth_sim.init_pos[vd.index];
|
||||
force = float3(0);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_deformation_filter) {
|
||||
@@ -1538,7 +1492,7 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
const ClothFilterType filter_type = ClothFilterType(RNA_enum_get(op->ptr, "type"));
|
||||
|
||||
/* Update the active vertex */
|
||||
float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||
float2 mval_fl{float(event->mval[0]), float(event->mval[1])};
|
||||
SculptCursorGeometryInfo sgi;
|
||||
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
||||
|
||||
@@ -1575,11 +1529,11 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
use_collisions,
|
||||
cloth_filter_is_deformation_filter(filter_type));
|
||||
|
||||
copy_v3_v3(ss.filter_cache->cloth_sim_pinch_point, SCULPT_active_vertex_co_get(ss));
|
||||
ss.filter_cache->cloth_sim_pinch_point = SCULPT_active_vertex_co_get(ss);
|
||||
|
||||
brush_simulation_init(ss, *ss.filter_cache->cloth_sim);
|
||||
|
||||
float origin[3] = {0.0f, 0.0f, 0.0f};
|
||||
float3 origin(0);
|
||||
ensure_nodes_constraints(
|
||||
sd, ob, ss.filter_cache->nodes, *ss.filter_cache->cloth_sim, origin, FLT_MAX);
|
||||
|
||||
|
||||
@@ -1609,10 +1609,10 @@ void do_simulation_step(const Sculpt &sd,
|
||||
Span<blender::bke::pbvh::Node *> nodes);
|
||||
|
||||
void ensure_nodes_constraints(const Sculpt &sd,
|
||||
Object &ob,
|
||||
Span<blender::bke::pbvh::Node *> nodes,
|
||||
const Object &ob,
|
||||
Span<bke::pbvh::Node *> nodes,
|
||||
SimulationData &cloth_sim,
|
||||
float initial_location[3],
|
||||
const float3 &initial_location,
|
||||
float radius);
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user