-
Notifications
You must be signed in to change notification settings - Fork 96
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Shifter: adding Chain_spring_gravity: Emilio Serrano Contribution: Ap…
- Loading branch information
miquelcampos
committed
Feb 9, 2025
1 parent
a624195
commit cde3fdc
Showing
5 changed files
with
446 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
release/scripts/mgear/shifter_classic_components/chain_spring_gravity_01/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
Custom chain spring with gravitiy and colliders setup. | ||
|
||
Following some insight from Hiroyuki Akasaki [https://x.com/akasaki1211/media](https://x.com/akasaki1211/status/1761769004715397579) | ||
|
||
I managed to add gravity and colliders to the spring chain component. | ||
|
||
I simply duplicated the component and hooked the mgear_springGravityNode to it, exposing the relevant parameters to the host control. | ||
|
||
![image](https://github.com/user-attachments/assets/78e44fc2-92d1-4971-8ba5-447c1b026faa) | ||
|
||
The component is exactly as the spring chain: | ||
|
||
![image](https://github.com/user-attachments/assets/41a1bbe3-6a07-48cb-8158-8bcfcea02c2e) | ||
|
||
Once built you can see the usual spring parameters plus the new ones exposed: | ||
|
||
![image](https://github.com/user-attachments/assets/967c5e60-0436-4c3f-9d52-c2fc0c184b99) | ||
|
||
Gravity per sections 0 to 10 | ||
|
||
Gravity direction pointing down (Y) per section | ||
|
||
Use Ground. (infinite plane at 0.0.0) per section | ||
|
||
Collide softness when you connect some basic primitives to the collider list and radius | ||
|
||
![image](https://github.com/user-attachments/assets/14e556e4-8550-4f0b-9281-7f7957417107) | ||
|
||
|
||
|
||
|
||
|
||
Download the zip, and extract into your mGear shifter Classic components: | ||
|
||
![image](https://github.com/user-attachments/assets/6c38679d-1aca-42ee-84d6-d9c0e968f373) | ||
|
||
Also, to define the component when building you need to add these lines to the applyop.py, or overwrite the file within the zip provided. | ||
|
||
C:\Users\yourUserName\Documents\maya\modules\scripts\mgear\core | ||
|
||
def gear_springG_op(in_obj, goal=False): | ||
"""Apply mGear spring Gravity node. | ||
|
||
Arguments: | ||
in_obj (dagNode): Constrained object. | ||
goal (dagNode): By default is False. | ||
|
||
Returns: | ||
pyNode: Newly created node | ||
""" | ||
if not goal: | ||
goal = in_obj | ||
|
||
node = pm.createNode("mgear_springGravityNode") | ||
|
||
pm.connectAttr("time1.outTime", node + ".time") | ||
dm_node = pm.createNode("decomposeMatrix") | ||
pm.connectAttr(goal + ".parentMatrix", dm_node + ".inputMatrix") | ||
pm.connectAttr(dm_node + ".outputTranslate", node + ".goal") | ||
|
||
cm_node = pm.createNode("composeMatrix") | ||
pm.connectAttr(node + ".output", cm_node + ".inputTranslate") | ||
|
||
mm_node = pm.createNode("mgear_mulMatrix") | ||
|
||
pm.connectAttr(cm_node + ".outputMatrix", mm_node + ".matrixA") | ||
pm.connectAttr(in_obj + ".parentInverseMatrix", mm_node + ".matrixB") | ||
|
||
dm_node2 = pm.createNode("decomposeMatrix") | ||
pm.connectAttr(mm_node + ".output", dm_node2 + ".inputMatrix") | ||
pm.connectAttr(dm_node2 + ".outputTranslate", in_obj + ".translate") | ||
|
||
pm.setAttr(node + ".stiffness", 0.5) | ||
pm.setAttr(node + ".damping", 0.5) | ||
|
||
return node |
232 changes: 232 additions & 0 deletions
232
release/scripts/mgear/shifter_classic_components/chain_spring_gravity_01/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
"""Component Chain Spring 01 module""" | ||
|
||
import pymel.core as pm | ||
from pymel.core import datatypes | ||
|
||
from mgear.shifter import component | ||
|
||
from mgear.core import applyop, vector, node | ||
from mgear.core import attribute, transform, primitive | ||
|
||
############################################# | ||
# COMPONENT | ||
############################################# | ||
|
||
|
||
class Component(component.Main): | ||
"""Shifter component Class""" | ||
|
||
# ===================================================== | ||
# OBJECTS | ||
# ===================================================== | ||
def addObjects(self): | ||
|
||
# blades computation | ||
self.normal = self.guide.blades["blade"].z | ||
self.binormal = self.guide.blades["blade"].x | ||
|
||
self.fk_npo = [] | ||
self.fk_ctl = [] | ||
self.spring_cns = [] | ||
self.spring_aim = [] | ||
self.spring_lvl = [] | ||
self.spring_ref = [] | ||
self.spring_npo = [] | ||
self.spring_target = [] | ||
parent = self.root | ||
self.previousTag = self.parentCtlTag | ||
for i, t in enumerate(transform.getChainTransform(self.guide.apos, | ||
self.normal, | ||
self.negate)): | ||
dist = vector.getDistance(self.guide.apos[i], | ||
self.guide.apos[i + 1]) | ||
|
||
fk_npo = primitive.addTransform(parent, | ||
self.getName("fk%s_npo" % i), t) | ||
|
||
spring_aim = primitive.addTransform( | ||
fk_npo, | ||
self.getName("spring%s_aim" % i), t) | ||
|
||
spring_cns = primitive.addTransform( | ||
fk_npo, | ||
self.getName("spring%s_cns" % i), t) | ||
|
||
fk_ctl = self.addCtl( | ||
spring_cns, | ||
"fk%s_ctl" % i, | ||
t, | ||
self.color_fk, | ||
"cube", w=dist, | ||
h=self.size * .1, | ||
d=self.size * .1, | ||
po=datatypes.Vector(dist * .5 * self.n_factor, 0, 0), | ||
tp=self.previousTag, | ||
lp=False) | ||
|
||
self.previousTag = fk_ctl | ||
|
||
t = transform.getTransformFromPos(self.guide.apos[i + 1]) | ||
spring_npo = primitive.addTransform( | ||
parent, self.getName("spring%s_npo" % i), t) | ||
spring_target = primitive.addTransform( | ||
spring_npo, self.getName("spring%s" % i), t) | ||
|
||
parent = fk_ctl | ||
|
||
self.spring_cns.append(spring_cns) | ||
self.spring_aim.append(spring_aim) | ||
|
||
self.addToGroup(spring_cns, "PLOT") | ||
|
||
self.fk_npo.append(fk_npo) | ||
self.fk_ctl.append(fk_ctl) | ||
attribute.setKeyableAttributes(self.fk_ctl, self.tr_params) | ||
|
||
self.spring_target.append(spring_target) | ||
|
||
# Chain of deformers ------------------------------- | ||
self.loc = [] | ||
parent = self.root | ||
for i, t in enumerate(transform.getChainTransform(self.guide.apos, | ||
self.normal, | ||
self.negate)): | ||
loc = primitive.addTransform(parent, self.getName("%s_loc" % i), t) | ||
|
||
self.loc.append(loc) | ||
self.jnt_pos.append([loc, i]) | ||
parent = loc | ||
|
||
# ===================================================== | ||
# ATTRIBUTES | ||
# ===================================================== | ||
def addAttributes(self): | ||
"""Create the anim and setupr rig attributes for the component""" | ||
|
||
# Anim ------------------------------------------- | ||
self.aDamping = [] | ||
self.aGravity = [] | ||
self.aGravitydirectionY = [] | ||
self.ause_ground = [] | ||
self.acollide_softness = [] | ||
self.aStiffness = [] | ||
self.aSpring_intensity = self.addAnimParam("spring_intensity", | ||
"Spring chain intensity", | ||
"double", | ||
0, | ||
0, | ||
1) | ||
for i, tar in enumerate(self.spring_target): | ||
aDamping = self.addAnimParam("damping_%s" % i, | ||
"damping_%s" % i, | ||
"double", | ||
0.5, | ||
0, | ||
1) | ||
self.aDamping.append(aDamping) | ||
|
||
for i, tar in enumerate(self.spring_target): | ||
|
||
aStiffness = self.addAnimParam( | ||
"stiffness_%s" % i, "stiffness_%s" % i, "double", 0.5, 0, 1) | ||
|
||
self.aStiffness.append(aStiffness) | ||
|
||
for i, tar in enumerate(self.spring_target): | ||
|
||
aGravity = self.addAnimParam( | ||
"gravity_%s" % i, "gravity_%s" % i, "double", 0, 0, 10) | ||
|
||
self.aGravity.append(aGravity) | ||
|
||
for i, tar in enumerate(self.spring_target): | ||
|
||
aGravity = self.addAnimParam( | ||
"gravity_directionY_%s" % i, "gravity_directionY_%s" % i, "double", -1, -10, 10) | ||
|
||
self.aGravitydirectionY.append(aGravity) | ||
|
||
for i, tar in enumerate(self.spring_target): | ||
|
||
ause_ground = self.addAnimParam( | ||
"useGround_%s" % i, "useGround_%s" % i, "bool", 0, 0, 1) | ||
|
||
self.ause_ground.append(ause_ground) | ||
|
||
for i, tar in enumerate(self.spring_target): | ||
|
||
acollide_softness = self.addAnimParam( | ||
"collide_softness_%s" % i, "collide_softness_%s" % i, "double", 0, 0, 1) | ||
|
||
self.acollide_softness.append(acollide_softness) | ||
|
||
# ===================================================== | ||
# OPERATORS | ||
# ===================================================== | ||
def addOperators(self): | ||
"""Create operators and set the relations for the component rig | ||
Apply operators, constraints, expressions to the hierarchy. | ||
In order to keep the code clean and easier to debug, | ||
we shouldn't create any new object in this method. | ||
""" | ||
|
||
# Chain of deformers ------------------------------- | ||
for i, loc in enumerate(self.loc): | ||
pm.parentConstraint(self.fk_ctl[i], loc, maintainOffset=False) | ||
|
||
# spring operators | ||
# settings aim contraints | ||
for i, tranCns in enumerate(self.spring_aim): | ||
if self.negate: | ||
aimAxis = "-xy" | ||
else: | ||
aimAxis = "xy" | ||
applyop.aimCns(tranCns, | ||
self.spring_target[i], | ||
aimAxis, | ||
2, | ||
[0, 1, 0], | ||
self.fk_npo[i], | ||
False) | ||
ori_cns = applyop.oriCns(tranCns, self.spring_cns[i]) | ||
|
||
springOP = applyop.gear_spring_gravity_op(self.spring_target[i]) | ||
|
||
blend_node = pm.createNode("pairBlend") | ||
|
||
pm.connectAttr(ori_cns.constraintRotate, blend_node.inRotate2) | ||
pm.connectAttr(self.aSpring_intensity, blend_node.weight) | ||
|
||
pm.disconnectAttr(ori_cns.constraintRotate, | ||
self.spring_cns[i].rotate) | ||
|
||
pm.connectAttr(blend_node.outRotateX, self.spring_cns[i].rotateX) | ||
pm.connectAttr(blend_node.outRotateY, self.spring_cns[i].rotateY) | ||
pm.connectAttr(blend_node.outRotateZ, self.spring_cns[i].rotateZ) | ||
|
||
pm.connectAttr(self.aSpring_intensity, springOP + ".intensity") | ||
pm.connectAttr(self.aDamping[i], springOP + ".damping") | ||
pm.connectAttr(self.aStiffness[i], springOP + ".stiffness") | ||
pm.connectAttr(self.aGravity[i], springOP + ".gravity") | ||
pm.connectAttr(self.ause_ground[i], springOP + ".use_ground") | ||
pm.connectAttr(self.acollide_softness[i], springOP + ".collide_softness") | ||
pm.connectAttr(self.aGravitydirectionY[i], springOP + ".gravity_directionY") | ||
|
||
# ===================================================== | ||
# CONNECTOR | ||
# ===================================================== | ||
def setRelation(self): | ||
"""Set the relation beetween object from guide to rig""" | ||
|
||
self.relatives["root"] = self.loc[0] | ||
self.controlRelatives["root"] = self.fk_ctl[0] | ||
self.jointRelatives["root"] = 0 | ||
for i in range(0, len(self.loc) - 1): | ||
self.relatives["%s_loc" % i] = self.loc[i + 1] | ||
self.controlRelatives["%s_loc" % i] = self.fk_ctl[i + 1] | ||
self.jointRelatives["%s_loc" % i] = i + 1 | ||
self.relatives["%s_loc" % (len(self.loc) - 1)] = self.loc[-1] | ||
self.controlRelatives["%s_loc" % (len(self.loc) - 1)] = self.fk_ctl[-1] | ||
self.jointRelatives["%s_loc" % (len(self.loc) - 1)] = len(self.loc) - 1 |
Oops, something went wrong.