Skip to content

Instantly share code, notes, and snippets.

@mottosso
Last active February 20, 2021 09:55
Show Gist options
  • Save mottosso/237aac24b17acd63c1d1c33d4d693a36 to your computer and use it in GitHub Desktop.
Save mottosso/237aac24b17acd63c1d1c33d4d693a36 to your computer and use it in GitHub Desktop.
Editable Initial State

Goal

Here's an example of the Maya Bullet integration implementing the desired behavior.

Notice how I can manipulate the cube on the start frame, and have it continue manipulating the cube on subsequent frames. Starting from wherever I left it.

Requirements

  • Must work with Parallel Evaluation
  • Must work with Cached Playback
  • Must work with mayapy, i.e. without a GUI

Attempts

These are the things I've tried so far.

  1. Attribute Affects
  2. Output Value I - Naive
  3. Output Value II - Start, First, Second
  4. Output Value III - Pull from Callback
  5. MDGContext
  6. Internal Value
  7. Mouse Up Event
  8. Output Value IV - By Force
  9. Matrix, not World Matrix
  10. Matrix + Parent Matrix
  11. MFnTransform

Problem

For completeness, here's what it looks like in the production project. It won't all make sense, hence the minimal reproducible associated to every attempt.

  1. I'd like to change initial state for one object
  2. And I'd like to not dirty the child transforms when that happens

I cannot make changes to the initial state, without explicitly writing to it via script. A is the goal user interaction, B is the current workaround.

ragdollissue11

Hierarchy is not maintained when parent moves.

ragdollissue2


Bullet Reference

Here's an example of the Maya Bullet integration implementing the desired behavior.

Here's what the network looks like.

image

  • .currentTime Likely used to dirty the output plugs
  • .inParentInverseMatrix This is needed to translate the worldspace Bullet transform into a localspace transform, and likely isn't used for the actual simulation.
  • .inWorldMatrix This looks to be where it gets the rest position of the box
  • .pivotTranslate Likely also used post-simulation, to convert worldspace into the local Maya transform, respecting the rotate pivot.
  • .solverInitialized Interestingly the solver telling the rigid the solver has been initialised, rather than the rigid passing data to the solver for its initial state on the first frame.
  • .solverUpdated Likewise, a connection from solver to rigid. I haven't made sense out of these yet. What can the rigid do with that information?

The most noticeable bit is pCube1.worldMatrix[0] connecting to bulletRigidBodyShape1.inWorldMatrix. Which can also be seen from the AE.

bulletclue1

Here's a schematic for clarity.

 ___________________________________________________
|                              __________________   |
|                             |                  |  |
|                             |   worldMatrix[0] o--`
|    __________________       |                  |
|   |                  |      |                  |
`-->o inWorldMatrix    |      |                  |
    |                  |      |                  |
    |                  |      |                  |
    |                  |      |                  |
    |                  |      |                  |
    |                  |      |                  |
    |  outputTranslate o----->o translate        |
    |                  |      |__________________|
    |__________________|
                                        transform
           My plug-in

Sidenote, the Bullet behaviour also applies to hierarchies of objects. This suggests to me that the .outSolvedTranslate isn't actually dirtied when inWorldMatrix is dirtied. Bullet isn't doing anything here, just standing by.

bulletgoal2


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment