Just to add some more light to it.
The easiest (and cheapest) way to make Source models is with Blender, using the Blender Source Tools extension.
Valve dev wiki link to it
For older versions of Source, everything is made in SMD models (This includes animations, too). Only vertex animation and QC files are not SMD files. Modern Source uses DMX files.
For an example of how a QC functions. Just look at this snippet of code I used on the Porygon-Z model. Stuff in Bold is not apart of the code, and is just rules to help understand how QCs work.
$modelname "Porygon_z.mdl"
(This is the model name when compiled. Can cause issues when changed without a recompile)
$bodygroup "PRGZ"
(This is the model SMD itself. It just references the SMD)
{
studio "porygon_z_reference.smd"
}
$cdmaterials "models\porygon_z\"
(This is where to tell Source to find textures under the game's "materials" folder.)
$texturegroup "skinfamilies"
(These are settings for texture changing. Source has a hard-coded 32-texture limit per model, though)
{
{
"body.vmt"
"eye.vmt"
}
{
"bodyshiny.vmt"
"eyeshiny.vmt"
}
}
$surfaceprop "metal"
(This is the sound/visual effect used when the model is hit/moves around)
$contents "solid"
(This refers to how Source will handle the model's collision)
$eyeposition 0 0 70
(This provides the eye rotation position. Didn't bother to add eye textures on the model, so it was rendered unused. Shouldn't of done that)
$sequence "ragdoll" "porygon_z_anims\ragdoll.smd" {
fps 30
"ACT_DIERAGDOLL" 1
}
(This is the model's animations. Multiple animations can be provided. But are capped at 30 FPS)
$collisionjoints "porygon_z_physics.smd"
{
$mass 15
$inertia 10
$damping 0.05
$rotdamping 5
$jointconstrain "Tail" x limit 0 0 0
$jointconstrain "Tail" y limit 0 0 0
$jointconstrain "Tail" z limit 0 0 0
$jointconstrain "RArm" x limit 0 0 0
$jointconstrain "RArm" y limit 0 0 0
$jointconstrain "RArm" z limit 0 0 0
$jointconstrain "EndRArm" x limit 0 0 0
$jointconstrain "EndRArm" y limit 0 0 0
$jointconstrain "EndRArm" z limit 0 0 0
$jointconstrain "EndTail" x limit 0 0 0
$jointconstrain "EndTail" y limit 0 0 0
$jointconstrain "EndTail" z limit 0 0 0
$jointconstrain "LArm" x limit 0 0 0
$jointconstrain "LArm" y limit 0 0 0
$jointconstrain "LArm" z limit 0 0 0
$jointconstrain "EndLArm" x limit 0 0 0
$jointconstrain "EndLArm" y limit 0 0 0
$jointconstrain "EndLArm" z limit 0 0 0
$jointconstrain "Head" x limit 0 0 0
$jointconstrain "Head" y limit 0 0 0
$jointconstrain "Head" z limit 0 0 0
}
(This is the model's physics hitbox. Used for ragdoll collision and whatnot. It's best to keep these models far lower poly than the actual model to reduce lag)