Finessing Physics

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search

Finessing Physics[edit | edit source]

Huge thanks to:

m4444x (not only as creator of the almighty NifSkope, but for originally proposing using the bhkTristrips data block in the first place), gundalf (aka fladnug), Brandano and Shon. Thanks also to all the usual suspects over at the CS forums whose indefatigable strivings in various directions of mod making in the face of inumerable setbacks and frustrations is a constant inspiration.


Now down to business:

So you've made a custom mesh, textured it and got it in game. Good for you. Plenty of modders don't get this far. But before you take off your modelling hat there's one more thing you need to think about: Physics.

For weapons misplaced collision boxes will cause clipping through floors, unnatural bounces and other minor annoyances. For architecture not having collision boxes in the right place is outright disastorous.

In the absence of an official exporter creating custom physics for your meshes isn't easy. As with most of the meshing solutions currently available the following is a work around and is consequently imperfect.

The Main Blocks[edit | edit source]

Before discussing how to add the Havok blocks it's worth saying something about what they are and what they do. Having a look at any nif file you should be able to work this out fairly readily for yourself, but in brief:

bhkCollisionObject

This is the basis of the collision object for the nif file. Each NiNode can reference one collision object. Of course one nif can have more than one NiNode and therefore more than one collision object (a fact which will be exploited later in this tutorial).

bhkRigidBody

Just as the NiNode refers to a collision object, so the collision object in turn refers to a rigid body. This is the first of the blocks with details which it's important to configure correctly:

Shape: Dealt with more fully below

Layer: Determines the colour of the collision box in the CS

Translation / Rotation: Deals with the position of the shapes in 3D space

Inertia: Defines how easy or hard it is to spin the body

Center: The center of gravity

Mass Operates largely as would be expected, except that it doesn't affect the speed at which bodies fall. This being controlled instead by:

Linear / Angular Damping: A force applied in the opposite direction to the direction of the travel. The strength of that force being specified by integers with 100 being the highest. Using this on the skeleton.nif for instance it has been possible to change the speed at which corpses fall.

Friction & Restitution: These properties affect how quickly a body will lose momentum (although of course it should be borne in mind that the friction of the surface the object comes into contact with will also be relevant).

Motion System & Quality Type:The most useful thing to know about these properties are these two permetations: MS - 7; QT - 1: will be a static object (eg. architecture); MS-3; QT- 4: will be a moveable object (eg. weapons, items, etc).

Shapes

As mentioned above the bhkrigidbody block will reference a Shape. Many official meshes use bhktriangles which fit closely to the trishape geometary. From a modder's perspective these shapes are basically useless for a number of reasons. When making custom physics for a mesh more generic shapes are therefore necessary, these can be found in most weapons for instance. The two most generally versatile being the bhkboxshape (found eg. in axe meshes) and the capsule shape (found eg. in sword meshes).

Shapes have materials defined by integers. A full list of the materials and corresponding integers can be found here

bhkListShape

This allows one rigid body to harbour multiple bhkshapes. The shape of the bhkrigidbody is set to the listshape block, which in turn references all of your added bhkshapes. As described below when building complex meshes (or even relativly simple ones for that matter) this block is imperative. It can readily be found in axe nifs.

bhkConvexTransformShape

As will be apparent from the dicussion below this is one of the most useful of all the Havok related blocks. It's Matrix44 Transform Controller allows changes to be made to the translation and rotation of the shape controlled by it.

DO NOT use the scaling function of this block. In game any scale changes made using    
this will be effectual in terms of the basic collision box, but does not affect the 
collision box as detected by arrows. For scaling then the Vector3 Dimensions of 
the Shape block itself should be used.

Simple Collision Modeling[edit | edit source]

Step 1


Create a nif file of your custom mesh. It doesn't really matter how you do this for these purposes (i.e. whether you export as .nif or as .obj). Now you need to assemble your Havok building blocks. If you've imported as obj you'll already have the bhkcollision object block and associated substructure;leave all of that in place but delete the shape blocks. If you exported as .nif you can copy/paste these blocks from an official mesh.

Look at your mesh and work out in terms of boxes and cylinders (capsules) how many of each type of shape you'll need. You can acquire these shapes from weapon meshes: swords have capsules and axes have boxes. Copy and paste as many as you'll need into your nif.

For each box you'll also need a bhkconvextransform shape block. Again these can be copied from axe nifs and indeed if you copy the entire branch (so including the box) you won't need to parent them up afterwards.

Finally you'll need a bhklistshape. Again you can take one from the axe meshes.


Step 2


Now you need to connect all these new blocks up.

Set the bhkrigidbody's shape to the bhklistshape you've just pasted in.

Then in the details window for the bhklistshape set the number of subshapes to the number of shapes you intend to use. Then right click the Subshapes array and update it so that you have open slots. Double click those and input the block numbers of your subshapes (for boxes using a convex transform shape to control it, it's the number of the convex transform shape which you should use).

Then follows the most mind-numbingly boring part of this process. The sequence of the block numbers has to be very specific for Havok in a way that is not true for trishapes. By right clicking the blocks in the block list window of NifSkope you can use move up and move down to change their position in the order. That order has to be made to follow this sequence:

0: NiNode;

1: (potentially 2&3) will be the BSX, UPB and PM blocks depending on what type of mesh you're creating;

2: Then comes the first of your bhk shapes. If it's a box with a convertedshape block then the shape comes first and then the convert block, then the next shape and so forth.

n: After listing all of your shapes, comes the bhklistshape;

n+1: Then the bhkrigidbody;

n+2: Then the bhkcollisionobject;

n+3: Then the trishape/strip blocks.


Basically the sequence of block numbers should run inversely to the order in which they appear in the NifSkope block list heirarchy.


  If on game testing the program crashes before it even fully loads it's usually
  because of an error in this sequence.


Step 3


At this stage you have a working nif which uses multiple collision shapes. Now you have to arrange these to work for your model. Obviously what this entails will be different for every mesh so it's not really possible to fully tutorialise this step.

bhkcapsules have a radius which determines their circumference. And then two "points" each of which corresponds to one end of the shape and can be set on the x,y and z axis.

bhkboxes have dimensions which be scaled separately along each of the three axis (as mentioned above, this should be used instead of the scaling function of the bhkconvextransformed shape block.

bhkconvextransformshape, can be used to control the translation and rotation of bhkboxshapes. In the details window for the block, right click the Transform property at the bottom of that list and choose Edit Matrix to open a dialogue allowing you to make the requisite changes. But please note the warning in the section above about it's scaling function.

Better Collision Modeling[edit | edit source]

3DS Max users now have the benefit of gundulf's plugin which automatically generates collision models on export. You can link to the download of that plugin and read a tutorial on it's use here. Users of this plugin may also find it helpful to read through this tutorial though since the technique described here is essentially the long hand version of what the plugin is doing.


But what about those of us not fortunate enough to have the latest version of 3DS? Well, do not despair. Because although the route is a little more arduous the creation of collision meshes directly matching your mesh is still a possibility. The following step by step will show how to produce the same end result as the plugin afore-mentioned via a few simple NifSkope hacks. But first a warning:

  WARNING
  The following technique generates collision objects in a more processor intensive
  manner than the Simple Collision Modelling technique discussed above. Because
  we will be dealing with TRIstrips the quads of your mesh will be subdivided into
  triangles. That means for instance even a basic shape like a box will have 12 
  faces rather than 6. In detecting collisions the engine calculates against all
  faces in the mesh thus it is strongly urged that you make every effort to minimise
  the number of faces.
  
  Wherever possible then the technique below should be combined with the technique
  above so that the bhkNiTristrip block is used only for sections of detailing where 
  using the primitive shapes would be impractical or impossible.


Step 1

The first phase of this process is to export your mesh from the modelling application (whether as .nif or .obj is really immaterial). If you're unsure of how to do this see Custom Weapons with NifSkope for further details.

The additional element in doing this though is to also create and export a less detailed version of your mesh which will be used as the collision model. In fact you may need to export more than one additional mesh if you're new model is going to be built from different materials. For instance the stone sections will need to be exported as one part, the wood sections as another and so forth.

From a workflow point of view I tend to find it helpful to duplicate the original mesh, move it to a different layer and then start to savage it. Your objective in this phase is to reduce the face count as far as possible. This can be done by hand or your application may have some tools to ease the process.

  Blender users may find the decimate modifier helpful. Details here

Remember also so that anything you could just use a bhkprimitive for (standard boxes, capsules, etc) can also be omitted and built up using the Simple Collision Modelling techniques above.


Step 2

By the end of step 1 you should now have two (or more) nif files. One which is the mesh as it will be seen in game (hereinafter the primary nif) and another (or others) which is the mesh as it will be collided with in game (hereinafter the secondary nif).

If your collision mesh has omitted any areas because you're going to create them using the Simple Collision Modelling techniques, you should do that now. Build those structures up within the primary nif, following the guide above.

So now on to converting those additional nifs into collision meshes. The first thing you're going to need is a bhkNitristrip block. You can find one of those in the following nif:

BSA\meshes\dungeons\ayleidruins\exterior\arstatue01.nif

Highlight that block in the block list and in the block details you should see Num Strips Data, followed by an array drop down showing which block the strips data is being taken from. For now, set the strips data to -1, copy the block and paste it into your primary nif. Don't save the change of setting the strips data to -1 on the statue nif, that's just a temporary measure to limit confusion on pasting it.


Step 3

Now in a new NifSkope window open your secondary nif. Go to it's NiTristrips block and within that to the NiTristripsData block. Copy the NiTristripsDatablock and paste it into your primary nif. Close the secondary nif window.

In the primary nif window, go to the bhkTristrips block you pasted in Step 2 and in the block list details change the strips data (which you set to -1 in Step 2) to point to the tristrips data block you just pasted across.


Step 4

From here on in, the process is essentially the same as when you reach Step 2 of the Simple Collision Modelling section above in terms of linking things to the proper nodes and fixing the block order (the bhkNiTristrips block can be treated essentially like any other bhk shape block). Set it's material to whatever you want, link it in to the bhkrigidbody block. Set the heirarchy up so that it runs the same way as discussed in the earlier part of this guide. And you're done.


Related Tutorials[edit | edit source]