diff --git a/Source/Core/GZBuilder/Data/ModelData.cs b/Source/Core/GZBuilder/Data/ModelData.cs index 5fcfcd6e..5e26d11b 100644 --- a/Source/Core/GZBuilder/Data/ModelData.cs +++ b/Source/Core/GZBuilder/Data/ModelData.cs @@ -1,36 +1,55 @@ -using System.Collections.Generic; +#region ================== Namespaces + +using System.Collections.Generic; +using CodeImp.DoomBuilder.Geometry; +using CodeImp.DoomBuilder.GZBuilder.MD3; using SlimDX; using SlimDX.Direct3D9; -using CodeImp.DoomBuilder.GZBuilder.MD3; + +#endregion namespace CodeImp.DoomBuilder.GZBuilder.Data { internal sealed class ModelData { + #region ================== Variables + + private ModelLoadState loadstate; + + #endregion + + #region ================== Properties + internal List ModelNames; internal List TextureNames; internal GZModel Model; - private ModelLoadState loadstate; - public ModelLoadState LoadState { get { return loadstate; } internal set { loadstate = value; } } - internal Matrix Scale; - internal float zOffset; + internal Vector2D OffsetXY; + internal float OffsetZ; internal float AngleOffset; //in radians internal float PitchOffset; //in radians internal float RollOffset; //in radians internal bool OverridePalette; //used for voxel models only - internal bool IsVoxel; internal bool InheritActorPitch; internal bool InheritActorRoll; + internal bool IsVoxel; + + public ModelLoadState LoadState { get { return loadstate; } internal set { loadstate = value; } } + + #endregion + + #region ================== Constructor / Disposer + internal ModelData() { ModelNames = new List(); TextureNames = new List(); Scale = Matrix.Identity; + OffsetXY = new Vector2D(); } internal void Dispose() @@ -42,5 +61,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data loadstate = ModelLoadState.None; } } + + #endregion } } diff --git a/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs b/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs index 0c49ffb2..53bfbf3a 100644 --- a/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs +++ b/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs @@ -21,7 +21,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom string[] modelNames = new string[4]; string path = ""; Vector3 scale = new Vector3(1, 1, 1); - float zOffset = 0; + Vector3 offset = new Vector3(); float angleOffset = 0; float pitchOffset = 0; float rollOffset = 0; @@ -155,34 +155,62 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom case "scale": parser.SkipWhitespace(true); - token = parser.StripTokenQuotes(parser.ReadToken()); if(!parser.ReadSignedFloat(token, ref scale.X)) { // Not numeric! - General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected scale X value, but got '" + token + "'"); + General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected Scale X value, but got '" + token + "'"); gotErrors = true; break; } parser.SkipWhitespace(true); - token = parser.StripTokenQuotes(parser.ReadToken()); if(!parser.ReadSignedFloat(token, ref scale.Y)) { // Not numeric! - General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected scale Y value, but got '" + token + "'"); + General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected Scale Y value, but got '" + token + "'"); gotErrors = true; break; } parser.SkipWhitespace(true); - token = parser.StripTokenQuotes(parser.ReadToken()); if(!parser.ReadSignedFloat(token, ref scale.Z)) { // Not numeric! - General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected scale Z value, but got '" + token + "'"); + General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected Scale Z value, but got '" + token + "'"); + gotErrors = true; + } + break; + + case "offset": + parser.SkipWhitespace(true); + token = parser.StripTokenQuotes(parser.ReadToken()); + if(!parser.ReadSignedFloat(token, ref offset.X)) + { + // Not numeric! + General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected Offset X value, but got '" + token + "'"); + gotErrors = true; + break; + } + + parser.SkipWhitespace(true); + token = parser.StripTokenQuotes(parser.ReadToken()); + if(!parser.ReadSignedFloat(token, ref offset.Y)) + { + // Not numeric! + General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected Offset Y value, but got '" + token + "'"); + gotErrors = true; + break; + } + + parser.SkipWhitespace(true); + token = parser.StripTokenQuotes(parser.ReadToken()); + if(!parser.ReadSignedFloat(token, ref offset.Z)) + { + // Not numeric! + General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected Offset Z value, but got '" + token + "'"); gotErrors = true; } break; @@ -191,7 +219,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom parser.SkipWhitespace(true); token = parser.StripTokenQuotes(parser.ReadToken()); - if(!parser.ReadSignedFloat(token, ref zOffset)) + if(!parser.ReadSignedFloat(token, ref offset.Z)) { // Not numeric! General.ErrorLogger.Add(ErrorType.Error, "Error in " + parser.Source + " at line " + parser.GetCurrentLineNumber() + ": expected ZOffset value, but got '" + token + "'"); @@ -382,7 +410,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom //classname is set in ModeldefParser ModelData mde = new ModelData(); mde.Scale = Matrix.Scaling(scale); - mde.zOffset = zOffset; + mde.OffsetXY = new Vector2D(offset.Y, -offset.X); // Things are complicated in GZDoom... + mde.OffsetZ = offset.Z; mde.AngleOffset = Angle2D.DegToRad(angleOffset); mde.RollOffset = Angle2D.DegToRad(rollOffset); mde.PitchOffset = Angle2D.DegToRad(pitchOffset); diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index 9ddac758..ac01fd3f 100644 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -1784,6 +1784,10 @@ namespace CodeImp.DoomBuilder { // Set this to false so we can see if errors are added General.ErrorLogger.IsErrorAdded = false; +#if DEBUG + DebugConsole.Clear(); +#endif + ReloadResources(); if (General.ErrorLogger.IsErrorAdded) diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index f73d9344..7c7dc3a9 100644 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -1339,7 +1339,7 @@ namespace CodeImp.DoomBuilder.Rendering foreach(Thing t in group.Value) { if(General.Settings.GZDrawModelsMode == ModelRenderMode.SELECTION && !t.Selected) continue; - Vector2D screenpos = ((Vector2D)t.Position).GetTransformed(translatex, translatey, scale, -scale); + Vector2D screenpos = ((Vector2D)t.Position + General.Map.Data.ModeldefEntries[t.Type].OffsetXY.GetScaled(t.ScaleX).GetRotated(t.Angle)).GetTransformed(translatex, translatey, scale, -scale); float modelScale = scale * t.ActorScale.Width * t.ScaleX; //should we render this model? @@ -1353,12 +1353,14 @@ namespace CodeImp.DoomBuilder.Rendering { float sx = t.ScaleX * t.ActorScale.Width; float sy = t.ScaleY * t.ActorScale.Height; - Matrix modelcale = Matrix.Scaling(sx, sx, sy) * General.Map.Data.ModeldefEntries[t.Type].Scale; + + Matrix modelscale = Matrix.Scaling(sx, sx, sy); + Matrix mdescale = General.Map.Data.ModeldefEntries[t.Type].Scale; Matrix rotation = Matrix.RotationY(-(t.RollRad + General.Map.Data.ModeldefEntries[t.Type].RollOffset)) * Matrix.RotationX(-(t.PitchRad + General.Map.Data.ModeldefEntries[t.Type].PitchOffset)) * Matrix.RotationZ(t.Angle + General.Map.Data.ModeldefEntries[t.Type].AngleOffset); Matrix position = Matrix.Translation(screenpos.x, screenpos.y, 0.0f); - Matrix world = rotation * modelcale * viewscale * position; + Matrix world = mdescale * rotation * modelscale * viewscale * position; graphics.Shaders.Things2D.SetTransformSettings(world); graphics.Shaders.Things2D.ApplySettings(); diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs index 5fb5cce5..d02ce23c 100644 --- a/Source/Core/Rendering/Renderer3D.cs +++ b/Source/Core/Rendering/Renderer3D.cs @@ -1122,13 +1122,18 @@ namespace CodeImp.DoomBuilder.Rendering // Create the matrix for positioning / rotation float sx = t.Thing.ScaleX * t.Thing.ActorScale.Width; float sy = t.Thing.ScaleY * t.Thing.ActorScale.Height * viewstretch; - Matrix modelcale = Matrix.Scaling(sx, sx, sy) * General.Map.Data.ModeldefEntries[t.Thing.Type].Scale; + + Matrix modelscale = Matrix.Scaling(sx, sx, sy); + Matrix mdescale = General.Map.Data.ModeldefEntries[t.Thing.Type].Scale; + Matrix rotation = Matrix.RotationY(-(t.Thing.RollRad + General.Map.Data.ModeldefEntries[t.Thing.Type].RollOffset)) * Matrix.RotationX(-(t.Thing.PitchRad + General.Map.Data.ModeldefEntries[t.Thing.Type].PitchOffset)) * Matrix.RotationZ(t.Thing.Angle + General.Map.Data.ModeldefEntries[t.Thing.Type].AngleOffset); - Matrix position = t.Position * Matrix.Translation(new Vector3(0, 0, General.Map.Data.ModeldefEntries[t.Thing.Type].zOffset * t.Thing.ScaleY)); + + Vector2D offset2d = General.Map.Data.ModeldefEntries[t.Thing.Type].OffsetXY.GetScaled(t.Thing.ScaleX).GetRotated(t.Thing.Angle); + Matrix position = Matrix.Translation(offset2d.x, offset2d.y, General.Map.Data.ModeldefEntries[t.Thing.Type].OffsetZ * t.Thing.ScaleY) * t.Position; - world = rotation * modelcale * position; + world = mdescale * rotation * modelscale * position; ApplyMatrices3D(); //mxd. set variables for fog rendering