Defining your Physics:
Here we get to the meat and potatoes of SMP, telling your mesh/bones what to do within the physics simulation. For the sake of this section lets assume we are working on the hands mesh and we have linked said mesh to handsOfArbritraryNamingConventions.xml
These are the "easy" ones, all we need to do here is define to SMP what mesh we want to be a collision object, what type of object we want to use, and what we DON'T want it to collide with.
For starters, the simpler of the two, note that all xml files need to have the <?xml > tag and the <system> </system> tag, place your declarations inside the system tags.
<?xml version="1.0" encoding="UTF-8"?>
<system xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="description.xsd">
<!-- name here refers to the name of your NiTriShape, find this in your body mods femalehands_0/_1 or malehands etc -->
<!-- margin is how much "padding" is added to your mesh when calculating collision, this will cause your mesh to act on physics objects "before" it intersects with them -->
Priority is deprecated and no longer used
how much resource is allocated to this collision object in a multi-collision scenario -->
<!-- an identifier for this mesh collision object for use with no collide tags -->
<!-- prevents this collision object from colliding with the specified tag, note that this will not prevent the specified object from colliding with this unless also defined -->
<!-- on the other colliding object, no colliding with itself is fairly common and is a good standard unless your mesh does in fact collide with itself (multipart earring perhaps) -->
<!-- this ones pretty apparent, will prevent collisions with mesh skinned to bones, could be useful if you wanted the hands to collide with the body but not the belly -->
<!-- although in that particular case the proxy objects give better results -->
<!-- per-vertex-shapes are the simpler and faster collision objects. Obviously that comes with the drawback of less accuracy -->
<!-- vertex is good to use for "dumb collider" type objects, like a bat or a hand, things that don't really need physics calculated on themselves -->
On to the second type, lets use the body as an example in body.xml or default-cbbe.xml etc.
Note: 27X points out that "prenetration" here was probably meant to be bullets "penetration" property.
<!-- How far your mesh can be inside another while still applying collisions -->
<!-- here we have our proxy objects coming in handy, letting us separately define collisions with the left and right breast -->
<weight-threshold bone="HDT Belly">1</weight-threshold>
<weight-threshold bone="NPC Belly">1</weight-threshold>
<!-- weight threshold lets you restrict which verticies/points deform and collide in the specified area -->
<!-- only points with a weight value higher than this threshold will act on collisions -->
<!-- triangle-shapes are best for mesh that needs highly accurate simulation, such as the body -->
It should be noted that traingle->triangle collisions are very demanding and somewhat inefficient, its always best to have vertex->vertex or vertex->triangle, it should also be noted that the more collisions you have the more performance hungry the system will be.
Collisions with the ground:
<!-- This is in the xml tutorial that comes with the packaged files, this is usually added as a flat plane collision proxy -->
By default collision objects collide with all other collision objects, it is highly advisable to restrict your collisions, especially on per-triangle-shapes, to what you really need it to collide with for both performance and visual reasons.
You can have the hands collide directly with the body mesh without the use of proxy objects, however this essentially requires custom animations made specifically for your body mesh/weight value to get desirable results.
This is described from the point of view of the camera behind the player character, e.g. z+ would be moving in the direction the character is facing.
- X: Left/Right/Pitch
- Y: Up/Down/Yaw
- Z: Forward/Back/Twist/Roll
Arrows indicate positive direction, e.g. <angularUpperLimit x="1.57" /> would allow your constraint to rotate 'down' by ~90 degrees.
Translation: WIP testing (these are reasonably small, e.g. you will be working in values under 10 usually).
Rotation: These are in Radians Help
I'm not going to focus too much on rigging or weight mapping here as there are many guides and tutorials and many different methods, here I will just tell you how to declare bones to SMP.
<bone name="bonename" /> <!-- name refers to the name of the bone exactly as displayed in NifSkope -->
Technically this is all you need to declare a bone, although the default values are only really useful for declaring a bunch of Kinematic/Static bones.
Speaking of defaults:
<inertia x="0" y="0" z="0"/>
<basis x="0" y="0" z="0" w="1"/> or <basis-axis-angle x="0" y="0" z="0" angle="0" /> <!-- translate/rotate your center of mass, only use one of these -->
<origin x="0" y="0" z="0"/> <!-- center of rotation/translation -->
These are the default values for bones, you can override these values and change the defaults however this will not "hoist" the deceleration, basically that means if you define a bone then change the default values afterwards those new values will only apply to bones declared after <bone-default>, you can use bone defaults to apply common properties to multiple bones without having to declare the properties on every bone.
As of update 20180113 we have the ability to define and extend templates for 'default' objects, we can now set up groups of common physics properties to be used later on.
<bone-default name="dress_heavy" extends="dress">
<mass>3</mass> (overrides mass to 3 instead of 0.5)
(inherits liner/angular damping and friction)
<bone name="dress_01" template="dress" />
<bone name="dress_02" template="dress" />
<bone name="dress_03" template="dress_heavy" />
<bone name="foo" /> <!-- this bone will have the standard default values -->
for the sake of space I have only declared mass, while this is a legitimate block you probably want to
do more than alter the mass of a bone
<bone name="bar" /> <!-- this bone will have a mass of 1 -->
<!-- Set default back to kinematic just in case, leave undeclared bones as non physics bones -->
You can also define custom properties for bones by turning them into explicit closing blocks/tags.
Be careful with bone defaults, if you set a default physics enabled bone and leave some bones undeclared they will automatically have the defaults applied to them, this is probably not a desirable result.
Custom bone properties:
<inertia x="0" y="0" z="0"/>
<basis x="0" y="0" z="0" w="1"/>
<origin x="0" y="0" z="0"/> <!-- center of rotation/translation -->
<!-- the majority of the way your bone physics behaves is in these next values -->
<!-- as far as I can tell this will override any declared properties and use defaults for any non-declared properties -->
Lets look at the properties of bones:
- <mass>: (float, reasonable starting value 1) This tells SMP how "heavy" the bone is, mostly used as a multiplier in other calculations, 0 is a special property though as a mass of 0 will change your bone to Kinematic/Static (will only be affected by animations targeting it, no physics). Use a mass of 0 for your anchor/root bone so that your bones don't "fall off your character"
- <inertia>: (float, reasonable starting value 100 * mass) How much energy is applied to your bone, if your bone is Dynamic (affected by physics) then none of these values can be 0, setting one or more of these to 0 will give you undesired results. This also affects how much energy your constraints have, low energy will make your constraints basically worthless.
- <linearDamping>: (float, valid range [0-1]) This will remove a percentage of your translational (X, Y, Z) energy per calculated second, a value of 1 will remove 100% of your energy, 0.3 will remove 30% etc
- <angularDamping>: (float, valid range [0-1]) This will remove a percentage of your rotational (Y, P, R) energy per calculated second.
- <friction/rollingFriction>: (float, valid range unknown) These are not terribly well explained, as damping is only applied when there is no external force then friction is most likely applied regardless, this would make your object seem "heavier" as it would be less affected by changes in velocity
- <restitution>: (float, valid range [0-1]) Restitution is how bouncy your object is, higher values being more bouncy
- <margin-multiplier>: (float, valid range any/standard float range) Has something to do with skeletal related collisions, higher values will increase impact of collisions on the bone.
Formula for damping: v = v * (1-damping), damping is applied when there is no external force/movement, to somewhat remove movement on a single axis set your linear/angular damping to 1 on that axis.
As a note, it is best to use a combination of linear and angular movement in most cases, relying only on one will give you somewhat poor simulation. In particular relying only on angular movement can give you frustratingly difficult movement to work with, e.g. If you have an earring attached to a chain, add at least one anchor bone, at least one bone for the chain using both angular and linear movement and at least one bone using angular/linear movement for the earring itself.
With some dedication you could get very nice physics simulations by combining animated (Kinematic/static) bones with Dynamic bones constrained to them.
This is where we tell our bones what to "stick" to and how far they are allowed to deviate/move from their parents position. There are two constraints so far:
At the moment I have not been able to get stiffspring to work so I will focus on the more expansive generic-constraint.
Much like bones we can either use/change the defaults or define the properties on the constraint itself, this follows the same hoisting rules as above.
Adding a constraint:
<generic-constraint bodyA="Bone-ear" bodyB="Bone-ear-anchor"/>
<!-- bodyA: the bone you want to constrain to something -->
<!-- bodyB: the parent bone you want to constrain it to -->
<!-- this constraint will use the default properties as defined before its decleration -->
<generic-constraint bodyA="Bone-ear" bodyB="Bone-ear-anchor">
<!-- for custom properties -->
And the default values:
<basis x="0" y="0" z="0" w="1"/>
<origin x="0" y="0" z="0"/>
<!-- This is a standard transform like above, it's where you want your constraint to start from, defaults to the center of the parent bone or bodyB -->
<!-- looking into what this is -->
<linearLowerLimit x="-1" y="-1" z="-1"/>
<linearUpperLimit x="1" y="1" z="1"/>
<angularLowerLimit x="-1" y="-1" z="-1"/>
<angularUpperLimit x="1" y="1" z="1"/>
<!-- These limit how far the constraint can move/rotate away from its parent -->
<!-- For angular (rotation) the lower and upper limit define the range of motion available to the constraint -->
<!-- e.g. <linearLower x="-5" /> | <linearUpper x="5" />, would allow this constraint to move 5 units left or right -->
<linearStiffness x="0" y="0" z="0"/>
<angularStiffness x="0" y="0" z="0"/>
<!-- These will change how stiff your spring is, much like suspension on a car -->
<linearDamping x="0" y="0" z="0"/>
<angularDamping x="0" y="0" z="0"/>
<!-- same as other damping values, although here I am not sure if the valid range is [0-1], it is not specifically stated to be so but I would assume it is -->
<linearEquilibrium x="0" y="0" z="0"/>
<angularEquilibrium x="0" y="0" z="0"/>
<!-- Equilibrium is where the bone will naturally try to come to rest, in general this will be 0,0,0 as you probably want your bone to rest where it started from -->
<!-- In terms of a spring this is where it would rest if there was no force being exerted on it -->
A fairly basic example:
<bone name="Spine05" />
<generic-constraint bodyA="BreastCenter" bodyB="Spine05" />
<generic-constraint bodyA="BreastFore" bodyB="BreastCenter" />
Shall look into some more use cases and examples...
There are several options available to tweak the physics engine settings here.
- <numIterations>: (int, reasonable starting value 10 - 16) Could be simplified as 'simluation accuracy', lower values will gain performance at the cost of less quality. The default value will probably suffice for the most part.
- <groupEnableMLCP>: (boolean) Turn on the higher quality constraint solver, better constraint simulation at the cost of performance.
- <erp>: (float, valid range [0-1]) The error correction force applied per simulation step, constraints will drift apart naturally, this value will exert a force to move them back to where they are supposed to be. You probably won't need to change this from default, do not use a value of 1 http://www.ode.org/o....html#sec_3_7_0
So how do I use this:
Using mod assets as collision objects (easy):
So let's say you download a pair of fancy gloves and you want them to collide with your character.
- Open up the gloves mesh in NifSkope and add the NiStringExtraData block, point it to your desired xml file
- In your xml file create a collision object (probably per vertex) and assign it to the name of the mesh you want to collide, if multiple meshes exists you could either assign both as collision objects or pick the dominant mesh (the one that is more likely to collide) if appropriate.
- Use an appropriate animation or idle to test and tweak the margin value until you have a desirable effect
What about armor?
To have armor collide is easy just do the same as above, likewise with any other type of mesh just make sure to note what the mesh's name is or change it to something standard like glove or armor. Note that your characters body will not collide with anything if you are wearing armor that has not been set up to simulate physics as there is nothing to collide with.
Jiggles and wiggles?
Jiggles is a bit more complicated as you will probably need to add extra bones to the mesh, in the case of armor most old HDT/BBP mesh has one bone for each breast located somewhere near the clavicle area and as you know SMP needs a parent child arrangement or your bones will fall off your character, also the location of the bone is less than ideal for collisions.
To get physics working you will need to load up Studio Max (or Blender) and shift/add the bones to a more ideal locations. Use the body mod as a reference for where to put your bones, this will of course require you to re-skin/weight map the new and old bones that you are modifying/creating.
Make sure that when creating bones you think about what they will be anchored to on the main skeleton.
I want to create waggling nose hairs!
Well much the same as above you would need to open up your 3D program, model some nose hair and add an appropriate number of bones depending on how detailed you want the waggling, weight map your mesh and the rest I would hope is fairly trivial when it comes to defining the physics of said bones.
- HydrogensaysHDT - Obvously
- ledo4ek - Great work on everything, collisions in particular
- ApoKryta - Packaging everything nicely
- prZ - The monumentally useful all in one easy package & detailed guides
- Uhuru N'Uru - Explaining the file structure and how to navigate
- 01023 - I believe for the xml tutorial in the packaged files
- FiftyTifty - Testing OpenCL compatability
- http://www.loverslab...ng-guide/page-1 - Basically everyone in this thread for persistence and testing
Edited by treota, 10 April 2018 - 08:32 AM.