6c3b78075b
maybe put in maya config? idk what funiman's preference is
1046 lines
33 KiB
Python
1046 lines
33 KiB
Python
from .functions import *
|
|
from bpy.types import AddonPreferences
|
|
|
|
|
|
#
|
|
# UPDATE FUNCTIONS
|
|
#
|
|
|
|
|
|
def update_bones_prop(self, attr_name, attr_value):
|
|
prefs = bpy.context.preferences.addons["goo_physics"].preferences
|
|
|
|
if self.gp_update:
|
|
coll = bpy.data.collections.get("Goo Physics")
|
|
if coll is not None:
|
|
|
|
for pb in bpy.context.selected_pose_bones:
|
|
# Dont propagate settings between softbody and cloth if bone has a different setting
|
|
if pb.gp_has_sb_physics == False and bpy.context.active_pose_bone.gp_has_sb_physics:
|
|
continue
|
|
|
|
if pb.gp_has_jg_physics == False and bpy.context.active_pose_bone.gp_has_jg_physics:
|
|
continue
|
|
|
|
if pb.gp_has_cl_physics == False and bpy.context.active_pose_bone.gp_has_cl_physics:
|
|
continue
|
|
|
|
if prefs.apply_to_all_chains == False and pb.gp_chain_id != bpy.context.active_pose_bone.gp_chain_id:
|
|
continue
|
|
|
|
if prefs.apply_to_all_bones == False and pb != bpy.context.active_pose_bone:
|
|
continue
|
|
|
|
pb.gp_update = False
|
|
|
|
setattr(pb, attr_name, attr_value)
|
|
|
|
ob = coll.objects.get(pb.gp_sim_object)
|
|
|
|
if ob is not None and (pb.gp_has_sb_physics or pb.gp_has_cl_physics or pb.gp_has_jg_physics):
|
|
for mod in ob.modifiers:
|
|
if mod.type == "SOFT_BODY":
|
|
if pb.gp_has_sb_physics:
|
|
mod.settings.goal_min = pb.gp_sim_strength
|
|
|
|
mod.settings.goal_spring = pb.gp_sim_stiffness
|
|
mod.settings.goal_friction = pb.gp_sim_damping
|
|
mod.settings.speed = pb.gp_sim_speed
|
|
mod.settings.friction = pb.gp_sim_friction
|
|
mod.settings.mass = pb.gp_sim_mass
|
|
mod.settings.use_edge_collision = pb.gp_sim_use_collision
|
|
mod.settings.effector_weights.gravity = pb.gp_sim_gravity
|
|
|
|
if pb.gp_sim_limit_collision:
|
|
if pb.gp_has_sb_physics:
|
|
mod.settings.collision_collection = bpy.data.collections.get("Goo Physics Soft Body Colliders")
|
|
else:
|
|
mod.settings.collision_collection = bpy.data.collections.get("Goo Physics Jiggle Colliders")
|
|
else:
|
|
mod.settings.collision_collection = None
|
|
|
|
track_cons = pb.constraints.get("GP_Track")
|
|
if track_cons:
|
|
track_cons.influence = pb.gp_sim_influence
|
|
|
|
follow_cons = pb.constraints.get("GP_Follow")
|
|
if follow_cons:
|
|
follow_cons.influence = pb.gp_sim_influence
|
|
|
|
pb.gp_update = True
|
|
|
|
self.gp_update = False
|
|
|
|
track_cons = self.constraints.get("GP_Track")
|
|
if track_cons:
|
|
track_cons.influence = self.gp_sim_influence
|
|
|
|
follow_cons = self.constraints.get("GP_Follow")
|
|
if follow_cons:
|
|
follow_cons.influence = self.gp_sim_influence
|
|
|
|
self.gp_update = True
|
|
|
|
return
|
|
|
|
|
|
def update_bones_speed(self, context):
|
|
update_bones_prop(self, "gp_sim_speed", context.active_pose_bone.gp_sim_speed)
|
|
return
|
|
|
|
|
|
def update_bones_friction(self, context):
|
|
update_bones_prop(self, "gp_sim_friction", context.active_pose_bone.gp_sim_friction)
|
|
return
|
|
|
|
|
|
def update_bones_mass(self, context):
|
|
update_bones_prop(self, "gp_sim_mass", context.active_pose_bone.gp_sim_mass)
|
|
return
|
|
|
|
|
|
def update_bones_stiffness(self, context):
|
|
update_bones_prop(
|
|
self, "gp_sim_stiffness", context.active_pose_bone.gp_sim_stiffness
|
|
)
|
|
return
|
|
|
|
|
|
def update_bones_damping(self, context):
|
|
update_bones_prop(self, "gp_sim_damping", context.active_pose_bone.gp_sim_damping)
|
|
return
|
|
|
|
|
|
def update_bones_strength(self, context):
|
|
update_bones_prop(self, "gp_sim_strength", context.active_pose_bone.gp_sim_strength)
|
|
return
|
|
|
|
|
|
def update_bones_influence(self, context):
|
|
update_bones_prop(
|
|
self, "gp_sim_influence", context.active_pose_bone.gp_sim_influence
|
|
)
|
|
return
|
|
|
|
|
|
def update_bones_air_dampening(self, context):
|
|
update_bones_prop(
|
|
self, "gp_sim_air_dampening", context.active_pose_bone.gp_sim_air_dampening
|
|
)
|
|
return
|
|
|
|
|
|
def update_bones_bend_damping(self, context):
|
|
update_bones_prop(
|
|
self, "gp_sim_bend_damping", context.active_pose_bone.gp_sim_bend_damping
|
|
)
|
|
return
|
|
|
|
|
|
def update_bones_use_collision(self, context):
|
|
update_bones_prop(
|
|
self, "gp_sim_use_collision", context.active_pose_bone.gp_sim_use_collision
|
|
)
|
|
return
|
|
|
|
|
|
def update_bones_limit_collision(self, context):
|
|
update_bones_prop(
|
|
self, "gp_sim_limit_collision", context.active_pose_bone.gp_sim_limit_collision
|
|
)
|
|
return
|
|
|
|
|
|
def update_bones_gravity(self, context):
|
|
update_bones_prop(
|
|
self, "gp_sim_gravity", context.active_pose_bone.gp_sim_gravity
|
|
)
|
|
return
|
|
|
|
|
|
#
|
|
|
|
|
|
def update_chain_prop(self, attr_name, attr_value):
|
|
prefs = bpy.context.preferences.addons["goo_physics"].preferences
|
|
|
|
if self.gp_update:
|
|
coll = bpy.data.collections.get("Goo Physics")
|
|
if coll is not None:
|
|
chains, bones = [], []
|
|
for pb in bpy.context.selected_pose_bones:
|
|
if pb.gp_has_gn_physics == False and pb.gp_has_cl_physics == False:
|
|
continue
|
|
|
|
if prefs.apply_to_all_chains == False and pb.gp_chain_id != bpy.context.active_pose_bone.gp_chain_id:
|
|
continue
|
|
|
|
if pb.gp_chain_id not in chains:
|
|
chains.append(pb.gp_chain_id)
|
|
bones.append(pb)
|
|
|
|
# Loop all bones looking to update rest of chain with changed props
|
|
skip_rigs = []
|
|
for p, pb in enumerate(bones):
|
|
if pb.id_data in skip_rigs:
|
|
continue
|
|
else:
|
|
skip_rigs.append(pb.id_data)
|
|
|
|
for c_pb in pb.id_data.pose.bones:
|
|
if c_pb.gp_chain_id in chains:
|
|
c_pb.gp_update = False
|
|
|
|
setattr(c_pb, attr_name, attr_value)
|
|
|
|
ob = coll.objects.get(c_pb.gp_sim_object)
|
|
|
|
if ob:
|
|
mod = ob.modifiers.get("GP_Nodes Sim")
|
|
if mod:
|
|
inputs = get_inputs_container(mod.node_group)
|
|
if attr_name == "gp_chain_wind_strength":
|
|
set_geo_nodes_input(mod, "Wind Strength", attr_value)
|
|
if attr_name == "gp_chain_wind_noise_scale":
|
|
set_geo_nodes_input(mod, "Wind Noise Scale", attr_value)
|
|
if attr_name == "gp_chain_wind_noise_strength":
|
|
set_geo_nodes_input(mod, "Wind Noise Strength", attr_value)
|
|
if attr_name == "gp_chain_dampening":
|
|
set_geo_nodes_input(mod, "Velocity Dampening", attr_value)
|
|
if attr_name == "gp_chain_root_falloff":
|
|
set_geo_nodes_input(mod, "Root Pin Size", attr_value)
|
|
if attr_name == "gp_chain_velocity":
|
|
set_geo_nodes_input(mod, "Velocity Scaler", attr_value)
|
|
if attr_name == "gp_chain_gravity":
|
|
set_geo_nodes_input(mod, "Gravity Strength", attr_value)
|
|
if attr_name == "gp_chain_stiffness":
|
|
set_geo_nodes_input(mod, "Goal Strength", attr_value)
|
|
if attr_name == "gp_chain_stiff_end_fac":
|
|
set_geo_nodes_input(mod, "Goal End Strength", attr_value)
|
|
if attr_name == "gp_chain_stiff_vel_fac":
|
|
set_geo_nodes_input(mod, "Goal Velocity Factor", attr_value)
|
|
if attr_name == "gp_chain_stiff_vel_min":
|
|
set_geo_nodes_input(mod, "Goal Velocity Min", attr_value)
|
|
if attr_name == "gp_chain_stiff_vel_max":
|
|
set_geo_nodes_input(mod, "Goal Velocity Max", attr_value)
|
|
if attr_name == "gp_chain_use_collision":
|
|
set_geo_nodes_input(mod, "Use Collision", attr_value)
|
|
if attr_name == "gp_chain_collision_dist":
|
|
set_geo_nodes_input(mod, "Collision Distance", attr_value)
|
|
if attr_name == "gp_chain_collision_friction":
|
|
set_geo_nodes_input(mod, "Collision Friction", attr_value)
|
|
|
|
if attr_name == "gp_chain_limit_collision":
|
|
if c_pb.gp_chain_limit_collision:
|
|
set_geo_nodes_input(mod, "Collision Collection", bpy.data.collections.get("Goo Physics Geo Nodes Colliders"))
|
|
else:
|
|
set_geo_nodes_input(mod, "Collision Collection", bpy.data.collections.get("Goo Physics All Colliders"))
|
|
|
|
ob.location = ob.location
|
|
|
|
for mod in ob.modifiers:
|
|
if mod.type == "CLOTH":
|
|
mod.settings.mass = pb.gp_chain_mass
|
|
mod.settings.time_scale = pb.gp_chain_speed
|
|
mod.settings.air_damping = pb.gp_chain_air_dampening
|
|
mod.collision_settings.use_collision = pb.gp_chain_use_collision
|
|
mod.settings.effector_weights.gravity = pb.gp_chain_gravity
|
|
|
|
if pb.gp_chain_limit_collision:
|
|
mod.collision_settings.collection = bpy.data.collections.get("Goo Physics Cloth Colliders")
|
|
else:
|
|
mod.collision_settings.collection = None
|
|
|
|
c_pb.gp_update = True
|
|
|
|
return
|
|
|
|
|
|
def update_chain_speed(self, context):
|
|
update_chain_prop(self, "gp_chain_speed", context.active_pose_bone.gp_chain_speed)
|
|
return
|
|
|
|
|
|
def update_chain_mass(self, context):
|
|
update_chain_prop(self, "gp_chain_mass", context.active_pose_bone.gp_chain_mass)
|
|
return
|
|
|
|
|
|
def update_chain_air_dampening(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_air_dampening", context.active_pose_bone.gp_chain_air_dampening
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_bend_damping(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_bend_damping", context.active_pose_bone.gp_chain_bend_damping
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_wind_strength(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_wind_strength", context.active_pose_bone.gp_chain_wind_strength
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_wind_noise_scale(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_wind_noise_scale", context.active_pose_bone.gp_chain_wind_noise_scale
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_wind_noise_strength(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_wind_noise_strength", context.active_pose_bone.gp_chain_wind_noise_strength
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_dampening(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_dampening", context.active_pose_bone.gp_chain_dampening
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_root_falloff(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_root_falloff", context.active_pose_bone.gp_chain_root_falloff
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_velocity(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_velocity", context.active_pose_bone.gp_chain_velocity
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_gravity(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_gravity", context.active_pose_bone.gp_chain_gravity
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_stiffness(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_stiffness", context.active_pose_bone.gp_chain_stiffness
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_stiff_end_fac(self, context):
|
|
update_chain_prop(
|
|
self,
|
|
"gp_chain_stiff_end_fac",
|
|
context.active_pose_bone.gp_chain_stiff_end_fac,
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_velocity_fac(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_stiff_vel_fac", context.active_pose_bone.gp_chain_stiff_vel_fac
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_velocity_min(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_stiff_vel_min", context.active_pose_bone.gp_chain_stiff_vel_min
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_velocity_max(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_stiff_vel_max", context.active_pose_bone.gp_chain_stiff_vel_max
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_use_collision(self, context):
|
|
update_chain_prop(
|
|
self, "gp_chain_use_collision", context.active_pose_bone.gp_chain_use_collision
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_collision_dist(self, context):
|
|
update_chain_prop(
|
|
self,
|
|
"gp_chain_collision_dist",
|
|
context.active_pose_bone.gp_chain_collision_dist,
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_friction(self, context):
|
|
update_chain_prop(
|
|
self,
|
|
"gp_chain_collision_friction",
|
|
context.active_pose_bone.gp_chain_collision_friction,
|
|
)
|
|
return
|
|
|
|
|
|
def update_chain_limit_collision(self, context):
|
|
update_chain_prop(
|
|
self,
|
|
"gp_chain_limit_collision",
|
|
context.active_pose_bone.gp_chain_limit_collision,
|
|
)
|
|
return
|
|
|
|
|
|
#
|
|
|
|
|
|
def toggle_physics_status(self, context):
|
|
|
|
coll, collide_colls, control_coll, bake_coll = ensure_collections()
|
|
|
|
for ob in bpy.data.objects:
|
|
if ob.type == "ARMATURE":
|
|
for pb in ob.pose.bones:
|
|
|
|
track_cons = pb.constraints.get("GP_Track")
|
|
if track_cons:
|
|
track_cons.enabled = self.gp_physics_active
|
|
|
|
follow_cons = pb.constraints.get("GP_Follow")
|
|
if follow_cons:
|
|
follow_cons.enabled = self.gp_physics_active
|
|
|
|
for ob in coll.all_objects:
|
|
if ob.type == "MESH":
|
|
for mod in ob.modifiers:
|
|
if mod.type in ["NODES", "CLOTH", "SOFT_BODY"]:
|
|
mod.show_viewport = self.gp_physics_active
|
|
|
|
return
|
|
|
|
|
|
#
|
|
|
|
|
|
#
|
|
# PRESETS FUNCTIONS
|
|
#
|
|
|
|
|
|
def load_presets(preset_fp):
|
|
|
|
presets_data = None
|
|
if os.path.exists(preset_fp):
|
|
presets_data = json.load(open(str(preset_fp)))
|
|
|
|
items = []
|
|
if presets_data is not None:
|
|
for k in presets_data.keys():
|
|
items.append(
|
|
(
|
|
k,
|
|
presets_data[k]["Name"],
|
|
presets_data[k]["Description"],
|
|
)
|
|
)
|
|
|
|
return sorted(items)
|
|
|
|
|
|
def get_cl_presets(self, context):
|
|
preset_fp = Path(os.path.dirname(__file__)) / "presets" / "cloth_presets.json"
|
|
user_preset_fp = Path(os.path.dirname(__file__)) / "user_created_presets" / "cloth_presets.json"
|
|
|
|
return load_presets(preset_fp) + load_presets(user_preset_fp)
|
|
|
|
|
|
def get_sb_presets(self, context):
|
|
preset_fp = Path(os.path.dirname(__file__)) / "presets" / "soft_body_presets.json"
|
|
user_preset_fp = Path(os.path.dirname(__file__)) / "user_created_presets" / "soft_body_presets.json"
|
|
|
|
return load_presets(preset_fp) + load_presets(user_preset_fp)
|
|
|
|
|
|
def get_jg_presets(self, context):
|
|
preset_fp = Path(os.path.dirname(__file__)) / "presets" / "jiggle_spring_presets.json"
|
|
user_preset_fp = Path(os.path.dirname(__file__)) / "user_created_presets" / "jiggle_spring_presets.json"
|
|
|
|
return load_presets(preset_fp) + load_presets(user_preset_fp)
|
|
|
|
|
|
def get_gn_presets(self, context):
|
|
preset_fp = Path(os.path.dirname(__file__)) / "presets" / "geo_nodes_presets.json"
|
|
user_preset_fp = Path(os.path.dirname(__file__)) / "user_created_presets" / "geo_nodes_presets.json"
|
|
|
|
return load_presets(preset_fp) + load_presets(user_preset_fp)
|
|
|
|
|
|
def get_bm_presets(self, context):
|
|
user_preset_fp = Path(os.path.dirname(__file__)) / "user_created_presets" / "bone_map_presets.json"
|
|
|
|
return load_presets(user_preset_fp)
|
|
|
|
|
|
#
|
|
|
|
|
|
class gp_bone_props(PropertyGroup):
|
|
rig_object: StringProperty(description="")
|
|
rig_bone: StringProperty(description="")
|
|
|
|
|
|
class gp_bone_collection(PropertyGroup):
|
|
coll: CollectionProperty(type=gp_bone_props)
|
|
index: IntProperty()
|
|
|
|
|
|
#
|
|
# PREFERENCES AND REGISTERS
|
|
#
|
|
|
|
|
|
class GooPhysicsPreferences(AddonPreferences):
|
|
bl_idname = "goo_physics"
|
|
|
|
gp_divisions: bpy.props.IntProperty(
|
|
default=1,
|
|
min=0,
|
|
max=10,
|
|
name="Bone Resolution",
|
|
description="Number of extra vertices to add to each bone segment for Geo Nodes. Can help to add detail and extra points to calculate collisions.",
|
|
)
|
|
|
|
gp_physics_type: bpy.props.EnumProperty(
|
|
items=(
|
|
("GEO_NODES", "Geo Nodes Chain", "Collision Physics using custom Geometry Nodes Simulation"),
|
|
("SIMP_SOFTBODY", "Soft Body Chain", "Chain Physics using builtin Soft Body Simulation"),
|
|
("CLOTH", "Cloth Chain", "Chain Physics using builtin Cloth Simulation"),
|
|
("JIGGLE", "Jiggle Physics", "Jiggle Physics using builtin Soft Body Simulation"),
|
|
)
|
|
)
|
|
|
|
cl_presets: bpy.props.EnumProperty(
|
|
name="Cloth Chain Presets",
|
|
items=get_cl_presets,
|
|
)
|
|
|
|
sb_presets: bpy.props.EnumProperty(
|
|
name="Soft Body Chain Presets",
|
|
items=get_sb_presets,
|
|
)
|
|
|
|
jg_presets: bpy.props.EnumProperty(
|
|
name="Jiggle Physics Presets",
|
|
items=get_jg_presets,
|
|
)
|
|
|
|
gn_presets: bpy.props.EnumProperty(
|
|
name="Geo Nodes Chain Presets",
|
|
items=get_gn_presets,
|
|
)
|
|
|
|
bm_presets: bpy.props.EnumProperty(
|
|
name="Bone Map Presets",
|
|
items=get_bm_presets,
|
|
)
|
|
|
|
settings_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
|
|
gp_physics_active: bpy.props.BoolProperty(
|
|
default=True,
|
|
update=toggle_physics_status
|
|
)
|
|
chain_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
bone_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
|
|
cl_time_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
cl_physical_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
cl_structure_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
cl_collision_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
|
|
sb_time_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
sb_physical_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
sb_structure_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
sb_collision_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
|
|
jg_physical_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
jg_collision_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
|
|
gn_general_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
gn_stiff_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
gn_stiff_adv_menu: bpy.props.BoolProperty(
|
|
default=False,
|
|
)
|
|
gn_wind_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
gn_collision_menu: bpy.props.BoolProperty(
|
|
default=True,
|
|
)
|
|
|
|
keep_existing_settings: bpy.props.BoolProperty(
|
|
default=False,
|
|
name="Keep Existing Settings",
|
|
description="When readding a physics type to bones it will keep the previously set settings. Otherwise it will load in the active preset"
|
|
)
|
|
|
|
has_bte: bpy.props.BoolProperty(
|
|
default=False,
|
|
)
|
|
|
|
apply_to_all_chains: bpy.props.BoolProperty(
|
|
default=True,
|
|
name="Auto Update All Selected Chains",
|
|
description="Any physics settings change for the active chain will apply to all selected bone chains of the same physics mode",
|
|
)
|
|
|
|
apply_to_all_bones: bpy.props.BoolProperty(
|
|
default=True,
|
|
name="Auto Update All Selected Bones",
|
|
description="Any physics settings change for the active bone will apply to all selected bones of the same physics mode",
|
|
)
|
|
|
|
precaching: bpy.props.BoolProperty(
|
|
default=False,
|
|
)
|
|
|
|
active_timeline_sync_frames: StringProperty(
|
|
default="",
|
|
)
|
|
|
|
timeline_sync_frames: StringProperty(
|
|
default="",
|
|
)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
column = layout.column(align=True)
|
|
row = column.row(align=True)
|
|
row.prop(self, "apply_to_all_chains")
|
|
row = column.row(align=True)
|
|
row.prop(self, "apply_to_all_bones")
|
|
row = column.row(align=True)
|
|
row.prop(self, "keep_existing_settings")
|
|
row = column.row(align=True)
|
|
row.prop(self, "gp_divisions")
|
|
row = column.row(align=True)
|
|
row.prop(self, "gp_physics_type", text="Phyics Type")
|
|
|
|
|
|
#
|
|
#
|
|
#
|
|
|
|
|
|
_classes = [
|
|
GooPhysicsPreferences
|
|
]
|
|
|
|
|
|
_register, _unregister = register_classes_factory(_classes)
|
|
|
|
|
|
def register():
|
|
_register()
|
|
|
|
bpy.app.handlers.animation_playback_pre.append(timeline_sync_handler_playback_pre)
|
|
bpy.app.handlers.animation_playback_post.append(timeline_sync_handler_playback_post)
|
|
|
|
bpy.types.PoseBone.gp_chain_wind_strength = FloatProperty(
|
|
default=1.0,
|
|
min=0.0,
|
|
max=100.0,
|
|
description="Amplitude of the wind in the Z axis direction of the wind controller (the direction the arrow is pointing)",
|
|
update=update_chain_wind_strength,
|
|
options={"LIBRARY_EDITABLE"},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_wind_noise_strength = FloatProperty(
|
|
default=0.1,
|
|
min=0.0,
|
|
max=100.0,
|
|
description="Amplitude of the noise applied over time along the X/Y axis of the wind controller",
|
|
update=update_chain_wind_noise_strength,
|
|
options={"LIBRARY_EDITABLE"},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_wind_noise_scale = FloatProperty(
|
|
default=1.0,
|
|
min=-100.0,
|
|
max=100.0,
|
|
description="Frequency or speed of the wind X/Y noise",
|
|
update=update_chain_wind_noise_scale,
|
|
options={"LIBRARY_EDITABLE"},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_dampening = FloatProperty(
|
|
default=0.1,
|
|
min=0.0,
|
|
max=1.0,
|
|
description="The amount of slow down applied to the forces applied to the simulation chain",
|
|
update=update_chain_dampening,
|
|
options={"LIBRARY_EDITABLE"},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_root_falloff = FloatProperty(
|
|
default=0.25,
|
|
min=0.0,
|
|
max=1.0,
|
|
description="0-1 factor for how much the base of the simulation chain follows the motion of its parent",
|
|
update=update_chain_root_falloff,
|
|
options={"LIBRARY_EDITABLE"},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_velocity = FloatProperty(
|
|
default=1.0,
|
|
min=0.01,
|
|
max=5.0,
|
|
description="Overall scaler for the simulation forces applied to the simulation chain",
|
|
update=update_chain_velocity,
|
|
options={"LIBRARY_EDITABLE"},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_gravity = FloatProperty(
|
|
default=0.02,
|
|
min=-10.0,
|
|
max=10.0,
|
|
description="Strength of the gravity forces applied to the simulation",
|
|
update=update_chain_gravity,
|
|
options={"LIBRARY_EDITABLE"},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_stiffness = FloatProperty(
|
|
default=0.25,
|
|
min=0.0,
|
|
max=1.0,
|
|
description="The amount of stiffness or resistance to bending on the simulation chain",
|
|
update=update_chain_stiffness,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_stiff_end_fac = FloatProperty(
|
|
default=0.25,
|
|
min=0.0,
|
|
max=1.0,
|
|
description="An additional factor for stiffness applied to the last bone of the chain allowing for extra overlapping motion at the end",
|
|
update=update_chain_stiff_end_fac,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_stiff_vel_fac = FloatProperty(
|
|
default=0.2,
|
|
min=0.0,
|
|
max=1.0,
|
|
description="Scaling factor of chain's stiffness when moving at the max velocity. Lower value makes the chain less stiff during fast motion",
|
|
update=update_chain_velocity_fac,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_stiff_vel_min = FloatProperty(
|
|
default=0.1,
|
|
min=0.0,
|
|
max=10.0,
|
|
description="Minimum velocity the chain is moving to start scaling down stiffness",
|
|
update=update_chain_velocity_min,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_stiff_vel_max = FloatProperty(
|
|
default=1.0,
|
|
min=0.0,
|
|
max=10.0,
|
|
description="Maximum velocity the chain is moving to fully scale down stiffness",
|
|
update=update_chain_velocity_max,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_use_collision = BoolProperty(
|
|
default=True,
|
|
description="Simulation tests collisions against the objects in the collision collection",
|
|
update=update_chain_use_collision,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_collision_dist = FloatProperty(
|
|
default=0.01,
|
|
min=0.0,
|
|
max=10.0,
|
|
description="Extra distance to search for a collision",
|
|
update=update_chain_collision_dist,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_collision_friction = FloatProperty(
|
|
default=0.25,
|
|
min=0.0,
|
|
max=1.0,
|
|
description="Scaler for the velocities applied to a chain point when it is colliding",
|
|
update=update_chain_friction,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_limit_collision = BoolProperty(
|
|
default=False,
|
|
description="Limits the collisions of the chain to the typed collection",
|
|
update=update_chain_limit_collision,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
#
|
|
|
|
bpy.types.PoseBone.gp_chain_speed = FloatProperty(
|
|
default=2.0,
|
|
min=0.01,
|
|
max=5.0,
|
|
description="Simulation timescale of the chain",
|
|
update=update_chain_speed,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_mass = FloatProperty(
|
|
default=0.3,
|
|
min=0.0,
|
|
max=50000.0,
|
|
description="How heavy the chain of the simulation is",
|
|
update=update_chain_mass,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_air_dampening = FloatProperty(
|
|
default=0.5,
|
|
min=0.0,
|
|
max=10.0,
|
|
description="Air dampening slows down the chain physics as they fall downwards",
|
|
update=update_chain_air_dampening,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_bend_damping = FloatProperty(
|
|
default=0.5,
|
|
min=0.0,
|
|
max=1000.0,
|
|
description="Amount of dampening applied to the bending of the chain",
|
|
update=update_chain_bend_damping,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
#
|
|
|
|
bpy.types.PoseBone.gp_sim_speed = FloatProperty(
|
|
default=0.8,
|
|
min=0.01,
|
|
max=5.0,
|
|
description="Simulation timescale of the bone",
|
|
update=update_bones_speed,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_friction = FloatProperty(
|
|
default=5.0,
|
|
min=0.0,
|
|
max=50.0,
|
|
description="Friction of the bones simulation",
|
|
update=update_bones_friction,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_mass = FloatProperty(
|
|
default=0.15,
|
|
min=0.0,
|
|
max=50000.0,
|
|
description="How heavy the bone of the simulation chain is",
|
|
update=update_bones_mass,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_stiffness = FloatProperty(
|
|
default=0.1,
|
|
min=0.0,
|
|
max=1.0,
|
|
description="Stiffness of the bones original shape spring during simulation",
|
|
update=update_bones_stiffness,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_damping = FloatProperty(
|
|
default=8.0,
|
|
min=0.0,
|
|
max=50.0,
|
|
description="Amount of damping applied to the bones original shape strength",
|
|
update=update_bones_damping,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_strength = FloatProperty(
|
|
default=0.95,
|
|
min=0.0,
|
|
max=1.0,
|
|
description="Strength of the bones original shape during simulation",
|
|
update=update_bones_strength,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_influence = FloatProperty(
|
|
default=1.0,
|
|
min=0.0,
|
|
max=1.0,
|
|
description="0-1 influence of how much the bone follows the simulation",
|
|
update=update_bones_influence,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_air_dampening = FloatProperty(
|
|
default=1.0,
|
|
min=0.0,
|
|
max=10.0,
|
|
description="Air dampening slows down the bone physics as they fall downwards",
|
|
update=update_bones_air_dampening,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_bend_damping = FloatProperty(
|
|
default=10.0,
|
|
min=0.0,
|
|
max=1000.0,
|
|
description="Amount of dampening applied to the bending of the chain",
|
|
update=update_bones_bend_damping,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_use_collision = BoolProperty(
|
|
default=True,
|
|
description="Simulation tests collisions against the objects in the collision collection",
|
|
update=update_bones_use_collision,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_limit_collision = BoolProperty(
|
|
default=False,
|
|
description="Limits the collisions of the bone to the typed collection",
|
|
update=update_bones_limit_collision,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_gravity = FloatProperty(
|
|
default=1.0,
|
|
min=-10.0,
|
|
max=10.0,
|
|
description="Controls the amount gravity effects the simulation",
|
|
update=update_bones_gravity,
|
|
options={"LIBRARY_EDITABLE",},
|
|
override={"LIBRARY_OVERRIDABLE"},
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_sim_object = StringProperty(
|
|
default="", options={"LIBRARY_EDITABLE"}, override={"LIBRARY_OVERRIDABLE"}
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_chain_id = StringProperty(
|
|
default="", options={"LIBRARY_EDITABLE"}, override={"LIBRARY_OVERRIDABLE"}
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_has_sb_physics = BoolProperty(
|
|
default=False, options={"LIBRARY_EDITABLE"}, override={"LIBRARY_OVERRIDABLE"}
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_has_gn_physics = BoolProperty(
|
|
default=False, options={"LIBRARY_EDITABLE"}, override={"LIBRARY_OVERRIDABLE"}
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_has_jg_physics = BoolProperty(
|
|
default=False, options={"LIBRARY_EDITABLE"}, override={"LIBRARY_OVERRIDABLE"}
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_has_cl_physics = BoolProperty(
|
|
default=False, options={"LIBRARY_EDITABLE"}, override={"LIBRARY_OVERRIDABLE"}
|
|
)
|
|
|
|
bpy.types.PoseBone.gp_update = BoolProperty(default=True, options={"LIBRARY_EDITABLE"}, override={"LIBRARY_OVERRIDABLE"})
|
|
|
|
bpy.types.PoseBone.gp_end_of_chain = BoolProperty(default=False, options={"LIBRARY_EDITABLE"}, override={"LIBRARY_OVERRIDABLE"})
|
|
|
|
bpy.utils.register_class(gp_bone_props)
|
|
bpy.utils.register_class(gp_bone_collection)
|
|
bpy.types.Object.gp_bone_coll = PointerProperty(type=gp_bone_collection)
|
|
|
|
|
|
def unregister():
|
|
_unregister()
|
|
|
|
bpy.app.handlers.animation_playback_pre.remove(timeline_sync_handler_playback_pre)
|
|
bpy.app.handlers.animation_playback_post.remove(timeline_sync_handler_playback_post)
|
|
|
|
bpy.utils.unregister_class(gp_bone_props)
|
|
bpy.utils.unregister_class(gp_bone_collection)
|
|
del bpy.types.Object.gp_bone_coll
|