DigitalEro Offline

Quick and dirty Titanfall model porting tutorial

Tue, 25 Mar 2014 09:14:37

Ganonmaster

How to get Titanfall models into Source Filmmaker. Quick and dirty tutorial. Post a comment if something doesn't make sense. Tools used [list:gcvlq61o][*:gcvlq61o]Cra0kalo's VPK Tool[/*:m:gcvlq61o] [*:gcvlq61o]VTFEdit or Photoshop/GIMP with VTF plugin[/*:m:gcvlq61o] [*:gcvlq61o]Crowbar[/*:m:gcvlq61o] [*:gcvlq61o]Notepad++[/*:m:gcvlq61o] [*:gcvlq61o]Source Filmmaker[/*:m:gcvlq61o][/list:u:gcvlq61o] Step 1: Extract the materials and model folders from the VPK files [youtube:gcvlq61o]UclhtkshOCo[/youtube:gcvlq61o] Step 2: Copy the materials and models folder into their respective counterparts in the usermod directory of you SFM installation I feel this doesn't need any more explanation. Step 3: Open up one of the models in Source Filmmaker If it works, that's where the tutorial stops. If it doesn't, keep reading... Step 4: Decompile the model using Crowbar Open up Crowbar and pick the model you want in the MDL File field. You can keep the default settings. Make note of the output location, because you'll need it for the next steps. When done, hit "Decompile MDL" It should be decompiling the model. Sample output:
Decompiling...

Decompiling ".\pilot_female_br.mdl"...

  Reading data...
    Checking for required files...
    Reading mdl file header...
    ...Reading mdl file header finished.
    ...All required files found.
    Reading phy file...
    ...Reading phy file finished.
    Reading mdl file...
    ...Reading mdl file finished.
    Reading vtx file...
    ...Reading vtx file finished.
    Reading vvd file...
    ...Reading vvd file finished.
  ...Reading data finished.
  Writing data...
    Writing qc file...
    ...Writing qc file finished.
    Writing reference and lod mesh files...
    ...Writing reference and lod mesh files finished.
    Writing physics mesh file...
    ...Writing physics file mesh finished.
  ...Writing data finished.

...Decompiling ".\pilot_female_br.mdl" finished.

...Decompiling finished.
Step 5: Change the QC file and re-compile Navigate to the output folder. You should be seeing something like this: First things first. You can delete any of the files that end with lod1, lod2 or lod3, unless you want to keep the lower levels of detail. Next, open the QC file in Notepad++. Here's a sample file:
// Created by Crowbar 0.19.0.0

$modelname "humans/pilot/female_br/pilot_female_br.mdl"

$bodygroup "mri"
{
	blank
	studio "pilot_female_br_w_pete_mri.smd"
}
$bodygroup "body"
{
	studio "pilot_female_br_body_lod0.smd"
}
$bodygroup "head"
{
	studio "pilot_female_br_head_a_lod0.smd"
	studio "pilot_female_br_head_b_lod0.smd"
}
$bodygroup "jumpkit"
{
	studio "pilot_female_br_jumpkit_lod0.smd"
}

$lod 40
{
	replacemodel "pilot_female_br_.smd" "pilot_female_br__lod1.smd"
}
$lod 55
{
	replacemodel "pilot_female_br_.smd" "pilot_female_br__lod2.smd"
}
$lod 65
{
	replacemodel "pilot_female_br_.smd" "pilot_female_br__lod3.smd"
}

$cdmaterials "models\humans\titan_pilots\battle_rifle_imc_female_pilot\"
$cdmaterials "models\humans\titan_pilots\battle_rifle_mcor_female_pilot\"
$cdmaterials "models\humans\titan_jockey_gear\jumpkit\"

$texturegroup "skinfamilies"
{
	{
		"pilot_imc_f_body_brp_a_urb.vmt"
		"pilot_imc_f_gear_brp_a_urb.vmt"
	}
	{
		"pilot_mcor_f_body_brp_a_urb.vmt"
		"pilot_mcor_f_gear_brp_a_urb.vmt"
	}
}

// Model uses material "models\humans\mri\mri_male_v1\mri_male_v1.vmt"
// Model uses material "pilot_imc_f_body_brp_a_urb.vmt"
// Model uses material "pilot_imc_f_gear_brp_a_urb.vmt"
// Model uses material "pilot_mcor_f_body_brp_a_urb.vmt"
// Model uses material "pilot_mcor_f_gear_brp_a_urb.vmt"
// Model uses material "pilot_imc_f_helmet_brp_a_urb.vmt"
// Model uses material "pilot_mcor_f_helmet_brp_a_urb.vmt"
// Model uses material "imc_jumpkit_a_urb.vmt"

$attachment "OFFSET" "jx_c_delta" 0 0 0 rotate -90 -90 0
$attachment "REF" "jx_c_start" 0 0 0 rotate -90 -90 0
$attachment "HEADFOCUS" "def_c_neckB" 0 0 0 rotate -90 -90 0
$attachment "HEADSHOT" "def_c_head" 0 0 0 rotate -90 -90 0
$attachment "CHESTFOCUS" "def_c_spineC" 0 0 0 rotate -90 -90 0
$attachment "PROPGUN" "ja_c_propGun" 0 0 0 rotate -90 -90 0
$attachment "VDU" "jx_c_camera" 0 0 0 rotate -90 -90 0
$attachment "L_HAND" "ja_l_propHand" 0 0 0 rotate 0 0 0
$attachment "R_HAND" "ja_r_propHand" 0 0 0 rotate 0 0 0
$attachment "ORIGIN" "jx_c_delta" 0 0 0 rotate -90 -90 0
$attachment "foot_L_sole" "def_l_ankle" 0 0 0 rotate 0 0 0
$attachment "foot_R_sole" "def_r_ankle" 0 0 0 rotate 0 0 0
$attachment "FLAG" "def_c_spineC" 12 -20 -8 rotate 0 15 -90
$attachment "vent_right_back" "def_c_hip" -5.99 0.9 -10.15 rotate 90 46 0
$attachment "vent_left_back" "def_c_hip" 5.99 0.9 -10.15 rotate 90 -46 0
$attachment "vent_right" "def_c_hip" -5.65 5.2 -7.75 rotate 6.83 -99.97 -145.9
$attachment "vent_left" "def_c_hip" 6.03 5.18 -7.76 rotate 6.83 -80.03 -34.09
$attachment "vent_right_out" "def_c_hip" -5.65 5.2 -7.75 rotate 31.61 -152.77 -164.9
$attachment "vent_left_out" "def_c_hip" 6.03 5.18 -7.76 rotate 31.61 -27.23 -15.09

$surfaceprop "flesh"

$contents "solid"

$eyeposition 0 0 64

// Only set this if you know what it does, and need it for special circumstances, such as with gibs.
// $illumposition 0 0 0

// $bbox 0 0 0 0 0 0

// $cbox is probably not used anymore
// $cbox 0 0 0 0 0 0

$hboxset "default"
$hbox 1 "def_c_head" -3.982669 -3.10708 -5.731091 3.982669 6.545656 4.677943
$hbox 2 "def_c_neckA" -2.537003 -0.029134 -2.432672 2.537003 1.337005 3.101568
$hbox 2 "def_c_spineC" -6.705893 0 -5.230305 6.705893 9.785808 5.049202
$hbox 3 "def_c_hip" -7.545654 -3.373222 -5.146446 7.545654 0.889368 5.146446
$hbox 3 "def_c_spineA" -6.924789 0 -5.146446 6.924789 7.326757 5.146446
$hbox 3 "def_c_spineB" -6.705893 0 -5.104714 6.705893 5.08503 5.104714
$hbox 4 "def_l_shoulder" -1.968894 -1.592517 -1.661808 11.015332 1.592517 1.661808
$hbox 4 "def_l_elbow" 0 -1.592517 -1.670469 8.980691 1.592517 1.653146
$hbox 4 "def_l_wrist" -0.312598 -1.597241 -1.648816 5.555107 0.635826 1.704327
$hbox 5 "def_r_shoulder" -10.927931 -1.592517 -1.661808 2.056295 1.592517 1.661808
$hbox 5 "def_r_elbow" -8.980297 -1.592517 -1.653146 0 1.592123 1.670469
$hbox 5 "def_r_wrist" -5.555501 -0.635826 -1.704327 0.312991 1.597635 1.648422
$hbox 6 "def_l_thigh" 0 -3.081884 -2.94527 15.393669 3.081884 2.94527
$hbox 6 "def_l_knee" 0 -2.875585 -3.064955 16.67477 2.875585 3.064955
$hbox 6 "def_l_ankle" -2.515743 -2.058657 -1.977555 3.28897 2.058657 1.977555
$hbox 6 "def_l_ball" -1.376769 -0.181889 -1.977555 3.501174 3.935031 1.977555
$hbox 7 "def_r_thigh" -15.393669 -3.081884 -2.94527 0 3.081884 2.94527
$hbox 7 "def_r_knee" -16.67477 -2.875585 -3.064955 0 2.875585 3.064955
$hbox 7 "def_r_ankle" -3.28897 -2.058657 -1.977555 2.515743 2.058657 1.977555
$hbox 7 "def_r_ball" -3.501174 -3.938181 -1.977555 1.376769 0.179134 1.977555


$includemodel "humans/pilot/female_cq/female_core.mdl"
$includemodel "humans/pilot/female_cq/female_reactions.mdl"
$includemodel "humans/pilot/female_cq/female_scripted.mdl"
$includemodel "humans/pilot/female_cq/female_poses.mdl"
$includemodel "humans/pilot/female_cq/female_skits.mdl"
$includemodel "humans/pete/human_male_anims_workspace.mdl"

$collisionjoints "pilot_female_br_physics.smd"
{
	$mass 0
	$inertia 1
	$damping 1
	$rotdamping 4


	$jointconstrain "def_r_thigh" x limit -35 10 0.2
	$jointconstrain "def_r_thigh" y limit -10 -5 0.2
	$jointconstrain "def_r_thigh" z limit 10 70 0.2

	$jointmassbias "def_r_knee" 2
	$jointconstrain "def_r_knee" x limit 0 0 0.2
	$jointconstrain "def_r_knee" y limit 0 0 0.2
	$jointconstrain "def_r_knee" z limit -70 -10 0.2

	$jointconstrain "def_l_thigh" x limit -35 10 0.2
	$jointconstrain "def_l_thigh" y limit -10 -5 0.2
	$jointconstrain "def_l_thigh" z limit 10 70 0.2

	$jointmassbias "def_l_knee" 2
	$jointconstrain "def_l_knee" x limit 0 0 0.2
	$jointconstrain "def_l_knee" y limit 0 0 0.2
	$jointconstrain "def_l_knee" z limit -70 -10 0.2

	$jointmassbias "def_l_ankle" 3
	$jointconstrain "def_l_ankle" x limit -5 -5 0.2
	$jointconstrain "def_l_ankle" y limit -5 5 0.2
	$jointconstrain "def_l_ankle" z limit -5 5 0.2

	$jointconstrain "def_c_spineB" x limit -5 12.5 0.2
	$jointconstrain "def_c_spineB" y limit -12.5 12.5 0.2
	$jointconstrain "def_c_spineB" z limit -10 10 0.2

	$jointconstrain "def_r_shoulder" x limit -70 15 0.2
	$jointconstrain "def_r_shoulder" y limit -97 23 0.2
	$jointconstrain "def_r_shoulder" z limit -10 92 0.2

	$jointmassbias "def_r_elbow" 2
	$jointconstrain "def_r_elbow" x limit 0 0 0.2
	$jointconstrain "def_r_elbow" y limit -60 40 0.2
	$jointconstrain "def_r_elbow" z limit 0 0 0.2

	$jointconstrain "def_l_shoulder" x limit -70 15 0.2
	$jointconstrain "def_l_shoulder" y limit -97 23 0.2
	$jointconstrain "def_l_shoulder" z limit -10 92 0.2

	$jointmassbias "def_l_elbow" 2
	$jointconstrain "def_l_elbow" x limit 0 0 0.2
	$jointconstrain "def_l_elbow" y limit -60 40 0.2
	$jointconstrain "def_l_elbow" z limit 0 0 0.2

	$jointmassbias "def_l_wrist" 2
	$jointconstrain "def_l_wrist" x limit -37.5 37.5 0.2
	$jointconstrain "def_l_wrist" y limit -7.5 15 0.2
	$jointconstrain "def_l_wrist" z limit -37.5 37.5 0.2

	$jointconstrain "def_c_neckB" x limit -20 20 0.2
	$jointconstrain "def_c_neckB" y limit -25 25 0.2
	$jointconstrain "def_c_neckB" z limit -12.5 12.5 0.2

	$jointmassbias "def_r_wrist" 2
	$jointconstrain "def_r_wrist" x limit -37.5 37.5 0.2
	$jointconstrain "def_r_wrist" y limit -7.5 15 0.2
	$jointconstrain "def_r_wrist" z limit -37.5 37.5 0.2

	$jointmassbias "def_r_ankle" 3
	$jointconstrain "def_r_ankle" x limit -5 5 0.2
	$jointconstrain "def_r_ankle" y limit -5 5 0.2
	$jointconstrain "def_r_ankle" z limit -5 5 0.2
}

$collisiontext
{
	animatedfriction 
	{
		"animfrictionmin" "0.000000"
		"animfrictionmax" "300.000000"
		"animfrictiontimein" "1.000000"
		"animfrictiontimeout" "1.000000"
		"animfrictiontimehold" "1.000000"
	}
	editparams 
	{
		"rootname" "def_c_hip"
		"totalmass" "100.000000"
		"jointmerge" "def_c_hip,jx_c_delta"
	}
}

$bonemerge "jx_c_delta"
$bonemerge "jx_c_pov"
$bonemerge "jx_c_camera"
$bonemerge "jx_c_start"
$bonemerge "def_c_hip"
$bonemerge "def_c_spineA"
$bonemerge "def_c_spineB"
$bonemerge "def_c_spineC"
$bonemerge "def_c_neckA"
$bonemerge "jx_c_neckB"
$bonemerge "def_c_neckB"
$bonemerge "def_c_head"
$bonemerge "def_l_clav"
$bonemerge "def_l_shoulder"
$bonemerge "def_l_shoulderTwist"
$bonemerge "def_l_elbowB"
$bonemerge "def_l_shoulderMid"
$bonemerge "def_l_elbow"
$bonemerge "def_l_forearm"
$bonemerge "def_l_wrist"
$bonemerge "ja_l_propHand"
$bonemerge "def_l_finThumbA"
$bonemerge "def_l_finThumbB"
$bonemerge "def_l_finThumbC"
$bonemerge "def_l_finIndexA"
$bonemerge "def_l_finIndexB"
$bonemerge "def_l_finIndexC"
$bonemerge "def_l_finMidA"
$bonemerge "def_l_finMidB"
$bonemerge "def_l_finMidC"
$bonemerge "def_l_finRingCarpal"
$bonemerge "def_l_finRingA"
$bonemerge "def_l_finRingB"
$bonemerge "def_l_finRingC"
$bonemerge "def_l_finPinkyA"
$bonemerge "def_l_finPinkyB"
$bonemerge "def_l_finPinkyC"
$bonemerge "ja_c_propGun"
$bonemerge "def_r_clav"
$bonemerge "def_r_shoulder"
$bonemerge "def_r_shoulderTwist"
$bonemerge "def_r_elbowB"
$bonemerge "def_r_shoulderMid"
$bonemerge "def_r_elbow"
$bonemerge "def_r_forearm"
$bonemerge "def_r_wrist"
$bonemerge "ja_r_propHand"
$bonemerge "def_r_finThumbA"
$bonemerge "def_r_finThumbB"
$bonemerge "def_r_finThumbC"
$bonemerge "def_r_finIndexA"
$bonemerge "def_r_finIndexB"
$bonemerge "def_r_finIndexC"
$bonemerge "def_r_finMidA"
$bonemerge "def_r_finMidB"
$bonemerge "def_r_finMidC"
$bonemerge "def_r_finRingCarpal"
$bonemerge "def_r_finRingA"
$bonemerge "def_r_finRingB"
$bonemerge "def_r_finRingC"
$bonemerge "def_r_finPinkyA"
$bonemerge "def_r_finPinkyB"
$bonemerge "def_r_finPinkyC"
$bonemerge "def_l_thigh"
$bonemerge "def_l_kneeB"
$bonemerge "def_l_knee"
$bonemerge "def_l_ankle"
$bonemerge "def_l_ball"
$bonemerge "def_r_thigh"
$bonemerge "def_r_kneeB"
$bonemerge "def_r_knee"
$bonemerge "def_r_ankle"
$bonemerge "def_r_ball"


$keyvalues
{
	teamSkin 
	{
	}
}
Now, this is all nice and good, but it's way more information than we really need. You can cut this down to the following if you want:
$modelname "humans/pilot/female_br/pilot_female_br.mdl"

$model body "pilot_female_br_body_lod0.smd"

$bodygroup "jumpkit"
{
	studio "pilot_female_br_jumpkit_lod0.smd"
}
$bodygroup "head"
{
	studio "pilot_female_br_head_a_lod0.smd"
	studio "pilot_female_br_head_b_lod0.smd"
}

$cdmaterials "models\humans\titan_pilots\battle_rifle_imc_female_pilot\"
$cdmaterials "models\humans\titan_pilots\battle_rifle_mcor_female_pilot\"
$cdmaterials "models\humans\titan_jockey_gear\jumpkit\"

$sequence idle	"pilot_female_br_body_lod0.smd"
Notice the lines I preserved and changed. The $cdmaterials are unedited, as are the jumpkit and head bodygroups. However, I changed the body to a $model, and added a sequence in there. Those two are required for the model to work properly. I know this part might be confusing, but I simply don't have the time to type out what everything does. Use your best judgement and read the documentation on QC files if you need more help. Now you're ready to compile your model. Go to the Source Filmmaker directory and open the /bin folder. (usually located at C:\Program Files (x86)\Steam\steamapps\common\sourcefilmmaker\game\bin) Look for a file named studiomdl.bat. Now drag and drop your QC file onto studiomdl.bat. A console window should now open, and text and number are flying over the screen! Whoaa! Wait for the program to finish and close the window when it's done. If you get an error during this process, you probably have made a mistake with your QC file. If it compiles, check to see if it works! Step 6: Convert Normal maps (optional) Some models have normal map textures with some kind of strange compression that SFM doesn't understand. These are VTF files usually ending in _nml.vtf. You can test them by opening them with VTFEdit. If they don't load in VTFEdit and return an error, you probably need to convert them. The fix is included in the Titanfall VPK tools. Open up the program, go to Tools > ATI2NormalTool. In the next Window, pick TGA, and drag the VTF file onto the window. Note that it creates a TGA file in the same folder, next to the VTF file. Open the TGA file in VTFEdit. You can do this by hitting File > Import... in VTFedit. A new window pops up with options. If you don't know what they do, you can leave them as is and they'll probably be fine. Now save the file as a VTF and overwrite the old VTF file. That fixes your normal maps.
Tue, 25 Mar 2014 16:51:17

Soul

Thanks for doing this, Ganon. Everything works perfectly now.
Sun, 06 Apr 2014 00:50:05

bbbufo

So here's the thing... I cant open any custom models in SFM, everytime i try to do so, it just crashes, no error, nothing, just shuts itself down. ive been trying to convert the files following this tutorial, and when trying to compile the QC. files through studiomdl, after a while when everythign seems to run smoothly, studiomdl just shuts itself as well, with the QC. file remaining as it was. :????:
Sun, 06 Apr 2014 02:32:42

Ganonmaster

"bbbufo" said ...
files through studiomdl, after a while when everythign seems to run smoothly, studiomdl just shuts itself as well, with the QC. file remaining as it was. :????:
What does your QC file look like? Does StudioMDL give any error messages?
Sun, 06 Apr 2014 13:37:36

bbbufo

no it doesnt, it just keeps chewing the file, then it shuts down :/
Sun, 06 Apr 2014 18:08:49

Ganonmaster

What does your QC file look like.