SMD file format: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
(various improvements)
No edit summary
Line 1: Line 1:
The '''StudioMDL Data''' file format stores 3D geometry data in ASCII for analysis and compilation by [[studiomdl]]. SMD files are usually generated by an [[SMD export]]er plug-in for a given [[model editor]] package.
{{toc-right}}


The format is carriage return sensitive: 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 '''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.


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". There is no support for comments.
*The format is carriage return sensitive: 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". There is no support for comments.


== Types ==
== Types ==


;Reference
;Reference / Collision
:''A complete snapshot of the model, including one frame of animation to define the default pose. Also used for [[collision mesh]]es.''
:''A complete snapshot of the model, including one frame of animation to define the default pose. Also used for [[collision mesh]]es.''
:<code>[[#Header|header]]</code>
:<code>[[#Header|header]]</code>
Line 14: Line 15:
:<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>
Line 42: Line 43:


{{note|Bones without attached vertices will not be compiled.}}
{{note|Bones without attached vertices will not be compiled.}}
==== Syntax ====
; <code>nodes</code>
: Starts the node block.
; <code><[[int]]|ID> "<[[string]]|Bone Name>" <int|Parent ID></code>
: 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 <code>-1</code>.
; <code>end</code>
: Ends the data block.
==== Example ====


A root bone with one child:
A root bone with one child:
Line 49: Line 60:
  1 "child" 0
  1 "child" 0
  end
  end
; <code>nodes</code>
: Starts the node block.
; <code><[[int]]|ID> "<[[string]]|Bone Name>" <int|Parent ID></code>
: 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 <code>-1</code>.
; <code>end</code>
: Ends the data block.


=== Skeleton ===
=== Skeleton ===
Line 63: Line 67:
{{note|There can only be one animation in each SMD.}}
{{note|There can only be one animation in each SMD.}}


This code makes bone 1 move two units along the Y axis, then back again:
==== Syntax ====
 
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


; <code>skeleton</code>
; <code>skeleton</code>
Line 86: Line 80:
; <code>end</code>
; <code>end</code>
: Ends the data block.
: 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 ===
=== Triangles ===
All of the polygons in the model by their three [[vertex|vertices]]. Included in each polygon is its [[UV]] co-ordinates and [[envelope]] weights.
All of the polygons in the model by their three [[vertex|vertices]]. Included in each polygon is its [[UV]] co-ordinates and [[envelope]] weights.


{{note|Source's polygons are one-sided. The active face is the one around which the vertices can be traced clockwise.}}
{{note|Source's polygons are one-sided. The active face is the one around which the vertices can be traced clockwise.}}


This code represents 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:
==== Syntax ====
 
; <code>triangles</code>
: Begins the triangle block.
; <code><material></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).
; <code><[[int]]|Parent bone> <[[float]]|PosX PosY PosZ> <[[normal]]|NormX NormY NormZ> <normal|U V> <int|links> <int|Bone ID> <normal|Weight> [...]</code>
: Defines a [[vertex]].
:* <code>Pos</code> is in world [[unit]]s
:* <code>Norm</code> is used to smooth the surface of the model ({{todo|How?}})
:* U and V are the vertex's [[UV map]] co-ordinates
: The final three options are optional: they override <code><Parent bone></code> to define a series of weighted envelopes. <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>.
; <code>end</code>
: 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
  triangles
Line 112: Line 138:
  0 0 0 0 1 0 1 0 1 1 0 1
  0 0 0 0 1 0 1 0 1 1 0 1
  end
  end
; <code>triangles</code>
: Begins the triangle block.
; <code><material></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).
; <code><[[int]]|Parent bone> <[[float]]|PosX PosY PosZ> <[[normal]]|NormX NormY NormZ> <normal|U V> <int|links> <int|Bone ID> <normal|Weight> [...]</code>
: Defines a [[vertex]]. <code>Pos</code> is in world [[unit]]s. <code>Norm</code> is used to smooth the surface of the model ({{todo|How?}}). U and V are the vertex's [[UV map]] co-ordinates.
: The final three options are optional: they override <code><Parent bone></code> to define a series of weighted envelopes. <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>.
; <code>end</code>
: Ends triangle block.


=== Vertexanimation ===
=== Vertexanimation ===
Line 128: Line 144:


{{warning|The precise structure of this block is unclear. It is known that a skeleton block is required elsewhere in the file, though all frames in it appear to be the same!}}
{{warning|The precise structure of this block is unclear. It is known that a skeleton block is required elsewhere in the file, though all frames in it appear to be the same!}}
==== Syntax ====


; <code>vertexanimation</code>
; <code>vertexanimation</code>
Line 134: Line 152:
: Begins a morph target. It is unclear how many or even which vertices should be included (though it's a safe bet that the modified ones are among them).
: Begins a morph target. It is unclear how many or even which vertices should be included (though it's a safe bet that the modified ones are among them).
; <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. Its ID is defined by its position in <code>[[#Triangles|triangles]]</code>; <code>Pos</code> is in world [[unit]]s; <code>Norm</code> is used to smooth the surface of the model ({{todo|How?}}).
: A vertex.  
:* ID is defined by its position in <code>[[#Triangles|triangles]]</code>
:* <code>Pos</code> is in world [[unit]]s
:* <code>Norm</code> is used to smooth the surface of the model ({{todo|How?}})
; <code>end</code>
; <code>end</code>
: Ends the data block.
: Ends the data block.

Revision as of 03:29, 6 January 2009

The StudioMDL Data file format 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.

  • The format is carriage return sensitive: 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". There is no support for comments.

Types

Reference / Collision
A complete snapshot of the model, including one frame of animation to define the default pose. Also used for collision meshes.
header
nodes
skeleton
triangles
Animation
A single skeletal animation.
header
nodes
skeleton
Vertex
For flex animation. Usually has extension .vta. Precise structure unclear.
header
nodes
skeleton
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.

Header

Simply:

version 1

Nodes

A list of all the bones in the model.

Note.pngNote:Bones without attached vertices will not be compiled.

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.
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).
Tip.pngTip: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.
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

All of the polygons in the model by their three vertices. Included in each polygon is its UV co-ordinates and envelope weights.

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

Syntax

triangles
Begins the triangle block.
<material>
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).
<int|Parent bone> <float|PosX PosY PosZ> <normal|NormX NormY NormZ> <normal|U V> <int|links> <int|Bone ID> <normal|Weight> [...]
Defines a vertex.
  • Pos is in world units
  • Norm is used to smooth the surface of the model (
    Todo: How?
    )
  • U and V are the vertex's UV map co-ordinates
The final three options are optional: they override <Parent bone> to define a series of weighted envelopes. 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>.
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_material
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_material
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_material
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_material
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

Position of vertices in various morph targets (for flex animation). Although this block uses the same time keyword as skeleton, each 'frame' is a discrete shape: transitions between them are created on-demand by the engine.

Warning.pngWarning:The precise structure of this block is unclear. It is known that a skeleton block is required elsewhere in the file, though all frames in it appear to be the same!

Syntax

vertexanimation
Begins the vertex animation block.
time <int>
Begins a morph target. It is unclear how many or even which vertices should be included (though it's a safe bet that the modified ones are among them).
<int|ID> <float|PosX PosY PosZ> <normal|NormX NormY NormZ>
A vertex.
  • ID is defined by its position in triangles
  • Pos is in world units
  • Norm is used to smooth the surface of the model (
    Todo: How?
    )
end
Ends the data block.