This article's documentation is for the "GoldSrc" engine. Click here for more information.
This article's documentation is for anything that uses the Source engine. Click here for more information.

SMD: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
mNo edit summary
m (Setting bug notice hidetested=1 param on page where the bug might not need tested in param specified)
 
(55 intermediate revisions by 10 users not shown)
Line 1: Line 1:
{{toc-right}}
{{LanguageBar}}
{{gldsrc topicon}}{{src topicon}}{{toc-right}}
{{stub}}
:''SMD has been superseded in {{src|1}} and {{src2|1}} by the [[DMX model]] format.''


:''SMD has been superseded by the [[DMX model]] format.''
The '''SMD''' file format (short for '''StudioModel Data''') stores 3D models in [[Wikipedia:ASCII|ASCII]] for analysis and compilation by [[studiomdl]]. SMD files are usually generated by an [[SMD export]] plug-in for a given [[model editor]] package like MilkShape.


The '''Studiomdl Data''' file format stores 3D models in [[Wikipedia:ASCII|ASCII]] for analysis and compilation by [[studiomdl]]. SMD files are usually generated by an [[SMD export]] plug-in for a given [[model editor]] package like MilkShape.
{{note|
* SMD files which are used for [[vertex animation]] or [[flex animation]] are usually given a '''VTA''' file extension. VTA files never have a {{mono|triangles}} block.
* {{src06|since}} SMD files can also use the '''SMA''' or '''PHYS''' file extensions.
}}


Aside from Source and GoldSrc, SMD is known to be used by [[W:Cube 2: Sauerbraten|Sauerbraten]] and third party tools for [[W:The Sims (series)|The Sims]] and [[W:Mount & Blade|Mount & Blade]].
== Software ==
Aside from {{Source|4}} and {{gldsrc|4}}, SMD is known to be used by [[W:Cube 2: Sauerbraten|Sauerbraten]] and third party tools for [[W:The Sims (series)|The Sims]] and [[W:Mount & Blade|Mount & Blade]].
It is also optionally used by the {{quakewiki|FTEQW_IQM_Tool_Documentation|FTE IQM Tool}}, used to create skeletal [[MDL (Quake)#Others|IQM]] models used by various {{Idtech2|4}} and {{idtech3|4}} source ports.


== General notes ==
== General notes ==


* X is north in SMD. Elsewhere in Source [[Coordinates|it is east]].
* X is north in SMD. Elsewhere in Source [[Coordinates|it is east]].
* The format is carriage return sensitive: Linux-based text editors should use CR or CRLF line terminators instead of just LF. each command must be on a separate line. There should also be a single blank line at the end (and only the end) of the file.
* The format is carriage return sensitive: text editors should use {{code|CR}} (Mac) or {{code|CRLF}} (Windows) line terminators instead of just {{code|LF}} (Linux). Each command must be on a separate line. There should also be a single blank line at the end (and only the end) of the file.
* White space is the only delimiter: any combination of tabs and spaces can be used to separate values, and for this reason multiword names should be enclosed in "quotation marks". {{bug|Avoid using tab. Its presence can crash studiomdl in very large SMDs.}}
* White space is the only delimiter: any combination of tabs and spaces can be used to separate values, and for this reason multiword names should be enclosed in "quotation marks". {{bug|hidetested=1|Avoid using tab. Its presence can crash studiomdl in very large SMDs.}}
* Stand-alone line comments start with '''//''' (double foreslash)
* Comments are '''''not''''' supported by {{gldsrc|2}} studiomdl.<br>For {{src|2}} studiomdl, the following comment delimiters can be used (but are likely to be stripped by 3D modeling programs):
* Emd-line comments start with '''#''' (hashtag) or ''';''' (semicolon)
** Stand-alone line comments start with '''//''' (double forward slash)
** End-line comments start with '''#''' (hashtag) or ''';''' (semicolon)


== Types ==
== Types ==
Line 19: Line 28:
;Reference / Collision
;Reference / Collision
:''A complete snapshot of the model, including one frame of animation to define the default pose. [[Collision mesh]]es follow the same pattern.''
:''A complete snapshot of the model, including one frame of animation to define the default pose. [[Collision mesh]]es follow the same pattern.''
:<code>[[#Header|header]]</code>
:<code>[[#Header|header ]]</code>
:<code>[[#Nodes|nodes]]</code>
:<code>[[#Nodes|nodes ]]</code>
:<code>[[#Skeleton|skeleton]]</code>
:<code>[[#Skeleton|skeleton ]]</code>
:<code>[[#Triangles|triangles]]</code>
:<code>[[#Triangles|triangles ]]</code>
; Animation
; Animation
: ''A single [[skeletal animation]].''
: ''A single [[skeletal animation]].''
:<code>[[#Header|header]]</code>
:<code>[[#Header|header ]]</code>
:<code>[[#Nodes|nodes]]</code>
:<code>[[#Nodes|nodes ]]</code>
:<code>[[#Skeleton|skeleton]]</code>
:<code>[[#Skeleton|skeleton ]]</code>
; Vertex
; Vertex {{src|only}}
: ''A [[flex animation]] library. Usually has extension <code>.vta</code>.''
: ''A [[flex animation]] library. Usually has extension <code>.vta</code>.''
:<code>[[#Header|header]]</code>
:<code>[[#Header|header ]]</code>
:<code>[[#Nodes|nodes]]</code>
:<code>[[#Nodes|nodes ]]</code>
:<code>[[#Skeleton|skeleton]]</code> (a "time <n>" header for each flex shape; no position data required)
:<code>[[#Skeleton|skeleton ]]</code> (a "time <n>" header for each flex shape; no position data required)
:<code>[[#Vertexanimation|vertexanimation]]</code>
:<code>[[#Vertexanimation|vertexanimation ]]</code>


== Data blocks ==
== Data blocks ==
Line 39: Line 48:
Here are the components of an SMD file, considered in order:
Here are the components of an SMD file, considered in order:


{{tip|Unless otherwise noted all [[integer]] values begin at 0 and all [[floating point]] values are limited to six decimal places.}}
{{tip|Unless otherwise noted, all [[integer]] values begin at 0 and all [[floating point]] values are limited to six decimal places. {{src|2}}'s StudioMDL supports floating point values being stored in scientific notation, but other engines and tools may not.}}


=== Header ===
=== Header ===
Line 46: Line 55:


  version 1
  version 1
{{todo|There are at least 3 versions; document their differences somewhere.}}


=== Nodes ===
=== Nodes ===
Line 51: Line 61:
A list of all the bones in the model.
A list of all the bones in the model.


{{note|Bones without attached vertices will not be compiled.}}
{{note|
* {{goldsrc}} Bones without attached vertices will not be compiled, unless using [[$keepallbones (GoldSrc)|$keepallbones]], [[$keepbone (GoldSrc)|$keepbone]], and/or [[$protected (GoldSrc)|$protected]]
* {{src}} {{confirm}} Bones without attached vertices aren't ''supposed'' to be removed, unless [[$collapsebones]]/[[$collapsebonesaggressive]] are used, but some versions of StudioMDL like {{gmod}} do anyway. Bones using [[$definebone]] or [[$bonemerge]] are never collapsed unless [[$alwayscollapse]] is used.}}


==== Syntax ====
==== Syntax ====
Line 84: Line 96:
; <code> <int|bone ID> <[[float]]|PosX PosY PosZ>  <float|RotX RotY RotZ> </code>
; <code> <int|bone ID> <[[float]]|PosX PosY PosZ>  <float|RotX RotY RotZ> </code>
: A bone's position relative to its parent (give absolute values in the case of root bones).
: A bone's position relative to its parent (give absolute values in the case of root bones).
:* <code>Pos</code> is position in [[unit]]s.
:* <code>Pos</code> is position in [[unit]]s relative to the parent bone.
:* <code>Rot</code> is local [[Wikipedia:Euler angles|Euler angles]], given in [[Wikipedia:Radian|radians]]. (90&deg; = 1.570796 rad)
:* <code>Rot</code> is local [[Wikipedia:Euler angles#Tait–Bryan_angles|Tait-Bryan angles]], given in [[Wikipedia:Radian|radians]] relative to the parent bone (90&deg; = 1.570796 rad)
:{{tip|The first frame must include all bones. After that, those which have not moved relative to their parent since the last frame can be omitted.}}
:{{note|In {{src}}, the first frame must include all bones. After that, those which have not moved relative to their parent since the last frame can be omitted.<br>Doing this in {{goldsrc}} resets the bone to its default position; all frames should have all bones. {{confirm|Default as in first frame, or default as in reference pose?}} }}
:{{tip|Converting from a local rotation matrix to [[Wikipedia:Euler angles|Euler angles]] might require you to invert the rotation matrix before conversion.}}
; <code>end</code>
; <code>end</code>
: Ends the data block.
: Ends the data block.
Line 114: Line 127:
; <code>triangles</code>
; <code>triangles</code>
: Begins the triangle block.
: Begins the triangle block.
; <code><material></code>
; <code><[[material]] ({{src}}) or [[texture]] ({{gldsrc}})></code>
: Defines the start of a new triangle and the material to apply to it. Anything after a '.' (e.g. a file extension) is ignored. Do not enclose in quotes and do not include a path ([[$cdmaterials]] will provide one).
: Defines the start of a new triangle and the material to apply to it.  
; <code><[[int]]|Parent bone> <[[float]]|PosX PosY PosZ> <[[normal]]|NormX NormY NormZ> <normal|U V> <int|links> <int|Bone ID> <normal|Weight> [...]</code>
: File extensions (anything after a ".") are ignored in {{src|2}}, but '''''must''''' be be {{code|[[bmp]]}} in {{gldsrc|4}}.
: Do not enclose in quotes and do not include a path ([[$cdmaterials]] ({{src}}) or [[$cdtexture]] ({{gldsrc}}) will provide one).
: {{warning|In {{src}} StudioMDL, any faces using a materials named "null.bmp", "null.tga", or "debug/debugempty" will be deleted!<br>This is ''not'' the case for {{GoldSrc}} StudioMDL; several vanilla {{dod}} models have materials named "null.bmp".}}
: {{note|In {{goldsrc}}, this should not exceed 63 characters (including the file extension).}}
; <code><[[int]]|Parent bone> <[[float]]|PosX PosY PosZ> <[[normal]]|NormX NormY NormZ> <[[float]]|U V> <int|links> <int|Bone ID> <[[float]]|Weight> [...]</code>
: Defines a [[vertex]].
: Defines a [[vertex]].
:* <code>Pos</code> is in world [[unit]]s
:* <code>Pos</code> is in world [[unit]]s
:* <code>Norm</code> is used to smooth the surface of the model (See: [http://en.wikipedia.org/wiki/Normal_%28geometry%29 Normal (geometry)])
:* <code>Norm</code> is the [[vertex normal]], dictating how sharp or smooth the geometry is shaded
:* U and V are the vertex's [[UV map]] co-ordinates
:* U and V are the vertex's [[UV map]] co-ordinates
: The final three values are optional: they override <code><Parent bone></code> to define a series of [[weightmap]] links. <code>Bone ID</code> and <code>Weight</code> are repeated for each link. If the weights do not add up to 1, any remaining value is placed on <code><Parent bone></code>. {{note|For SMDs included with [[$lod]], Studiomdl can determine a vertex's weight links by copying those of the closest [[reference mesh]] vertex.}}
: The final three values are only supported by {{src}}, where they are optional: they override <code><Parent bone></code> to define a series of [[weightmap]] links. <code>Bone ID</code> and <code>Weight</code> are repeated for each link. If the weights do not add up to 1, any remaining value is placed on <code><Parent bone></code>.
: {{note|For SMDs included with [[$lod]], Studiomdl can determine a vertex's weight links by copying those of the closest [[reference mesh]] vertex.}}
: {{note|SMD version 3 supports up to 8 additional UV layers after additional links. Format {{code|<[[int]]{{!}}extra uvs> U1 V1 U2 V2 [...]}}.<br>Nonetheless, the [[MDL]] formats used by both {{gldsrc|2}} and {{src|2}} only support a single set of UVs, except for {{csgo|2|nt=0}}, which uses a second set for [[$decaltexture]].}}
; <code>end</code>
; <code>end</code>
: Ends triangle block.
: Ends triangle block.
Line 130: Line 149:


  triangles
  triangles
  my_material
  my_texture.bmp
  0 0 0 0 0 0 1 0 1 1 0 1
  0 0 0 0 0 0 1 0 1 1 0 1
  0 0 -1 0 0 0 1 0 0 1 0 1
  0 0 -1 0 0 0 1 0 0 1 0 1
  1 1 -1 0 0 0 1 1 0 1 1 1
  1 1 -1 0 0 0 1 1 0 1 1 1
  my_material
  my_texture.bmp
  0 0 0 0 1 0 1 0 1 1 0 1
  0 0 0 0 1 0 1 0 1 1 0 1
  1 1 -1 0 1 0 1 1 0 1 1 1
  1 1 -1 0 1 0 1 1 0 1 1 1
  1 1 0 0 1 0 1 1 1 1 1 1
  1 1 0 0 1 0 1 1 1 1 1 1
  my_material
  my_texture.bmp
  1 1 -1 0 0 0 1 1 0 1 1 1
  1 1 -1 0 0 0 1 1 0 1 1 1
  0 0 -1 0 0 0 1 0 0 1 0 1
  0 0 -1 0 0 0 1 0 0 1 0 1
  0 0 0 0 0 0 1 0 1 1 0 1
  0 0 0 0 0 0 1 0 1 1 0 1
  my_material
  my_texture.bmp
  1 1 0 0 1 0 1 1 1 1 1 1
  1 1 0 0 1 0 1 1 1 1 1 1
  1 1 -1 0 1 0 1 1 0 1 1 1
  1 1 -1 0 1 0 1 1 0 1 1 1
Line 149: Line 168:


=== Vertexanimation ===
=== Vertexanimation ===
{{update|This can also be used to store discrete key frames, using [[vertex animation]] instead of [[flex animation]].}}
{{only|{{src|4.1}}}} Position of vertices in various morph targets, for use in [[vertex animation]] or [[flex animation]]. While this block uses the same <code>time</code> keyword as <code>[[#Skeleton|skeleton ↑]]</code>, each 'frame' is instead a discrete, static shape. Transitions between them are created on-demand by the engine.


Position of vertices in various morph targets, for use in [[flex animation]]. While this block uses the same <code>time</code> keyword as <code>[[#Skeleton|skeleton]]</code>, each 'frame' is instead a discrete, static shape. Transitions between them are created on-demand by the engine.
{{note|A <code>[[#Nodes|nodes ]]</code> and a <code>[[#Skeleton|skeleton ]]</code> block are needed in each VTA. The skeleton block needs only contain a "time <n>" header for each flex shape.}}
 
{{note|A <code>[[#Nodes|nodes]]</code> and a <code>[[#Skeleton|skeleton]]</code> block are needed in each VTA. The skeleton block needs only contain a "time <n>" header for each flex shape.}}


==== Syntax ====
==== Syntax ====
Line 162: Line 181:
; <code><int|ID> <[[float]]|PosX PosY PosZ> <[[normal]]|NormX NormY NormZ></code>
; <code><int|ID> <[[float]]|PosX PosY PosZ> <[[normal]]|NormX NormY NormZ></code>
: A vertex.  
: A vertex.  
:* ID is the position of the equivalent reference vertex in the <code>[[#Triangles|triangles]]</code> block
:* ID is the position of the equivalent reference vertex in the <code>[[#Triangles|triangles ]]</code> block
:* <code>Pos</code> is in absolute world [[unit]]s
:* <code>Pos</code> is in absolute world [[unit]]s
:* <code>Norm</code> defines the direction from which the vertex receives the most light
:* <code>Norm</code> defines the direction from which the vertex receives the most light
Line 168: Line 187:
: Ends the data block.
: Ends the data block.


[[Category:Plain text formats]]
[[Category:Plain text files]]
[[Category:Modeling]]
[[Category:Modeling]]
[[Category:File formats]]
[[Category:Glossary]]

Latest revision as of 07:13, 20 May 2025

English (en)Translate (Translate)

Stub

This article or section is a stub. You can help by expanding it.

SMD has been superseded in Source and Source 2 by the DMX model format.

The SMD file format (short for StudioModel Data) stores 3D models in ASCII for analysis and compilation by studiomdl. SMD files are usually generated by an SMD export plug-in for a given model editor package like MilkShape.

Note.pngNote:
  • SMD files which are used for vertex animation or flex animation are usually given a VTA file extension. VTA files never have a triangles block.
  • (in all games since Source 2006) SMD files can also use the SMA or PHYS file extensions.

Software

Aside from Source Source and GoldSrc GoldSrc, SMD is known to be used by Sauerbraten and third party tools for The Sims and Mount & Blade. It is also optionally used by the Quake1-16px.png FTE IQM Tool, used to create skeletal IQM models used by various id Tech 2 id Tech 2 and id Tech 3 id Tech 3 source ports.

General notes

  • X is north in SMD. Elsewhere in Source it is east.
  • The format is carriage return sensitive: text editors should use CR (Mac) or CRLF (Windows) line terminators instead of just LF (Linux). Each command must be on a separate line. There should also be a single blank line at the end (and only the end) of the file.
  • White space is the only delimiter: any combination of tabs and spaces can be used to separate values, and for this reason multiword names should be enclosed in "quotation marks".
    Icon-Bug.pngBug:Avoid using tab. Its presence can crash studiomdl in very large SMDs.
  • Comments are not supported by GoldSrc GoldSrc studiomdl.
    For Source Source studiomdl, the following comment delimiters can be used (but are likely to be stripped by 3D modeling programs):
    • Stand-alone line comments start with // (double forward slash)
    • End-line comments start with # (hashtag) or ; (semicolon)

Types

Reference / Collision
A complete snapshot of the model, including one frame of animation to define the default pose. Collision meshes follow the same pattern.
header ↓
nodes ↓
skeleton ↓
triangles ↓
Animation
A single skeletal animation.
header ↓
nodes ↓
skeleton ↓
Vertex (only in Source)
A flex animation library. Usually has extension .vta.
header ↓
nodes ↓
skeleton ↓ (a "time <n>" header for each flex shape; no position data required)
vertexanimation ↓

Data blocks

Here are the components of an SMD file, considered in order:

Tip.pngTip:Unless otherwise noted, all integer values begin at 0 and all floating point values are limited to six decimal places. Source Source's StudioMDL supports floating point values being stored in scientific notation, but other engines and tools may not.

Header

Simply:

version 1
Todo: There are at least 3 versions; document their differences somewhere.

Nodes

A list of all the bones in the model.

Note.pngNote:

Syntax

nodes
Starts the node block.
<int|ID> "<string|Bone Name>" <int|Parent ID>
A bone definition. Unique ID number (does not have to be sequential), name in quote marks and the parent bone's ID. Bones without parents (i.e. children of the world) have a Parent ID of -1.
Note.pngNote:Studiomdl matches bones across SMDs by name. IDs are internal to each file.
end
Ends the data block.

Example

A root bone with one child:

nodes
0 "root" -1
1 "child" 0
end

Skeleton

Position data for each bone in each animation frame. In a reference SMD there is only one frame, which contains the model's default posture.

Note.pngNote:There can only be one animation in each SMD.

Syntax

skeleton
Begins the skeleton block.
time <int>
Begins a new frame. Any range of numbers can be used, so long as they increase sequentially.
<int|bone ID> <float|PosX PosY PosZ> <float|RotX RotY RotZ>
A bone's position relative to its parent (give absolute values in the case of root bones).
  • Pos is position in units relative to the parent bone.
  • Rot is local Tait-Bryan angles, given in radians relative to the parent bone (90° = 1.570796 rad)
Note.pngNote:In Source, the first frame must include all bones. After that, those which have not moved relative to their parent since the last frame can be omitted.
Doing this in GoldSrc resets the bone to its default position; all frames should have all bones.
Confirm:Default as in first frame, or default as in reference pose?
Tip.pngTip:Converting from a local rotation matrix to Euler angles might require you to invert the rotation matrix before conversion.
end
Ends the data block.

Example

Bone 1 move two units along the Y axis, then back again:

skeleton
time 0
0	0 0 0	1.570796 0 0
1	1 0 0	0 0 0
time 1
1	1 2 0	0 0 0
time 2
1	1 0 0	0 0 0
end

Triangles

A triangle in a model is defined by three vertices. Included in each triangle is its UV co-ordinates and envelope weights.

Note.pngNote:Source's triangles are one-sided. The active face is the one around which the vertices can be traced clockwise.

Syntax

triangles
Begins the triangle block.
<material (Source) or texture (GoldSrc)>
Defines the start of a new triangle and the material to apply to it.
File extensions (anything after a ".") are ignored in Source Source, but must be be bmp in GoldSrc GoldSrc.
Do not enclose in quotes and do not include a path ($cdmaterials (Source) or $cdtexture (GoldSrc) will provide one).
Warning.pngWarning:In Source StudioMDL, any faces using a materials named "null.bmp", "null.tga", or "debug/debugempty" will be deleted!
This is not the case for GoldSrc StudioMDL; several vanilla Day of Defeat models have materials named "null.bmp".
Note.pngNote:In GoldSrc, this should not exceed 63 characters (including the file extension).
<int|Parent bone> <float|PosX PosY PosZ> <normal|NormX NormY NormZ> <float|U V> <int|links> <int|Bone ID> <float|Weight> [...]
Defines a vertex.
  • Pos is in world units
  • Norm is the vertex normal, dictating how sharp or smooth the geometry is shaded
  • U and V are the vertex's UV map co-ordinates
The final three values are only supported by Source, where they are optional: they override <Parent bone> to define a series of weightmap links. Bone ID and Weight are repeated for each link. If the weights do not add up to 1, any remaining value is placed on <Parent bone>.
Note.pngNote:For SMDs included with $lod, Studiomdl can determine a vertex's weight links by copying those of the closest reference mesh vertex.
Note.pngNote:SMD version 3 supports up to 8 additional UV layers after additional links. Format <int|extra uvs> U1 V1 U2 V2 [...].
Nonetheless, the MDL formats used by both GoldSrc GoldSrc and Source Source only support a single set of UVs, except for Counter-Strike: Global Offensive CSGO, which uses a second set for $decaltexture.
end
Ends triangle block.

Example

A flat, two-sided square. The left edge envelopes bone 0 and the right edge envelopes bone 1, and the UV map is a simple square projection:

triangles
my_texture.bmp
0	0 0 0	0 0 1	0 1	1 0 1
0	0 -1 0	0 0 1	0 0	1 0 1
1	1 -1 0	0 0 1	1 0	1 1 1
my_texture.bmp
0	0 0 0	1 0 1	0 1	1 0 1
1	1 -1 0	1 0 1	1 0	1 1 1
1	1 0 0	1 0 1	1 1	1 1 1
my_texture.bmp
1	1 -1 0	0 0 1	1 0	1 1 1
0	0 -1 0	0 0 1	0 0	1 0 1
0	0 0 0	0 0 1	0 1	1 0 1
my_texture.bmp
1	1 0 0	1 0 1	1 1	1 1 1
1	1 -1 0	1 0 1	1 0	1 1 1
0	0 0 0	1 0 1	0 1	1 0 1
end

Vertexanimation

Broom icon.png
This article or section needs to be updated to include current information regarding the subject because:
This can also be used to store discrete key frames, using vertex animation instead of flex animation.
Remember to check for any notes left by the tagger at this article's talk page.

(only in Source Source) Position of vertices in various morph targets, for use in vertex animation or flex animation. While this block uses the same time keyword as skeleton ↑, each 'frame' is instead a discrete, static shape. Transitions between them are created on-demand by the engine.

Note.pngNote:A nodes ↑ and a skeleton ↑ block are needed in each VTA. The skeleton block needs only contain a "time <n>" header for each flex shape.

Syntax

vertexanimation
Begins the vertex animation block.
time <int>
Begins a morph target. The first target must include all vertices on the mesh in their reference positions; subsequent targets should include only vertices that differ from the reference.
<int|ID> <float|PosX PosY PosZ> <normal|NormX NormY NormZ>
A vertex.
  • ID is the position of the equivalent reference vertex in the triangles ↑ block
  • Pos is in absolute world units
  • Norm defines the direction from which the vertex receives the most light
end
Ends the data block.