public static idMapPatch Parse(idLexer lexer, Vector3 origin, bool patchDef3 = true, float version = idMapFile.CurrentMapVersion)
{
if(lexer.ExpectTokenString("{") == false)
{
return null;
}
// read the material (we had an implicit 'textures/' in the old format...)
idToken token = lexer.ReadToken();
if(token == null)
{
lexer.Error("idMapPatch::Parse: unexpected EOF");
return null;
}
// Parse it
float[] info;
if(patchDef3 == true)
{
info = lexer.Parse1DMatrix(7);
if(info == null)
{
lexer.Error("idMapPatch::Parse: unable to Parse patchDef3 info");
return null;
}
}
else
{
info = lexer.Parse1DMatrix(5);
if(info == null)
{
lexer.Error("idMapPatch::Parse: unable to parse patchDef2 info");
return null;
}
}
idMapPatch patch = new idMapPatch((int) info[0], (int) info[1]);
if(version < 2.0f)
{
patch.Material = "textures/" + token.ToString();
}
else
{
patch.Material = token.ToString();
}
if(patchDef3 == true)
{
patch.HorizontalSubdivisions = (int) info[2];
patch.VerticalSubdivisions = (int) info[3];
patch.ExplicitlySubdivided = true;
}
if((patch.Width < 0) || (patch.Height < 0))
{
lexer.Error("idMapPatch::Parse: bad size");
return null;
}
// these were written out in the wrong order, IMHO
if(lexer.ExpectTokenString("(") == false)
{
lexer.Error("idMapPatch::Parse: bad patch vertex data");
return null;
}
for(int j = 0; j < patch.Width; j++)
{
if(lexer.ExpectTokenString("(") == false)
{
lexer.Error("idMapPatch::Parse: bad vertex row data");
return null;
}
for(int i = 0; i < patch.Height; i++)
{
float[] v = lexer.Parse1DMatrix(5);
if(v == null)
{
lexer.Error("idMapPatch::Parse: bad vertex column data");
return null;
}
Vertex vert = new Vertex();
vert.Position.X = v[0] - origin.X;
vert.Position.Y = v[1] - origin.Y;
vert.Position.Z = v[2] - origin.Z;
vert.TextureCoordinates = new Vector2(v[3], v[4]);
patch.SetVertex(i * patch.Width + j, vert);
}
if(lexer.ExpectTokenString(")") == false)
{
lexer.Error("idMapPatch::Parse: unable to parse patch control points");
return null;
}
}
if(lexer.ExpectTokenString(")") == false)
{
lexer.Error("idMapPatch::Parse: unable to parse patch control points, no closure" );
return null;
}
// read any key/value pairs
while((token = lexer.ReadToken()) != null)
{
if(token.ToString() == "}")
{
lexer.ExpectTokenString("}");
break;
}
if(token.Type == TokenType.String)
{
string key = token.ToString();
token = lexer.ExpectTokenType(TokenType.String, 0);
patch.Dict.Set(key, token.ToString());
}
}
return patch;
}