mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-31 04:40:55 +00:00
Added support for SurfaceSkin MODELDEF property.
Changed, Visual mode: increased maximum rendreable dynamic lights count to 64.
This commit is contained in:
parent
68c5ed1747
commit
3f93525ebc
7 changed files with 143 additions and 39 deletions
|
@ -3210,7 +3210,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
// Load the skysphere model...
|
// Load the skysphere model...
|
||||||
BoundingBoxSizes bbs = new BoundingBoxSizes();
|
BoundingBoxSizes bbs = new BoundingBoxSizes();
|
||||||
Stream modeldata = General.ThisAssembly.GetManifestResourceStream("CodeImp.DoomBuilder.Resources.SkySphere.md3");
|
Stream modeldata = General.ThisAssembly.GetManifestResourceStream("CodeImp.DoomBuilder.Resources.SkySphere.md3");
|
||||||
ModelReader.MD3LoadResult meshes = ModelReader.ReadMD3Model(ref bbs, true, modeldata, device, 0);
|
ModelReader.MD3LoadResult meshes = ModelReader.ReadMD3Model(ref bbs, new Dictionary<int, string>(), modeldata, device, 0);
|
||||||
if(meshes.Meshes.Count != 3) throw new Exception("Skybox creation failed: "
|
if(meshes.Meshes.Count != 3) throw new Exception("Skybox creation failed: "
|
||||||
+ (string.IsNullOrEmpty(meshes.Errors) ? "skybox model must contain 3 surfaces" : meshes.Errors));
|
+ (string.IsNullOrEmpty(meshes.Errors) ? "skybox model must contain 3 surfaces" : meshes.Errors));
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
||||||
#region ================== Properties
|
#region ================== Properties
|
||||||
|
|
||||||
internal List<string> ModelNames;
|
internal List<string> ModelNames;
|
||||||
internal List<string> TextureNames;
|
internal List<string> SkinNames;
|
||||||
|
internal List<Dictionary<int, string>> SurfaceSkinNames;
|
||||||
internal List<string> FrameNames;
|
internal List<string> FrameNames;
|
||||||
internal List<int> FrameIndices;
|
internal List<int> FrameIndices;
|
||||||
|
|
||||||
|
@ -62,7 +63,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
||||||
internal ModelData()
|
internal ModelData()
|
||||||
{
|
{
|
||||||
ModelNames = new List<string>();
|
ModelNames = new List<string>();
|
||||||
TextureNames = new List<string>();
|
SkinNames = new List<string>();
|
||||||
|
SurfaceSkinNames = new List<Dictionary<int, string>>();
|
||||||
FrameNames = new List<string>();
|
FrameNames = new List<string>();
|
||||||
FrameIndices = new List<int>();
|
FrameIndices = new List<int>();
|
||||||
transform = Matrix.Identity;
|
transform = Matrix.Identity;
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear unneeded data
|
//clear unneeded data
|
||||||
mde.TextureNames = null;
|
mde.SkinNames = null;
|
||||||
mde.ModelNames = null;
|
mde.ModelNames = null;
|
||||||
|
|
||||||
if(mde.Model.Meshes == null || mde.Model.Meshes.Count == 0)
|
if(mde.Model.Meshes == null || mde.Model.Meshes.Count == 0)
|
||||||
|
@ -95,10 +95,15 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
//load models and textures
|
//load models and textures
|
||||||
for(int i = 0; i < mde.ModelNames.Count; i++)
|
for(int i = 0; i < mde.ModelNames.Count; i++)
|
||||||
{
|
{
|
||||||
//need to use model skins?
|
// Use model skins?
|
||||||
bool useSkins = string.IsNullOrEmpty(mde.TextureNames[i]);
|
// INFO: Skin MODELDEF property overrides both embedded surface names and ones set using SurfaceSkin MODELDEF property
|
||||||
|
Dictionary<int, string> skins = null;
|
||||||
|
if(string.IsNullOrEmpty(mde.SkinNames[i]))
|
||||||
|
{
|
||||||
|
skins = (mde.SurfaceSkinNames[i].Count > 0 ? mde.SurfaceSkinNames[i] : new Dictionary<int, string>());
|
||||||
|
}
|
||||||
|
|
||||||
//load mesh
|
// Load mesh
|
||||||
MemoryStream ms = LoadFile(containers, mde.ModelNames[i], true);
|
MemoryStream ms = LoadFile(containers, mde.ModelNames[i], true);
|
||||||
if(ms == null)
|
if(ms == null)
|
||||||
{
|
{
|
||||||
|
@ -115,7 +120,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
General.ErrorLogger.Add(ErrorType.Error, "Error while loading \"" + mde.ModelNames[i] + "\": frame names are not supported for MD3 models!");
|
General.ErrorLogger.Add(ErrorType.Error, "Error while loading \"" + mde.ModelNames[i] + "\": frame names are not supported for MD3 models!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
result = ReadMD3Model(ref bbs, useSkins, ms, device, mde.FrameIndices[i]);
|
result = ReadMD3Model(ref bbs, skins, ms, device, mde.FrameIndices[i]);
|
||||||
break;
|
break;
|
||||||
case ".md2":
|
case ".md2":
|
||||||
result = ReadMD2Model(ref bbs, ms, device, mde.FrameIndices[i], mde.FrameNames[i]);
|
result = ReadMD2Model(ref bbs, ms, device, mde.FrameIndices[i], mde.FrameNames[i]);
|
||||||
|
@ -145,7 +150,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
List<string> errors = new List<string>();
|
List<string> errors = new List<string>();
|
||||||
|
|
||||||
// Texture not defined in MODELDEF?
|
// Texture not defined in MODELDEF?
|
||||||
if(useSkins)
|
if(skins != null)
|
||||||
{
|
{
|
||||||
//try to use model's own skins
|
//try to use model's own skins
|
||||||
for(int m = 0; m < result.Meshes.Count; m++)
|
for(int m = 0; m < result.Meshes.Count; m++)
|
||||||
|
@ -169,7 +174,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
|
|
||||||
//relative path?
|
//relative path?
|
||||||
if(path.IndexOf(Path.DirectorySeparatorChar) == -1)
|
if(path.IndexOf(Path.DirectorySeparatorChar) == -1)
|
||||||
path = Path.Combine(Path.GetDirectoryName(mde.ModelNames[useSkins ? i : m]), path);
|
path = Path.Combine(Path.GetDirectoryName(mde.ModelNames[i]), path);
|
||||||
|
|
||||||
Texture t = LoadTexture(containers, path, device);
|
Texture t = LoadTexture(containers, path, device);
|
||||||
|
|
||||||
|
@ -186,11 +191,11 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
//Try to use texture loaded from MODELDEFS
|
//Try to use texture loaded from MODELDEFS
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Texture t = LoadTexture(containers, mde.TextureNames[i], device);
|
Texture t = LoadTexture(containers, mde.SkinNames[i], device);
|
||||||
if(t == null)
|
if(t == null)
|
||||||
{
|
{
|
||||||
mde.Model.Textures.Add(General.Map.Data.UnknownTexture3D.Texture);
|
mde.Model.Textures.Add(General.Map.Data.UnknownTexture3D.Texture);
|
||||||
errors.Add("unable to load texture \"" + mde.TextureNames[i] + "\"");
|
errors.Add("unable to load texture \"" + mde.SkinNames[i] + "\"");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -208,7 +213,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear unneeded data
|
//clear unneeded data
|
||||||
mde.TextureNames = null;
|
mde.SkinNames = null;
|
||||||
mde.ModelNames = null;
|
mde.ModelNames = null;
|
||||||
|
|
||||||
if(mde.Model.Meshes == null || mde.Model.Meshes.Count == 0)
|
if(mde.Model.Meshes == null || mde.Model.Meshes.Count == 0)
|
||||||
|
@ -231,7 +236,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
|
|
||||||
#region ================== MD3
|
#region ================== MD3
|
||||||
|
|
||||||
internal static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, bool useSkins, Stream s, Device device, int frame)
|
internal static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, Dictionary<int, string> skins, Stream s, Device device, int frame)
|
||||||
{
|
{
|
||||||
long start = s.Position;
|
long start = s.Position;
|
||||||
MD3LoadResult result = new MD3LoadResult();
|
MD3LoadResult result = new MD3LoadResult();
|
||||||
|
@ -265,6 +270,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
Dictionary<string, List<List<int>>> polyIndecesListsPerTexture = new Dictionary<string, List<List<int>>>(StringComparer.Ordinal);
|
Dictionary<string, List<List<int>>> polyIndecesListsPerTexture = new Dictionary<string, List<List<int>>>(StringComparer.Ordinal);
|
||||||
Dictionary<string, List<WorldVertex>> vertListsPerTexture = new Dictionary<string, List<WorldVertex>>(StringComparer.Ordinal);
|
Dictionary<string, List<WorldVertex>> vertListsPerTexture = new Dictionary<string, List<WorldVertex>>(StringComparer.Ordinal);
|
||||||
Dictionary<string, List<int>> vertexOffsets = new Dictionary<string, List<int>>(StringComparer.Ordinal);
|
Dictionary<string, List<int>> vertexOffsets = new Dictionary<string, List<int>>(StringComparer.Ordinal);
|
||||||
|
bool useskins = false;
|
||||||
|
|
||||||
for(int c = 0; c < numSurfaces; c++)
|
for(int c = 0; c < numSurfaces; c++)
|
||||||
{
|
{
|
||||||
|
@ -277,8 +283,22 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(useSkins)
|
// Pick a skin to use
|
||||||
|
if(skins == null)
|
||||||
{
|
{
|
||||||
|
// skins is null when Skin MODELDEF property is set
|
||||||
|
skin = string.Empty;
|
||||||
|
}
|
||||||
|
else if(skins.ContainsKey(c))
|
||||||
|
{
|
||||||
|
// Overrtide surface skin with SurfaceSkin MODELDEF property
|
||||||
|
skin = skins[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!string.IsNullOrEmpty(skin))
|
||||||
|
{
|
||||||
|
useskins = true;
|
||||||
|
|
||||||
if(polyIndecesListsPerTexture.ContainsKey(skin))
|
if(polyIndecesListsPerTexture.ContainsKey(skin))
|
||||||
{
|
{
|
||||||
polyIndecesListsPerTexture[skin].Add(polyIndecesList);
|
polyIndecesListsPerTexture[skin].Add(polyIndecesList);
|
||||||
|
@ -298,8 +318,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!useSkins)
|
if(!useskins)
|
||||||
{
|
{
|
||||||
//create mesh
|
//create mesh
|
||||||
CreateMesh(device, ref result, vertList, polyIndecesList);
|
CreateMesh(device, ref result, vertList, polyIndecesList);
|
||||||
result.Skins.Add("");
|
result.Skins.Add("");
|
||||||
|
|
19
Source/Core/Windows/PreferencesForm.Designer.cs
generated
19
Source/Core/Windows/PreferencesForm.Designer.cs
generated
|
@ -602,7 +602,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
// label1
|
// label1
|
||||||
//
|
//
|
||||||
label1.AutoSize = true;
|
label1.AutoSize = true;
|
||||||
label1.Location = new System.Drawing.Point(41, 171);
|
label1.Location = new System.Drawing.Point(43, 171);
|
||||||
label1.Name = "label1";
|
label1.Name = "label1";
|
||||||
label1.Size = new System.Drawing.Size(145, 13);
|
label1.Size = new System.Drawing.Size(145, 13);
|
||||||
label1.TabIndex = 20;
|
label1.TabIndex = 20;
|
||||||
|
@ -612,11 +612,11 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
// label18
|
// label18
|
||||||
//
|
//
|
||||||
label18.AutoSize = true;
|
label18.AutoSize = true;
|
||||||
label18.Location = new System.Drawing.Point(41, 208);
|
label18.Location = new System.Drawing.Point(80, 208);
|
||||||
label18.Name = "label18";
|
label18.Name = "label18";
|
||||||
label18.Size = new System.Drawing.Size(147, 13);
|
label18.Size = new System.Drawing.Size(108, 13);
|
||||||
label18.TabIndex = 25;
|
label18.TabIndex = 25;
|
||||||
label18.Text = "Max. dynamic lights to render:";
|
label18.Text = "Dynamic lights count:";
|
||||||
label18.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
label18.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||||
this.toolTip1.SetToolTip(label18, "Controls how many dynamic lights could be \r\nrendered simultaneously in Visual mod" +
|
this.toolTip1.SetToolTip(label18, "Controls how many dynamic lights could be \r\nrendered simultaneously in Visual mod" +
|
||||||
"e ");
|
"e ");
|
||||||
|
@ -654,7 +654,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
// label29
|
// label29
|
||||||
//
|
//
|
||||||
label29.AutoSize = true;
|
label29.AutoSize = true;
|
||||||
label29.Location = new System.Drawing.Point(90, 356);
|
label29.Location = new System.Drawing.Point(96, 356);
|
||||||
label29.Name = "label29";
|
label29.Name = "label29";
|
||||||
label29.Size = new System.Drawing.Size(93, 13);
|
label29.Size = new System.Drawing.Size(93, 13);
|
||||||
label29.TabIndex = 38;
|
label29.TabIndex = 38;
|
||||||
|
@ -1704,7 +1704,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
// label32
|
// label32
|
||||||
//
|
//
|
||||||
this.label32.AutoSize = true;
|
this.label32.AutoSize = true;
|
||||||
this.label32.Location = new System.Drawing.Point(44, 134);
|
this.label32.Location = new System.Drawing.Point(49, 134);
|
||||||
this.label32.Name = "label32";
|
this.label32.Name = "label32";
|
||||||
this.label32.Size = new System.Drawing.Size(139, 13);
|
this.label32.Size = new System.Drawing.Size(139, 13);
|
||||||
this.label32.TabIndex = 44;
|
this.label32.TabIndex = 44;
|
||||||
|
@ -1724,7 +1724,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
// label30
|
// label30
|
||||||
//
|
//
|
||||||
this.label30.AutoSize = true;
|
this.label30.AutoSize = true;
|
||||||
this.label30.Location = new System.Drawing.Point(16, 97);
|
this.label30.Location = new System.Drawing.Point(15, 97);
|
||||||
this.label30.Name = "label30";
|
this.label30.Name = "label30";
|
||||||
this.label30.Size = new System.Drawing.Size(173, 13);
|
this.label30.Size = new System.Drawing.Size(173, 13);
|
||||||
this.label30.TabIndex = 41;
|
this.label30.TabIndex = 41;
|
||||||
|
@ -1845,14 +1845,13 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
// tbDynLightCount
|
// tbDynLightCount
|
||||||
//
|
//
|
||||||
this.tbDynLightCount.BackColor = System.Drawing.SystemColors.Window;
|
this.tbDynLightCount.BackColor = System.Drawing.SystemColors.Window;
|
||||||
this.tbDynLightCount.LargeChange = 3;
|
this.tbDynLightCount.LargeChange = 1;
|
||||||
this.tbDynLightCount.Location = new System.Drawing.Point(199, 197);
|
this.tbDynLightCount.Location = new System.Drawing.Point(199, 197);
|
||||||
this.tbDynLightCount.Maximum = 32;
|
this.tbDynLightCount.Maximum = 8;
|
||||||
this.tbDynLightCount.Minimum = 1;
|
this.tbDynLightCount.Minimum = 1;
|
||||||
this.tbDynLightCount.Name = "tbDynLightCount";
|
this.tbDynLightCount.Name = "tbDynLightCount";
|
||||||
this.tbDynLightCount.Size = new System.Drawing.Size(154, 45);
|
this.tbDynLightCount.Size = new System.Drawing.Size(154, 45);
|
||||||
this.tbDynLightCount.TabIndex = 5;
|
this.tbDynLightCount.TabIndex = 5;
|
||||||
this.tbDynLightCount.TickFrequency = 4;
|
|
||||||
this.tbDynLightCount.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
|
this.tbDynLightCount.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
|
||||||
this.tbDynLightCount.Value = 1;
|
this.tbDynLightCount.Value = 1;
|
||||||
this.tbDynLightCount.ValueChanged += new System.EventHandler(this.tbDynLightCount_ValueChanged);
|
this.tbDynLightCount.ValueChanged += new System.EventHandler(this.tbDynLightCount_ValueChanged);
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
checkforupdates.Checked = General.Settings.CheckForUpdates;
|
checkforupdates.Checked = General.Settings.CheckForUpdates;
|
||||||
toolbar_gzdoom.Checked = General.Settings.GZToolbarGZDoom;
|
toolbar_gzdoom.Checked = General.Settings.GZToolbarGZDoom;
|
||||||
cbSynchCameras.Checked = General.Settings.GZSynchCameras;
|
cbSynchCameras.Checked = General.Settings.GZSynchCameras;
|
||||||
tbDynLightCount.Value = General.Clamp(General.Settings.GZMaxDynamicLights, tbDynLightCount.Minimum, tbDynLightCount.Maximum);
|
tbDynLightCount.Value = General.Clamp(General.Settings.GZMaxDynamicLights / 8, tbDynLightCount.Minimum, tbDynLightCount.Maximum);
|
||||||
labelDynLightCount.Text = General.Settings.GZMaxDynamicLights.ToString();
|
labelDynLightCount.Text = General.Settings.GZMaxDynamicLights.ToString();
|
||||||
tbDynLightSize.Value = General.Clamp((int)(General.Settings.GZDynamicLightRadius * 10), tbDynLightSize.Minimum, tbDynLightSize.Maximum);
|
tbDynLightSize.Value = General.Clamp((int)(General.Settings.GZDynamicLightRadius * 10), tbDynLightSize.Minimum, tbDynLightSize.Maximum);
|
||||||
labelDynLightSize.Text = General.Settings.GZDynamicLightRadius.ToString();
|
labelDynLightSize.Text = General.Settings.GZDynamicLightRadius.ToString();
|
||||||
|
@ -409,7 +409,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
General.Settings.GZSynchCameras = cbSynchCameras.Checked;
|
General.Settings.GZSynchCameras = cbSynchCameras.Checked;
|
||||||
General.Settings.GZMaxDynamicLights = tbDynLightCount.Value;
|
General.Settings.GZMaxDynamicLights = tbDynLightCount.Value * 8;
|
||||||
General.Settings.GZDynamicLightRadius = (tbDynLightSize.Value / 10.0f);
|
General.Settings.GZDynamicLightRadius = (tbDynLightSize.Value / 10.0f);
|
||||||
General.Settings.GZDynamicLightIntensity = (tbDynLightIntensity.Value / 10.0f);
|
General.Settings.GZDynamicLightIntensity = (tbDynLightIntensity.Value / 10.0f);
|
||||||
General.Settings.FilterAnisotropy = D3DDevice.AF_STEPS[anisotropicfiltering.Value];
|
General.Settings.FilterAnisotropy = D3DDevice.AF_STEPS[anisotropicfiltering.Value];
|
||||||
|
@ -1006,7 +1006,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
//mxd
|
//mxd
|
||||||
private void tbDynLightCount_ValueChanged(object sender, EventArgs e)
|
private void tbDynLightCount_ValueChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
labelDynLightCount.Text = tbDynLightCount.Value.ToString();
|
labelDynLightCount.Text = (tbDynLightCount.Value * 8).ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
|
|
|
@ -118,9 +118,10 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
}
|
}
|
||||||
|
|
||||||
// Texture name will be empty when skin path is embedded in the model
|
// Texture name will be empty when skin path is embedded in the model
|
||||||
string texturename = (!string.IsNullOrEmpty(mds.TextureNames[fs.ModelIndex]) ? mds.TextureNames[fs.ModelIndex].ToLowerInvariant() : string.Empty);
|
string skinname = (!string.IsNullOrEmpty(mds.SkinNames[fs.ModelIndex]) ? mds.SkinNames[fs.ModelIndex].ToLowerInvariant() : string.Empty);
|
||||||
|
|
||||||
md.TextureNames.Add(texturename);
|
md.SkinNames.Add(skinname);
|
||||||
|
md.SurfaceSkinNames.Add(mds.SurfaceSkinNames[fs.ModelIndex]);
|
||||||
md.ModelNames.Add(mds.ModelNames[fs.ModelIndex].ToLowerInvariant());
|
md.ModelNames.Add(mds.ModelNames[fs.ModelIndex].ToLowerInvariant());
|
||||||
md.FrameNames.Add(fs.FrameName);
|
md.FrameNames.Add(fs.FrameName);
|
||||||
md.FrameIndices.Add(fs.FrameIndex);
|
md.FrameIndices.Add(fs.FrameIndex);
|
||||||
|
|
|
@ -33,7 +33,8 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
|
|
||||||
#region ================== Variables
|
#region ================== Variables
|
||||||
|
|
||||||
private string[] texturenames;
|
private string[] skinnames;
|
||||||
|
private Dictionary<int, string>[] surfaceskinenames;
|
||||||
private string[] modelnames;
|
private string[] modelnames;
|
||||||
private string path;
|
private string path;
|
||||||
private Vector3 scale;
|
private Vector3 scale;
|
||||||
|
@ -51,7 +52,8 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
|
|
||||||
#region ================== Properties
|
#region ================== Properties
|
||||||
|
|
||||||
public string[] TextureNames { get { return texturenames; } }
|
public string[] SkinNames { get { return skinnames; } }
|
||||||
|
public Dictionary<int, string>[] SurfaceSkinNames { get { return surfaceskinenames; } }
|
||||||
public string[] ModelNames { get { return modelnames; } }
|
public string[] ModelNames { get { return modelnames; } }
|
||||||
public Vector3 Scale { get { return scale; } }
|
public Vector3 Scale { get { return scale; } }
|
||||||
public Vector3 Offset { get { return offset; } }
|
public Vector3 Offset { get { return offset; } }
|
||||||
|
@ -70,10 +72,15 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
|
|
||||||
internal ModeldefStructure()
|
internal ModeldefStructure()
|
||||||
{
|
{
|
||||||
texturenames = new string[MAX_MODELS];
|
skinnames = new string[MAX_MODELS];
|
||||||
modelnames = new string[MAX_MODELS];
|
modelnames = new string[MAX_MODELS];
|
||||||
frames = new Dictionary<string, HashSet<FrameStructure>>(StringComparer.OrdinalIgnoreCase);
|
frames = new Dictionary<string, HashSet<FrameStructure>>(StringComparer.OrdinalIgnoreCase);
|
||||||
scale = new Vector3(1.0f, 1.0f, 1.0f);
|
scale = new Vector3(1.0f, 1.0f, 1.0f);
|
||||||
|
surfaceskinenames = new Dictionary<int, string>[MAX_MODELS];
|
||||||
|
for(int i = 0; i < MAX_MODELS; i++)
|
||||||
|
{
|
||||||
|
surfaceskinenames[i] = new Dictionary<int, string>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -194,7 +201,72 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
}
|
}
|
||||||
|
|
||||||
// GZDoom allows skins with identical index, it uses the last one encountered
|
// GZDoom allows skins with identical index, it uses the last one encountered
|
||||||
texturenames[skinindex] = Path.Combine(path, token);
|
skinnames[skinindex] = Path.Combine(path, token);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// SurfaceSkin <int modelindex> <int surfaceindex> <string skinfile>
|
||||||
|
case "surfaceskin":
|
||||||
|
parser.SkipWhitespace(true);
|
||||||
|
|
||||||
|
// Model index
|
||||||
|
int modelindex = 0;
|
||||||
|
token = parser.ReadToken();
|
||||||
|
if(!parser.ReadSignedInt(token, ref modelindex))
|
||||||
|
{
|
||||||
|
// Not numeric!
|
||||||
|
parser.ReportError("Expected model index, but got \"" + token + "\"");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(modelindex < 0 || modelindex >= MAX_MODELS)
|
||||||
|
{
|
||||||
|
// Out of bounds
|
||||||
|
parser.ReportError("Model index must be in [0.." + (MAX_MODELS - 1) + "] range");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.SkipWhitespace(true);
|
||||||
|
|
||||||
|
// Surfaceindex index
|
||||||
|
int surfaceindex = 0;
|
||||||
|
token = parser.ReadToken();
|
||||||
|
if(!parser.ReadSignedInt(token, ref surfaceindex))
|
||||||
|
{
|
||||||
|
// Not numeric!
|
||||||
|
parser.ReportError("Expected surface index, but got \"" + token + "\"");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(surfaceindex < 0)
|
||||||
|
{
|
||||||
|
// Out of bounds
|
||||||
|
parser.ReportError("Surface index must be positive integer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.SkipWhitespace(true);
|
||||||
|
|
||||||
|
// Skin path
|
||||||
|
token = parser.StripTokenQuotes(parser.ReadToken(false)).ToLowerInvariant(); // Don't skip newline
|
||||||
|
if(string.IsNullOrEmpty(token))
|
||||||
|
{
|
||||||
|
parser.ReportError("Expected skin path");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check invalid path chars
|
||||||
|
if(!parser.CheckInvalidPathChars(token)) return false;
|
||||||
|
|
||||||
|
// Check extension
|
||||||
|
string skinext = Path.GetExtension(token);
|
||||||
|
if(Array.IndexOf(ModelData.SUPPORTED_TEXTURE_EXTENSIONS, skinext) == -1)
|
||||||
|
{
|
||||||
|
parser.ReportError("Image format \"" + skinext + "\" is not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store
|
||||||
|
surfaceskinenames[modelindex][surfaceindex] = Path.Combine(path, token);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "scale":
|
case "scale":
|
||||||
|
@ -511,11 +583,21 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check skin-model associations
|
// Check skin-model associations
|
||||||
for(int i = 0; i < texturenames.Length; i++)
|
for(int i = 0; i < skinnames.Length; i++)
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrEmpty(texturenames[i]) && string.IsNullOrEmpty(modelnames[i]))
|
if(!string.IsNullOrEmpty(skinnames[i]) && string.IsNullOrEmpty(modelnames[i]))
|
||||||
{
|
{
|
||||||
parser.ReportError("No model is defined for skin " + i + ":\"" + texturenames[i] + "\"");
|
parser.ReportError("No model is defined for skin " + i + ":\"" + skinnames[i] + "\"");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check surfaceskin-model associations
|
||||||
|
for(int i = 0; i < surfaceskinenames.Length; i++)
|
||||||
|
{
|
||||||
|
if(surfaceskinenames[i].Count > 0 && string.IsNullOrEmpty(modelnames[i]))
|
||||||
|
{
|
||||||
|
parser.ReportError("No model is defined for surface skin " + i);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue