Skip to content

Commit e20155a

Browse files
authored
Merge pull request #61 from klaussilveira/feat/md5
Added support for MD5v11 (ETQW) and MD5v12 (Storm Engine 2)
2 parents 8339579 + 8f04c3d commit e20155a

File tree

4 files changed

+63
-7
lines changed

4 files changed

+63
-7
lines changed

radiantcore/model/md5/MD5Anim.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,10 @@ void MD5Anim::parseFromTokens(parser::DefTokeniser& tok)
147147

148148
int version = string::convert<int>(tok.nextToken());
149149

150-
if (version != 10)
150+
if (version != 10 && version != 11 && version != 12)
151151
{
152-
rWarning() << "Unexpected version encountered: " << version
153-
<< " (expected 10), will attempt to load anyway." << std::endl;
152+
rWarning() << "Unexpected MD5 version encountered: " << version
153+
<< " (expected 10, 11, or 12), will attempt to load anyway." << std::endl;
154154
}
155155

156156
tok.assertNextToken("commandline");

radiantcore/model/md5/MD5Model.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,12 @@ void MD5Model::parseFromTokens(parser::DefTokeniser& tok)
205205

206206
// Check the version number
207207
tok.assertNextToken("MD5Version");
208-
tok.assertNextToken("10");
208+
int version = string::convert<int>(tok.nextToken());
209+
210+
if (version != 10 && version != 11 && version != 12)
211+
{
212+
throw parser::ParseException("Unsupported MD5Version: " + std::to_string(version));
213+
}
209214

210215
// Commandline
211216
tok.assertNextToken("commandline");
@@ -268,7 +273,7 @@ void MD5Model::parseFromTokens(parser::DefTokeniser& tok)
268273
// Construct the surface for this mesh
269274
MD5Surface& surface = createNewSurface();
270275

271-
surface.parseFromTokens(tok);
276+
surface.parseFromTokens(tok, version);
272277

273278
// Build the index array - this has to happen at least once
274279
surface.buildIndexArray();

radiantcore/model/md5/MD5Surface.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ void MD5Surface::buildIndexArray()
294294
}
295295
}
296296

297-
void MD5Surface::parseFromTokens(parser::DefTokeniser& tok)
297+
void MD5Surface::parseFromTokens(parser::DefTokeniser& tok, int version)
298298
{
299299
// Start of datablock
300300
tok.assertNextToken("mesh");
@@ -303,10 +303,25 @@ void MD5Surface::parseFromTokens(parser::DefTokeniser& tok)
303303
// Get the reference to the mesh definition
304304
MD5Mesh& mesh = *_mesh;
305305

306+
// v11 may have an optional "name" field before shader
307+
if (tok.peek() == "name")
308+
{
309+
tok.nextToken(); // "name"
310+
tok.nextToken(); // skip the name string
311+
}
312+
306313
// Get the shader name
307314
tok.assertNextToken("shader");
308315
setDefaultMaterial(tok.nextToken());
309316

317+
// v11 may have an optional "flags { ... }" block
318+
if (tok.peek() == "flags")
319+
{
320+
tok.nextToken(); // "flags"
321+
tok.assertNextToken("{");
322+
while (tok.nextToken() != "}") {} // skip until closing brace
323+
}
324+
310325
// ----- VERTICES ------
311326

312327
// Read the vertex count
@@ -335,6 +350,27 @@ void MD5Surface::parseFromTokens(parser::DefTokeniser& tok)
335350
vt->weight_index = string::convert<std::size_t>(tok.nextToken());
336351
vt->weight_count = string::convert<std::size_t>(tok.nextToken());
337352

353+
if (version == 11)
354+
{
355+
// v11: optional per-vertex RGBA as ( R G B A )
356+
if (tok.peek() == "(")
357+
{
358+
tok.nextToken(); // "("
359+
tok.skipTokens(4); // R G B A
360+
tok.assertNextToken(")");
361+
}
362+
}
363+
else if (version == 12)
364+
{
365+
// v12: per-vertex normal ( nx ny nz ) and tangent ( tx ty tz tw )
366+
tok.assertNextToken("(");
367+
tok.skipTokens(3); // nx ny nz
368+
tok.assertNextToken(")");
369+
tok.assertNextToken("(");
370+
tok.skipTokens(4); // tx ty tz tw
371+
tok.assertNextToken(")");
372+
}
373+
338374
} // for each vertex
339375

340376
// ------ TRIANGLES ------
@@ -385,6 +421,21 @@ void MD5Surface::parseFromTokens(parser::DefTokeniser& tok)
385421

386422
} // for each weight
387423

424+
// v12: optional vertex colors block
425+
if (version == 12 && tok.peek() == "numvertexcolors")
426+
{
427+
tok.nextToken(); // "numvertexcolors"
428+
std::size_t numColors = string::convert<std::size_t>(tok.nextToken());
429+
for (std::size_t i = 0; i < numColors; ++i)
430+
{
431+
tok.assertNextToken("vertexcolor");
432+
tok.skipTokens(1); // index
433+
tok.assertNextToken("(");
434+
tok.skipTokens(4); // R G B A
435+
tok.assertNextToken(")");
436+
}
437+
}
438+
388439
// ----- END OF MESH DECL -----
389440

390441
tok.assertNextToken("}");

radiantcore/model/md5/MD5Surface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class MD5Surface final :
8989

9090
const AABB& getSurfaceBounds() const override;
9191

92-
void parseFromTokens(parser::DefTokeniser& tok);
92+
void parseFromTokens(parser::DefTokeniser& tok, int version = 10);
9393

9494
// Rebuild the render index array - usually needs to be called only once
9595
void buildIndexArray();

0 commit comments

Comments
 (0)