Source SDK

Source SDK

126 ratings
Procedural bone data using Blender
By мяFunreal
This guide shows how to create Procedural bones without using SFM
2
2
   
Award
Favorite
Favorited
Unfavorite
Foreword
Up until now, creating Procedural bone data required SFM, which is a pain to use.
The developer of SourceOps, bonjorno7, added functions to his blender tool to do the same.
Get the addon on this Github page[github.com]
(Made for 2.92.0 but It also works on 2.8)

The following guide assumes you know what procedural bones are.
It also assumes you already have properly rigged helper bones ready to be used.
If you do not know what procedural bones are to begin with, check the VDC

WARNING:
If you are working on a model with proportions, you should do this after you are 100% sure that you are not going to edit the proportions any more!
Editing proportions requires you to redo the VRD from scratch.
0 - Installing the addon
To install the addon, open user preferences by using Ctrl & Alt & U or "Edit > Preferences".
Click the "Install" Button, Find and doubleclick the SourceOps.zip.
Enable the addon by clicking the Tickbox.



1 - Setup
You need a VRD file called "Procedurals.vrd" in which the procedural bone data will be written in.
Just make a txt and change the file ending, or make a new file in Notepad++ and save it as Procedurals.vrd
If you don't have any base, use this:
<helper> <basepos> <trigger> 90 <trigger> 90 <trigger> 90
This uses three triggers, as i'm working on a hand. Other bones like elbows only need two.
You could use as many as you want though.


Your QC file will need the following line to read the VRD data:
$proceduralbones "Procedurals.vrd"

2 - Bone names
Write bone names for the "Helper" field.
Those being: the procedural bone, its root, its parent (same bone) and the control bone.
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> <trigger> 90 <trigger> 90 <trigger> 90
Note: The ValveBiped. part of the full bone name is removed.
3 - Basepos
Select your helper bone in pose mode and bring up the "Context Menu".
If LMB is assigned to "select", context menu assigned to RMB.
If RMB is assigned to "select", context menu assigned to W.


Click "Translation for Source".
The required numbers are copied to your clipboard, ready to be pasted into the VRD.

You can see the default letter assigned to this action is "A".
Next time you could use RMB followed by A, or W followed by A. Gotta go fast, amirite?


Paste the numbers into the "Basepos" field.
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 10.703916 -3.4e-05 1.4e-05 <trigger> 90 <trigger> 90 <trigger> 90
You may notice that the two last numbers contain "e-": -3.4e-05 1.4e-05.
Those are e-notations[en.wikipedia.org], which source engine understands. Ignore them.
4 - Rest Trigger
The first trigger is the "Rest" trigger.
Make sure your pose in blender is the rest pose.
Select the Control bone of your helper, which is the left hand for me.
Bring up the context menu again and pick "Rotation for Source"
Or the shortcuts RMB followed by O, or W followed by O


Paste the new copied numbers into the first trigger, after the 90:
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 10.703916 -3.4e-05 1.4e-05 <trigger> 90 78.669354 6.507517 7.12238 <trigger> 90 <trigger> 90

Select the procedural bone and copy its rotational values right after the control rotation values.
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 10.703916 -3.4e-05 1.4e-05 <trigger> 90 78.669354 6.507517 7.12238 -13.66161 -3.7e-05 8e-06 <trigger> 90 <trigger> 90

Next are the translational values of the procedural. Copy yours if you use them.
I have not moved it, so i just use 0 0 0.
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 10.703916 -3.4e-05 1.4e-05 <trigger> 90 78.669354 6.507517 7.12238 -13.66161 -3.7e-05 8e-06 0 0 0 <trigger> 90 <trigger> 90
Optional - Keyframes
This step is optional. You do not need it, but if you are unsure about making the poses, you should consider following this step.

You'll need to pose the helper bones in at least three positions: Base, positive, and negative.
You could turn on "Auto Keying" in order to temporarily keep the poses of your helpers.
This allows you to jump back into blender and adjust the poses, if you feel like you need to do so.
Not having these keyframes means you'll need to redo the poses from scratch.

First, enter the animation screen.


Press this little button. It looks like the "Rec." LED on camcorders.


Enter pose mode, Press A to select all bones.
Then press i to insert keyframes for all bones.
Pick "Whole Character"


The "Dope sheet" will now show a whole bunch of dots. Those are your keyframes.
5 - Negative Extreme Trigger
If you did the Keyframe setup, you will now need to press the Right Arrow key.
the Dope Sheet should now show a "1" at the very top.


Now that we have a base, we need a trigger for an extreme rotation.
Pose the hand and wrist bone as far into one direction as it would be humanly possible.
I rotated my hand by -100°, wrist by -80° and the forearm helper by -50° on X.
The Forearm needs its own setup, for now i'm posing it to make sure the entire arm looks good.


Now do the same three steps as you just did on the base trigger.

Select the Control bone of your helper, which is the left hand for me.
Bring up the context menu again and pick "Rotation for Source"
Or the shortcuts RMB followed by O, or W followed by O

Paste the new copied numbers into the second trigger, after the 90:
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 10.703916 -3.4e-05 1.4e-05 <trigger> 90 78.669354 6.507517 7.12238 -13.66161 -3.7e-05 8e-06 0 0 0 <trigger> 90 -21.330655 6.507494 7.122384 <trigger> 90

Select the procedural bone and copy its rotational values right after the control rotation values.
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 10.703916 -3.4e-05 1.4e-05 <trigger> 90 78.669354 6.507517 7.12238 -13.66161 -3.7e-05 8e-06 0 0 0 <trigger> 90 -21.330655 6.507494 7.122384 -93.661612 -5.1e-05 3e-06 <trigger> 90

I have not moved by procedural bone, so my translational values will remain 0 0 0.
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 10.703916 -3.4e-05 1.4e-05 <trigger> 90 78.669354 6.507517 7.12238 -13.66161 -3.7e-05 8e-06 0 0 0 <trigger> 90 -21.330655 6.507494 7.122384 -93.661612 -5.1e-05 3e-06 0 0 0 <trigger> 90

Checking up on the Keyframes, you should now have a second row of dots.

If not, you didn't activate the auto key. So you could just select all bones and inserting keyframes for all bones again.
6 - Positive Extreme Trigger
Press the Right Arrow key once more to advance to frame 2.
So we won't overwrite the pose of the negative pose.


We now have triggers for base and far negative rotation. We still need far positive rotation.
Undo all poses and pose all bones by the same amount in the other direction.
I will rotate my hand by 100°, wrist by 80° and the forearm helper by 50° on X.


Write down the rotational data in the third trigger. with 0 0 0 transition, because nothing moved.
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 10.703916 -3.4e-05 1.4e-05 <trigger> 90 78.669354 6.507517 7.12238 -13.66161 -3.7e-05 8e-06 0 0 0 <trigger> 90 -21.330655 6.507494 7.122384 -93.661612 -5.1e-05 3e-06 0 0 0 <trigger> 90 178.669361 6.507496 7.122389 66.33839 -4.9e-05 1.2e-05 0 0 0

You now should have another row of dots in the Dope Sheet.


By the way, you can use up to 32 total triggers per helper bone, should you need more poses.
For example, maybe if your wrist is curled inwards
7 - Repeat on all bones
Repeat these steps for all procedural bones and compile your model.
<helper> Bip01_L_Wrist Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 10.703916 -3.4e-05 1.4e-05 <trigger> 90 78.669354 6.507517 7.12238 -13.66161 -3.7e-05 8e-06 0 0 0 <trigger> 90 -21.330655 6.507494 7.122384 -93.661612 -5.1e-05 3e-06 0 0 0 <trigger> 90 178.669361 6.507496 7.122389 66.33839 -4.9e-05 1.2e-05 0 0 0 <helper> Bip01_L_Ulna Bip01_L_Forearm Bip01_L_Forearm Bip01_L_Hand <basepos> 5.351961 -1.6e-05 6e-06 <trigger> 90 78.669354 6.507517 7.12238 -7.237373 1.9e-05 0.000269 0 0 0 <trigger> 90 -21.330655 6.507494 7.122384 -57.237378 1.6e-05 0.000266 0 0 0 <trigger> 90 178.669361 6.507496 7.122389 42.762633 9e-06 0.00027 0 0 0
You may notice the ulna block being the wrist block, but with changed basepos and rotational values of the procedural bone in all triggers.


If you feel like your procedurals are not precise enough, you can add more triggers.
Instead of three triggers you could have five triggers (base, 50% -, 100% -, 50% +, 100% +).
Additional triggers in between are usually not required, but maybe you might need it.
What to do with the keyframes
Congratulations, you now have kept the helper bone poses. You may jump between frames using the left and right arrow keys, allowing you to alter the poses and gather new data without having to redo the entire pose.

If you want, you can keep this "animation" forever in your blender save. You don't need to though.
For this, swap the Dope sheet to "Action Editor"


You may need to scroll to the right, by hovering over the controls of the dope sheet and scrolling your wheel, until you get to the text box. Name this thing VRD.


You can now just scroll back to frame 0 to go back to your ref pose.
You can also disable "Auto Keying", and press the little X next to the VRD action name to drop the animation from selection.


Now you can come back to this at any point.
Granted, if you have a proportion trick going on and you move the entire proportions, you will need to redo all of this from scratch.
43 Comments
Tubby Hill 31 Mar @ 1:16pm 
that's why I was asking you, I don't know how do get it to work without it failing to compile. "ERROR: Missing control bone "rotor" for procedural bone "Valvebiped.Bip01_Head1" The bone is in the dmx files for the model, and the helper and controller names are in the right places in the VRD. The rotor bone is parented to the pelvis, and the head bone is parented to the neck, which is parented to the spine bones, which are parented to the pelvis.
мяFunreal  [author] 31 Mar @ 10:12am 
I've never tried it, but i think it should work.
Tubby Hill 31 Mar @ 5:43am 
is there a way to have the helper bone be controlled by a controller bone that's not parented to the same bone as the helper? for example: I have a helper bone parented to ValveBiped.bip01_spine, while the controller bone is ValveBiped.bip01_head1.
Tubby Hill 21 Jan @ 5:20am 
nvm, I was doing it on the decompiled version of the custom armature I made. works fine when using the original
мяFunreal  [author] 21 Jan @ 2:15am 
Well, I don't know what to tell you. Because it does work if everything would have been done correctly.
And i can't tell you where you messed up without seeing what you have done.

But my first guess is that you are making a player model that uses proportion trick.
For the proportion trick you need to pose the armature into a new pose.
So, I am guessing that you might not have "applied the pose as rest pose" so you were building your procedural bone data on some random pose that isn't its rest pose, which might make things look weird.
Tubby Hill 20 Jan @ 3:07pm 
i've done everything in this guide correctly, but my procedural bone is way off of it's original location. calculating its position in source with sourceops doesn't work.
мяFunreal  [author] 15 Jul, 2023 @ 4:46am 
1. if the bone is deleted upon compile, then it won't be in smf. but it should be there if it is compiled.

2. no, the <trigger> is always followed by a 90. you simply add more triggers where the rotation is just larger.
EmperorFaiz.rar 15 Jul, 2023 @ 4:07am 
Hey, got some questions.
1) Is it normal for the driver bone to be invisible in SFM? I can still select it on the viewport though. (I was testing)
2) So let's say, I want a driver bone to rotate to 150 degrees with 75 degrees in between. Should the triggers would look like these?

<trigger> 90 .... //reference
<trigger> 75 .... //driver bone at 75 degree
<trigger> 150 .... //driver bone at 150 degree
EmperorFaiz.rar 3 Jul, 2023 @ 7:04am 
Thanks.
мяFunreal  [author] 1 Jul, 2023 @ 3:55am 
The procedural bones should move if the control bone moves, no matter if the hand is rotated manually, or via some script.
But I haven't actually tested this.