diff --git a/Source/Core/GZBuilder/Data/ModelData.cs b/Source/Core/GZBuilder/Data/ModelData.cs
index c3299873..5424ba5e 100755
--- a/Source/Core/GZBuilder/Data/ModelData.cs
+++ b/Source/Core/GZBuilder/Data/ModelData.cs
@@ -22,6 +22,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
 
 		private ModelLoadState loadstate;
 		private Vector3f scale;
+		private Vector3f rotationcenter;
 		private Matrix transform;
         private Matrix transformrotation;
 		private Matrix transformstretched;
@@ -40,6 +41,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
 		internal GZModel Model;
 
 		internal Vector3f Scale { get { return scale; } }
+		internal Vector3f RotationCenter { get { return rotationcenter; } set { rotationcenter = value; } }
 		internal Matrix Transform { get { /* return (General.Settings.GZStretchView ? transformstretched : transform); */ return transformstretched; } }
         internal Matrix TransformRotation { get { return transformrotation; } }
 		internal bool OverridePalette; // Used for voxel models only 
@@ -47,6 +49,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
 		internal bool InheritActorPitch;
 		internal bool UseActorPitch;
 		internal bool UseActorRoll;
+		internal bool UseRotationCenter;
 
 		internal bool IsVoxel;
 
diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs
index cb934bf4..a836a5f7 100755
--- a/Source/Core/Rendering/Renderer2D.cs
+++ b/Source/Core/Rendering/Renderer2D.cs
@@ -1544,7 +1544,12 @@ namespace CodeImp.DoomBuilder.Rendering
 							Matrix modelscale = Matrix.Scaling((float)sx, (float)sx, (float)sy);
 							Matrix rotation = Matrix.RotationY((float)-t.RollRad) * Matrix.RotationX((float)-t.PitchRad) * Matrix.RotationZ((float)t.Angle);
 							Matrix position = Matrix.Translation((float)screenpos.x, (float)screenpos.y, 0.0f);
-							Matrix world = General.Map.Data.ModeldefEntries[t.Type].Transform * modelscale * rotation * viewscale * position;
+							Matrix world;
+
+							if (General.Map.Data.ModeldefEntries[t.Type].UseRotationCenter)
+								world = General.Map.Data.ModeldefEntries[t.Type].Transform * modelscale * Matrix.Translation(-General.Map.Data.ModeldefEntries[t.Type].RotationCenter) * rotation * Matrix.Translation(General.Map.Data.ModeldefEntries[t.Type].RotationCenter) * viewscale * position;
+							else
+								world = General.Map.Data.ModeldefEntries[t.Type].Transform * modelscale * rotation * viewscale * position;
 
 							SetThings2DTransformSettings(world);
 
diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs
index 9b15aad8..f1c72145 100755
--- a/Source/Core/Rendering/Renderer3D.cs
+++ b/Source/Core/Rendering/Renderer3D.cs
@@ -1603,7 +1603,10 @@ namespace CodeImp.DoomBuilder.Rendering
 				Matrix modelscale = Matrix.Scaling((float)sx, (float)sx, (float)sy);
 				Matrix modelrotation = Matrix.RotationY((float)-t.Thing.RollRad) * Matrix.RotationX((float)-t.Thing.PitchRad) * Matrix.RotationZ((float)t.Thing.Angle);
 
-				world = General.Map.Data.ModeldefEntries[t.Thing.Type].Transform * modelscale * modelrotation * t.Position;
+				if(General.Map.Data.ModeldefEntries[t.Thing.Type].UseRotationCenter)
+					world = General.Map.Data.ModeldefEntries[t.Thing.Type].Transform * modelscale * Matrix.Translation(-General.Map.Data.ModeldefEntries[t.Thing.Type].RotationCenter) * modelrotation * Matrix.Translation(General.Map.Data.ModeldefEntries[t.Thing.Type].RotationCenter) * t.Position;
+				else
+					world = General.Map.Data.ModeldefEntries[t.Thing.Type].Transform * modelscale * modelrotation  * t.Position;
                 graphics.SetUniform(UniformName.world, world);
 
                 // Set variables for fog rendering
diff --git a/Source/Core/ZDoom/ModeldefParser.cs b/Source/Core/ZDoom/ModeldefParser.cs
index 8e69d0a2..a06420d3 100755
--- a/Source/Core/ZDoom/ModeldefParser.cs
+++ b/Source/Core/ZDoom/ModeldefParser.cs
@@ -45,6 +45,9 @@ namespace CodeImp.DoomBuilder.ZDoom
 			this.actorsbyclass = actorsbyclass;
 			this.entries = new Dictionary<string, ModelData>(StringComparer.OrdinalIgnoreCase);
             this.parsedlumps = new HashSet<string>();
+
+			// We don't want the '-' as a special token because commands can contain them (like "rotation-center")
+			specialtokens = ":{}+\n;";
 		}
 
 		#endregion
@@ -187,7 +190,7 @@ namespace CodeImp.DoomBuilder.ZDoom
 								if(mds.Frames.ContainsKey(targetsprite))
 								{
 									// Create model data
-									ModelData md = new ModelData { InheritActorPitch = mds.InheritActorPitch, UseActorPitch = mds.UseActorPitch, UseActorRoll = mds.UseActorRoll, Path = mds.DataPath };
+									ModelData md = new ModelData { InheritActorPitch = mds.InheritActorPitch, UseActorPitch = mds.UseActorPitch, UseActorRoll = mds.UseActorRoll, UseRotationCenter = mds.UseRotationCenter, RotationCenter = mds.RotationCenter, Path = mds.DataPath };
 
 									// Things are complicated in GZDoom...
 									Matrix moffset = Matrix.Translation(mds.Offset.Y, -mds.Offset.X, mds.Offset.Z);
diff --git a/Source/Core/ZDoom/ModeldefStructure.cs b/Source/Core/ZDoom/ModeldefStructure.cs
index ef52cf95..dee2d052 100755
--- a/Source/Core/ZDoom/ModeldefStructure.cs
+++ b/Source/Core/ZDoom/ModeldefStructure.cs
@@ -34,12 +34,14 @@ namespace CodeImp.DoomBuilder.ZDoom
 		private string path;
 		private Vector3f scale;
 		private Vector3f offset;
+		private Vector3f rotationcenter;
 		private float angleoffset;
 		private float pitchoffset;
 		private float rolloffset;
 		private bool inheritactorpitch;
 		private bool useactorpitch;
 		private bool useactorroll;
+		private bool userotationcenter;
 
 		private Dictionary<string, HashSet<FrameStructure>> frames;
 
@@ -52,12 +54,14 @@ namespace CodeImp.DoomBuilder.ZDoom
 		public Dictionary<int, string> ModelNames { get { return modelnames; } }
 		public Vector3f Scale { get { return scale; } }
 		public Vector3f Offset { get { return offset; } }
+		public Vector3f RotationCenter { get { return rotationcenter; } }
 		public float AngleOffset { get { return angleoffset; } }
 		public float PitchOffset { get { return pitchoffset; } }
 		public float RollOffset { get { return rolloffset; } }
 		public bool InheritActorPitch { get { return inheritactorpitch; } }
 		public bool UseActorPitch { get { return useactorpitch; } }
 		public bool UseActorRoll { get { return useactorroll; } }
+		public bool UseRotationCenter { get { return userotationcenter; } }
 		public string DataPath { get { return path; } } // biwa
 
 		public Dictionary<string, HashSet<FrameStructure>> Frames { get { return frames; } }
@@ -351,6 +355,35 @@ namespace CodeImp.DoomBuilder.ZDoom
 						}
 						break;
 
+					case "rotation-center":
+						parser.SkipWhitespace(true);
+						token = parser.ReadToken();
+						if (!parser.ReadSignedFloat(token, ref rotationcenter.X))
+						{
+							// Not numeric!
+							parser.ReportError("Expected rotation center X value, but got \"" + token + "\"");
+							return false;
+						}
+
+						parser.SkipWhitespace(true);
+						token = parser.ReadToken();
+						if (!parser.ReadSignedFloat(token, ref rotationcenter.Y))
+						{
+							// Not numeric!
+							parser.ReportError("Expected rotation center Y value, but got \"" + token + "\"");
+							return false;
+						}
+
+						parser.SkipWhitespace(true);
+						token = parser.ReadToken();
+						if (!parser.ReadSignedFloat(token, ref rotationcenter.Z))
+						{
+							// Not numeric!
+							parser.ReportError("Expected rotation center Z value, but got \"" + token + "\"");
+							return false;
+						}
+						break;
+
 					case "useactorpitch":
 						inheritactorpitch = false;
 						useactorpitch = true;
@@ -360,6 +393,11 @@ namespace CodeImp.DoomBuilder.ZDoom
 						useactorroll = true;
 						break;
 
+					case "rotating":
+					case "userotationcenter":
+						userotationcenter = true;
+						break;
+
 					case "inheritactorpitch":
 						inheritactorpitch = true;
 						useactorpitch = false;