#region ================== Namespaces using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.Map; #endregion namespace CodeImp.DoomBuilder.VisualModes { /// <summary> /// This class provides the camera in Visual Mode /// </summary> public class VisualCamera { #region ================== Constants private const float ANGLE_FROM_MOUSE = 0.0001f; public const float MAX_ANGLEZ_LOW = 91f / Angle2D.PIDEG; public const float MAX_ANGLEZ_HIGH = (360f - 91f) / Angle2D.PIDEG; public const float THING_Z_OFFSET = 41.0f; #endregion #region ================== Variables // Properties private Vector3D position; private Vector3D target; private Vector3D movemultiplier; private float anglexy, anglez; private Sector sector; private float gravity = 1.0f; //mxd #endregion #region ================== Properties public Vector3D Position { get { return position; } set { position = value; } } public Vector3D Target { get { return target; } } public float AngleXY { get { return anglexy; } set { anglexy = value; } } public float AngleZ { get { return anglez; } set { anglez = value; } } public Sector Sector { get { return sector; } internal set { sector = value; UpdateGravity(); } } //mxd public Vector3D MoveMultiplier { get { return movemultiplier; } set { movemultiplier = value; } } public float Gravity { get { return gravity; } } //mxd #endregion #region ================== Constructor / Destructor // Constructor public VisualCamera() { // Initialize movemultiplier = new Vector3D(1.0f, 1.0f, 1.0f); anglexy = 0.0f; anglez = Angle2D.PI; sector = null; PositionAtThing(); } #endregion #region ================== Methods // Mouse input internal void ProcessMouseInput(Vector2D delta) { // Change camera angles with the mouse changes anglexy -= delta.x * ANGLE_FROM_MOUSE; if(General.Settings.InvertYAxis) anglez -= delta.y * ANGLE_FROM_MOUSE; else anglez += delta.y * ANGLE_FROM_MOUSE; // Normalize angles anglexy = Angle2D.Normalized(anglexy); anglez = Angle2D.Normalized(anglez); // Limit vertical angle if(anglez < MAX_ANGLEZ_LOW) anglez = MAX_ANGLEZ_LOW; if(anglez > MAX_ANGLEZ_HIGH) anglez = MAX_ANGLEZ_HIGH; } // Key input internal void ProcessMovement(Vector3D deltavec) { // Calculate camera direction vectors Vector3D camvec = Vector3D.FromAngleXYZ(anglexy, anglez); // Position the camera position += deltavec; // Target the camera target = position + camvec; } // This applies the position and angle from the 3D Camera Thing // Returns false when it couldn't find a 3D Camera Thing public virtual bool PositionAtThing() { if(General.Settings.GZSynchCameras) return true; //mxd Thing modething = null; // Find a 3D Mode thing foreach(Thing t in General.Map.Map.Things) { if(t.Type == General.Map.Config.Start3DModeThingType) { modething = t; break; //mxd } } // Found one? if(modething != null) { modething.DetermineSector(); float z = modething.Position.z; if(modething.Sector != null) z += modething.Sector.FloorHeight; // Position camera here Vector3D wantedposition = new Vector3D(modething.Position.x, modething.Position.y, z + THING_Z_OFFSET); Vector3D delta = position - wantedposition; if(delta.GetLength() > 1.0f) position = wantedposition; // Change angle float wantedanglexy = modething.Angle + Angle2D.PI; if(anglexy != wantedanglexy) { anglexy = wantedanglexy; anglez = Angle2D.PI; } return true; } return false; } // This applies the camera position and angle to the 3D Camera Thing // Returns false when it couldn't find a 3D Camera Thing public virtual bool ApplyToThing() { if(General.Settings.GZSynchCameras) return true; //mxd Thing modething = null; // Find a 3D Mode thing foreach(Thing t in General.Map.Map.Things) { if(t.Type == General.Map.Config.Start3DModeThingType) { modething = t; break; //mxd } } // Found one? if(modething != null) { int z = (int)position.z; //mxd if(sector != null) z -= sector.FloorHeight; // Position the thing to match camera modething.Move((int)position.x, (int)position.y, z - THING_Z_OFFSET); modething.Rotate(anglexy - Angle2D.PI); return true; } return false; } //mxd private void UpdateGravity() { if(!General.Map.UDMF || sector == null) return; gravity = sector.Fields.GetValue("gravity", 1.0f); } #endregion } }