DMX: Difference between revisions
TomEdwards (talk | contribs) No edit summary |
TomEdwards (talk | contribs) (restructured with more info from Valve) |
||
Line 1: | Line 1: | ||
{{toc-right}} | {{toc-right}} | ||
'''DMX''' (Data Model | '''DMX''' (Data Model eXchange) stores a [[Datamodel]] object, encoded as either [[W:Binary file|binary]] or ASCII (KeyValues2). The unreleased SDK tool '''dmxconvert''' can convert a DMX between them. | ||
Compared to KeyValues2, DMX is: | The internal structure ("format") of a DMX is defined by the user. | ||
== Encodings == | |||
=== KeyValues2 === | |||
This ASCII encoding is the successor to [[KeyValues]]. It's good if you have a small DMX and want it hand-editable. | |||
{{tip|1=When hand-editing, you can generate IDs for new elements [http://www.guidgen.com/ with this website] (or with guidgen itself, if you have the Windows SDK installed).}} | |||
{{bug|It is not currently possible to serialise a Datamodel to KV2 with the SDK.}} | |||
=== Binary === | |||
Compared to KeyValues2, binary DMX is: | |||
# ''Small'', especially when storing large [[int]]s or accurate [[float]]s | # ''Small'', especially when storing large [[int]]s or accurate [[float]]s | ||
Line 10: | Line 24: | ||
# ''Inscrutable'', because it contains native binary data | # ''Inscrutable'', because it contains native binary data | ||
Binary is good for large DMXes. | |||
== | == Formats == | ||
These are the formats used by Valve. | |||
=== | === Particle System === | ||
Created by the [[Particle Editor]] and read by the engine, usually with the extension <code>pcf</code>. There should be no reason to manipulate these yourself. | |||
=== Model === | |||
DMX model source files are generated by '''<code>vsdmxio</code>''', which only available publicly as a Maya plugin (<code>sourcesdk/maya/2009/plug-ins/valveSource/</code>). Some editing options are available with the Source 2009 SDK tool '''<code>dmxedit</code>''' however, including export to OBJ (unweighted, no animations). | DMX model source files are generated by '''<code>vsdmxio</code>''', which only available publicly as a Maya plugin (<code>sourcesdk/maya/2009/plug-ins/valveSource/</code>). Some editing options are available with the Source 2009 SDK tool '''<code>dmxedit</code>''' however, including export to OBJ (unweighted, no animations). | ||
Line 34: | Line 52: | ||
== Programming == | == Programming == | ||
Handling DMX files has many similarities to handling [[KeyValues]]. The | Handling DMX files has many similarities to handling [[KeyValues]]. The big architectural differences are that: | ||
* Where KVs had keys, Datamodel has '''<code>CDmxElement</code>''' objects containing '''<code>CDmxAttribute</code>''' (which can point to further elements). | |||
* There is '''support for [[array]]s'''. | |||
* Attribute values are accessed through '''a single [[W:Template (programming)|templated]] function''', not lots of different ones. | |||
* Each element has a '''unique 256-bit ID''', which can be used like a [[pointer]] to reference any other element loaded into memory. | |||
* There can be '''multiple roots''' in each serialised DMX file. | |||
{{todo|CDmxElement vs CDmElement}} | |||
For a full list of | For a full list of attribute types, see the bottom of <code>public\datamodel\dmattributetypes.h</code>. | ||
{{note|[[String]]s are <code>[[CUtlString]]</code> objects, not <code>[[char]]</code>!}} | {{note|[[String]]s are <code>[[CUtlString]]</code> objects, not <code>[[char]]</code>!}} | ||
{{note|The SerializeDMX() overload that includes a file path | {{note|The SerializeDMX() overload that includes a file path does not work. You must serialize to a buffer then write out manually.}} | ||
=== Creating === | === Creating === | ||
Line 55: | Line 78: | ||
{ | { | ||
DECLARE_DMX_CONTEXT(); | DECLARE_DMX_CONTEXT(); | ||
CDmxElement* DMX = CreateDmxElement(""); | CDmxElement* DMX = CreateDmxElement("MyElementTypeName"); | ||
CDmxAttribute* curAttr = DMX->AddAttribute("Hello"); | CDmxAttribute* curAttr = DMX->AddAttribute("Hello"); |
Revision as of 04:08, 21 December 2010
DMX (Data Model eXchange) stores a Datamodel object, encoded as either binary or ASCII (KeyValues2). The unreleased SDK tool dmxconvert can convert a DMX between them.
The internal structure ("format") of a DMX is defined by the user.
Encodings
KeyValues2
This ASCII encoding is the successor to KeyValues. It's good if you have a small DMX and want it hand-editable.


Binary
Compared to KeyValues2, binary DMX is:
- Small, especially when storing large ints or accurate floats
- Fast, as values do not have to be converted to or from human-readable characters
- Robust, since it does not have to worry about delimiters, line breaks or unclosed quote blocks
- Inscrutable, because it contains native binary data
Binary is good for large DMXes.
Formats
These are the formats used by Valve.
Particle System
Created by the Particle Editor and read by the engine, usually with the extension pcf
. There should be no reason to manipulate these yourself.
Model
DMX model source files are generated by vsdmxio
, which only available publicly as a Maya plugin (sourcesdk/maya/2009/plug-ins/valveSource/
). Some editing options are available with the Source 2009 SDK tool dmxedit
however, including export to OBJ (unweighted, no animations).
To use dmxedit:
- Create an empty file called
vs.lua
in the SDK binaries folder. This is probably meant to contain commands that are executed every time you run the tool. - You must then create a LUA file containing the actions you want to perform. Here is a simple example that exports to OBJ:
Load( "<path_to_dmx>" )
Save("<export_path>.obj")
- Perform
dmxedit myfile.lua
to run the script.
If export a mesh DMX to OBJ you will get a single file. If you export a morph DMX you will get one OBJ for each flex animation that was in the file. If you chose an animation you will get nothing; it seems that dmxedit doesn't support animations.
Programming
Handling DMX files has many similarities to handling KeyValues. The big architectural differences are that:
- Where KVs had keys, Datamodel has
CDmxElement
objects containingCDmxAttribute
(which can point to further elements). - There is support for arrays.
- Attribute values are accessed through a single templated function, not lots of different ones.
- Each element has a unique 256-bit ID, which can be used like a pointer to reference any other element loaded into memory.
- There can be multiple roots in each serialised DMX file.
For a full list of attribute types, see the bottom of public\datamodel\dmattributetypes.h
.

CUtlString
objects, not char
!
Creating
#include "cbase.h"
#include "dmxloader/dmxloader.h"
#include "dmxloader/dmxelement.h"
CON_COMMAND( dmx_create, "Makes a simple DMX" )
{
DECLARE_DMX_CONTEXT();
CDmxElement* DMX = CreateDmxElement("MyElementTypeName");
CDmxAttribute* curAttr = DMX->AddAttribute("Hello");
curAttr->SetValue("world");
CUtlBuffer buf;
SerializeDMX(buf,DMX);
FileHandle_t fh = filesystem->Open("test.dmx","w","DEFAULT_WRITE_PATH");
filesystem->Write(buf.Base(),buf.TellPut(),fh);
filesystem->Close(fh);
}
Iterator
This code will print string, int, float and bool values in the given DMX to the console.
#include "cbase.h"
#include "dmxloader/dmxloader.h"
#include "dmxloader/dmxelement.h"
void IterateDmxElement(CDmxElement* pRoot)
{
for (int i=0;i<pRoot->AttributeCount();i++)
{
CDmxAttribute* pCur = pRoot->GetAttribute(i);
CDmxElement* subElem;
Warning( "%s: ",pCur->GetName() );
switch (pCur->GetType())
{
case AT_ELEMENT:
subElem = pCur->GetValue<CDmxElement*>();
if (subElem)
IterateDmxElement(subElem);
break;
case AT_STRING:
Msg( "STRING | %s\n",pCur->GetValue<CUtlString>().Get() );
break;
case AT_INT:
Msg( "INT | %i\n",pCur->GetValue<int>() );
break;
case AT_FLOAT:
Msg( "FLOAT | %f\n",pCur->GetValue<float>() );
break;
case AT_BOOL:
Msg( "BOOL | %s\n",pCur->GetValue<bool>() ? "true" : "false" );
break;
default:
Msg("Unknown type %i\n",pCur->GetType());
break;
}
}
}
CON_COMMAND(dmx_iterate, "Prints a DMX file to the console")
{
DECLARE_DMX_CONTEXT();
CDmxElement* DMX = (CDmxElement*)DMXAlloc( 50000000 );
if (UnserializeDMX(args[1],"MOD",false,&DMX))
{
IterateDmxElement(DMX);
}
else
Warning("Could not read DMX file %s\n",args[1]);
}