• [TUTORIAL] Procedural bones in Source Engine (and Source Filmmaker)
    12 replies, posted
The changenotes for the 0.9.8.1 SFM update made me interested in procedural bones, and I was successful in figuring them out. This tutorial is aimed at everyone who wants to enhance their (or not) SFM characters. I assume that the reader is familiar with general Source character modelling. [B]What is a procedural bone?[/B] It's a special kind of bone that is animated by the 3D application's coding (this includes DCC apps and game engines). Hair, cloth, ragdolls, jigglebones, biceps or even full body movement like one that GTA IV's Naturalmotion Euphoria devilers -- all these things aren't the hard work of The Animator, they're being calculated by the framework that The Animator uses: 3DS Max's CAT, Euphoria, Bullet physics etc. "Procedural" means "calculated by a terrible lifeless machine like your PC". I'm going to clarify that 'bones' = 'joints', 'skeleton' = 'armature', 'binded' = 'skinned' = 'weigthed', etc. Every 3D app seems to have its own stupid ideas on how to name the same concept. Source Engine gives us different kinds of procedurals: ragdoll animation, $ikchain, $jigglebone (a rather dumb system but useful sometimes), and the $proceduralbones. We are going to talk about the latter. Let's start with an example: you, The Animator, always want the model's wrists/forearms to twist in a predefined way when the hand is begin rotated along the arm axis. Of course, you can animate the twist by hand. But why wouldn't let a computer do it since creative thinking is not involved? Source can do that! [MEDIA]http://www.youtube.com/watch?v=V_3aFLDmFj0[/MEDIA] Obviously, having Source animate that routine stuff speeds up your workflow! Now let's talk about how it's done. [B] VRD files overview[/B] Source uses special VRD files to set up such procedural bones that are included in the QC file. The Almighty Studiomdl then reads the VRD and stores the data in the MDL file, and the engine picks it up. Of course, the model needs to have these procedural bones, and the mesh must be skinned. Then Source will evaluate the helper's position and rotation based on the specified bones orientation. In this tutorial, we're going to enable procedural bones on everyone's beloved Femscout. She has her forearms skinned to hlp_forearm bones, and both the hlp_forearm and bip_hand are immediate children of bip_lowerArm (that's a requirement! also, I love this model! that's also a requierment!). You'd need to setup your model's skeleton the same way if you want these procedural things to work. [t]https://dl.dropboxusercontent.com/u/91422001/proc_tut/skinned.png[/t] Donwload the Femscout's source files from MaxOfS2D's website. Open the _femscout_high.qc file, and change the $modelname to something so that our expirements won't mess up the original model. [CODE]$modelname "player/hwm/femscout_with_helpers.mdl"[/CODE] Now navigate to line 48 in the QC file. [code] ... // $include wings.qci // SILLY // $proceduralbones femscout.vrd // BROKEN ... [/code] We're going to 'UNBRAKE' the femscout.vrd file. (BTW, Max, where did the video with a volumetric light and these wings go? It looked nice and the wings had a smooth "flap" sound!) Open that femscout.vrd file. What you're going to see won't amuse you at first... [code] <helper> hlp_forearm_L bip_lowerArm_L bip_lowerArm_L bip_hand_L <basepos> -9.99201e-016 -4.75779 -1.77636e-015 <trigger> 90 -1.09332e-015 3.97569e-016 1.59028e-015 0 0 0 0 0 0 <trigger> 90 0 89 0 0 65 0 0 0 0 <trigger> 90 0 -89 0 0 -65 0 0 0 0 <helper> hlp_forearm_R bip_lowerArm_R bip_lowerArm_R bip_hand_R <basepos> -1.02912e-005 4.75777 -9.37782e-006 <trigger> 90 -1.98785e-016 0 0 0 0 0 0 0 0 <trigger> 90 0 89 0 0 65 0 0 0 0 <trigger> 90 0 -89 0 0 -65 0 0 0 0 [/code] That looks like a big WTFy mess of random numbers, but it's actually a simple keyframed animation, 'trigger" being 'keyframe'. Let's take a close look at every line: [code]<helper> hlp_forearm_L bip_lowerArm_L bip_lowerArm_L bip_hand_L[/code] This line tells Source that 1) we want a procedural bone hlp_forearm_l 2) it's parented to bip_lowerArm_L 3) the coordinate origin is bip_lowerArm_L, too 4) it's going to be controlled by bip_hand_L's rotation [code] <basepos> -9.99201e-016 -4.75779 -1.77636e-015 [/code] That is a 3D translation vector that tells Source the 'rest' translation of the helper bone (hlp_forearm) in the parent bone (bip_lowerArm_L)'s coordinate system is (-9.99201e-016, -4.75779, -1.77636e-015) along X, Y, Z respectively. <trigger> is essentialy a keyframe! It will make more sense if we brake down the line [code]<trigger> 90 -1.09332e-015 3.97569e-016 1.59028e-015 0 0 0 0 0 0[/code] like this [code] // Angle of influence (AoI) Specified control bone rotation (RotC) Desired helper rot (axis angles) (RotH) Desired helper translation from basepos (TransH) <trigger> 90 -1.09332e-015 3.97569e-016 1.59028e-015 0 0 0 0 0 0 [/code] What we're telling the engine is that when control bone rotaton (bip_hand) starts to aprroach RotC (is 'within' AoI) we want the helper to start approaching RotH rotation and TransH translation. The engine will then watch the control's rotation (RotC) and interpolate (lerp if this tells you anything) the helper's transform towards RotH and TransH. How to visualize the agnle of influence: draw an angle of AoI degrees, bisect it and rotate it around the bisect 180 degrees. You just got a cone! Everything that's inside the cone is within the AoI. The first trigger/keyframe is the rest position, the model's default state (it approches the default state when you drag the Defaukt slider in SFM). We don't want the helper to be rotated ort translated if everything is OK. The second is the 'extreme' for the hand twisted left, and the third is the 'extreme' for the right twist. If the hand is twisted right, twist the helper right, and vice versa. Don't move the helper. Let's take one final look at the left forearm helper definition with comments: [code] // Declare a procedural bone for left forearm // Bone name Parent bone name Coordinate system origin Control bone name <helper> hlp_forearm_L bip_lowerArm_L bip_lowerArm_L bip_hand_L // Declare base translation of the helper (in parent's coordinate system) // X Y Z <basepos> -9.99201e-016 -4.75779 -1.77636e-015 // AoI = Angle of influence // RotC = Specified control bone rotation, // RotH = Desired helper rotation when control bone rotation approaches RotC // TransH = Desired helper translation when control bone rotation approaches RotC // All angles are in XYZ degrees // AoI RotC RotH TransH // 'Rest' position <trigger> 90 -1.09332e-015 3.97569e-016 1.59028e-015 0 0 0 0 0 0 // Left twist extreme <trigger> 90 0 89 0 0 65 0 0 0 0 // Right twist extreme <trigger> 90 -89 0 0 -65 0 0 0 0 0 [/code] Hopefully, this explains how this system works. Exercise: is [code] <helper> hlp_forearm_R bip_lowerArm_R bip_lowerArm_R bip_hand_R <basepos> -1.02912e-005 4.75777 -9.37782e-006 <trigger> 90 -1.98785e-016 0 0 0 0 0 0 0 0 <trigger> 90 0 89 0 0 65 0 0 0 0 <trigger> 90 0 -89 0 0 -65 0 0 0 0 [/code] and this [code] <helper> hlp_forearm_R bip_lowerArm_R bip_lowerArm_R bip_hand_R <basepos> 0 0 0 <trigger> 90 -1.98785e-016 0 0 0 0 0 -1.02912e-005 4.75777 -9.37782e-006 <trigger> 90 0 89 0 0 65 0 -1.02912e-005 4.75777 -9.37782e-006 <trigger> 90 0 -89 0 0 -65 0 -1.02912e-005 4.75777 -9.37782e-006 [/code] the same thing? Ok, now why this VRD doesn't work, or, as the French people say (in a very loud voice), BROKEN? You've probably guessed alre
Dude. This is gold.
God!
&#1063;&#1077;&#1083; , &#1090;&#1099; &#1084;&#1086;&#1085;&#1089;&#1090;&#1088; :D
Awesome! You should go write a wiki article about it on the VDC, I believe VRDs have never been documented before
[QUOTE=VincentS.Tom;41686132]&#1063;&#1077;&#1083; , &#1090;&#1099; &#1084;&#1086;&#1085;&#1089;&#1090;&#1088; :D[/QUOTE] remember - no russian
[QUOTE=DP Films;41686312]remember - no russian[/QUOTE] LOOK OUT, HE'S ARMED!
[QUOTE=MaxOfS2D;41686153]Awesome! You should go write a wiki article about it on the VDC, I believe VRDs have never been documented before[/QUOTE] [URL="http://forums.steampowered.com/forums/showthread.php?t=2740392"]They have been[/URL], but mine's better, 'cause keyframes, how to do it for any model and no Softimage Mod Tool, SFM only. WHY COULDNT I FIND THIS THREAD EARLIER THOUGH, I SPENT AN HOUR IN GOOGLE
Pardon me for replying to a 5 year old thread. And i don't count on getting a response. First trigger is for right turning extreme Second trigger if for left turning extreme. Third trigger is for what? I'm going through the trouble of learning this for an SFM short. And i'd like to know these kinds of things when possible
Hello again. Your first keyframe is the rest position. Your second is a twist either right or left. Doesn't really matter which. Your third is just a keyframe in the opposite direction as the second. Preferably twisted by the same amount. There isn't a limit on the number of keyframes but it tries to blend between all of them at a time so I wouldn't recommend going over the initial three.
adsadsad Okay, now that makes better sense. I still haven't had luck with getting the numbers right though. My main problem is i'm not entirely sure what the parameters should be relative to. Basepos "i think" is relative to the parent bone, in my case the elbow. Should the rotational values for the forearm and hand also be relative to the elbow? Or relative to the world? Or relative to their rest pose. It also doesn't help that i think blender "my 3d program" i think shows it's XYZ differently than in source. I'm not entirely sure. But would anyone kno a reliable way to get the correct numbers for bones in source?
When you think about it this just goes to show how fucking aged Source is when something that is such a "duh" standard in literally every animation tool these days (see: HumanIK in Maya/MoBu, CAT in Max, literally any modern game engine) requires like straight-up coding in Source
thread old. My problem is new
Sorry, you need to Log In to post a reply to this thread.