Level Of Detail
Light-weight or heavy-duty? How about both!
Level of Detail
Setup your character once with all bells-and-whistles, and interactively pick which level of detail to use for your simulation in a given situation.
Usecases
- Body at
Level 0
, fingers atLevel 1
- Props at
Level 1
, muscles atLevel 2
- Major masses at
Level 0
, extremities atLevel 1
andLevel 2
For example, here's a Wasp character with 3 levels of increasing detail.
As you'd expect, it'll record only the currently active markers.
Workflow
Here's how it works.
- Give each marker a "level", such as
1
- Tell solver which "level" to solve at, such as
1
And that's it! Any marker with a matching level is simulated and recorded.
Operators
What does each level mean? The answer lies in the "operator".
Operator | Description |
---|---|
Less Than |
If the Marker Level is less than (or equal) to the Solver Level , simulate it. |
Greater Than |
If the Marker Level is greater than (or equal) to the Solver Level , simulate it. |
Equal |
If the Marker Level is equal to the Solver Level , simulate it. |
NotEqual |
If the Marker Level is not equal to the Solver Level , simulate it. |
With these, you can use each level for..
- An increasing amount of detail
- An increasing amount of reduction
- Something completely custom
With Equal
and NotEqual
operators, you can have some markers appear or disappear on particular levels, enabling endless combinations.
Roadmap
This should cover a majority of cases, but there are things you cannot yet do, but will be able to in the future.
Capsule
on one level,Mesh
on another. For higher-resolution contacts.- Dense hierarchy of controls at one level, sparse at another. For e.g. twist joints versus a simple 2-joint chain, or a densely packed spine versus just hip and torso controls.
Algorithm
For the geeks out there, here's what the underlying algorithm looks like in Python.
# Membership types
Minimum = 1 # Present at this level and higher
Maximum = 3 # Present at this level and lower
Only = 4 # Only present at this level
Not = 5 # Present at all levels *except* this one
markers = [
{"name": "hip", "level": 0, "membership": Minimum},
{"name": "spine", "level": 0, "membership": Minimum},
{"name": "neck", "level": 0, "membership": Minimum},
{"name": "head", "level": 0, "membership": Minimum},
{"name": "L_upper_leg", "level": 0, "membership": Minimum},
{"name": "L_lower_leg", "level": 0, "membership": Minimum},
{"name": "R_hand", "level": 1, "membership": Minimum},
{"name": "L_foot_box", "level": 1, "membership": Maximum},
{"name": "L_foot_convex", "level": 2, "membership": Minimum},
{"name": "R_toe_capsule", "level": 2, "membership": Not},
{"name": "R_toe_convex", "level": 2, "membership": Only},
]
def resolve(level):
print("Level %d" % level)
for marker in markers:
if marker["membership"] == Minimum and marker["level"] <= level:
print(" - {name} ({level})".format(**marker))
if marker["membership"] == Maximum and marker["level"] >= level:
print(" - {name} ({level})".format(**marker))
if marker["membership"] == Only and marker["level"] == level:
print(" - {name} ({level})".format(**marker))
if marker["membership"] == Not and marker["level"] != level:
print(" - {name} ({level})".format(**marker))
resolve(0)
resolve(1)
resolve(2)
Run this, and this is what you'll find.
Level 0
- hip (0)
- spine (0)
- neck (0)
- head (0)
- L_upper_leg (0)
- L_lower_leg (0)
- L_foot_box (1)
- R_toe_capsule (2)
Level 1
- hip (0)
- spine (0)
- neck (0)
- head (0)
- L_upper_leg (0)
- L_lower_leg (0)
- R_hand (1)
- L_foot_box (1)
- R_toe_capsule (2)
Level 2
- hip (0)
- spine (0)
- neck (0)
- head (0)
- L_upper_leg (0)
- L_lower_leg (0)
- R_hand (1)
- L_foot_convex (2)
- R_toe_convex (2)