removed camera code from VisualMode and created separate VisualCamera class in MapManager so that it is retained in between mode switches (keeps exact angle and position of camera intact)

This commit is contained in:
codeimp 2009-01-10 00:26:24 +00:00
parent 5adc7fd505
commit a67727fe46
6 changed files with 216 additions and 95 deletions

View file

@ -685,6 +685,7 @@
<Compile Include="IO\SerializerStream.cs" />
<Compile Include="Rendering\RenderPasses.cs" />
<Compile Include="VisualModes\VisualBlockEntry.cs" />
<Compile Include="VisualModes\VisualCamera.cs" />
<Compile Include="VisualModes\VisualPickResult.cs" />
<Compile Include="VisualModes\VisualThing.cs" />
<None Include="Resources\Script2.png" />

View file

@ -268,8 +268,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Select button pressed
public virtual void OnSelectBegin()
{
dragstartanglexy = mode.CameraAngleXY;
dragstartanglez = mode.CameraAngleZ;
dragstartanglexy = General.Map.VisualCamera.AngleXY;
dragstartanglez = General.Map.VisualCamera.AngleZ;
dragorigin = pickintersect;
startoffsetx = Sidedef.OffsetX;
startoffsety = Sidedef.OffsetY;
@ -321,8 +321,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(General.Actions.CheckActionActive(General.ThisAssembly, "visualselect"))
{
// Check if tolerance is exceeded to start UV dragging
float deltaxy = mode.CameraAngleXY - dragstartanglexy;
float deltaz = mode.CameraAngleZ - dragstartanglez;
float deltaxy = General.Map.VisualCamera.AngleXY - dragstartanglexy;
float deltaz = General.Map.VisualCamera.AngleZ - dragstartanglez;
if((Math.Abs(deltaxy) + Math.Abs(deltaz)) > DRAG_ANGLE_TOLERANCE)
{
General.Map.UndoRedo.CreateUndo("Change texture offsets");
@ -342,9 +342,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
float u_ray;
// Calculate intersection position
Line2D ray = new Line2D(mode.CameraPosition, mode.CameraTarget);
Line2D ray = new Line2D(General.Map.VisualCamera.Position, General.Map.VisualCamera.Target);
Sidedef.Line.Line.GetIntersection(ray, out u_ray);
Vector3D intersect = mode.CameraPosition + (mode.CameraTarget - mode.CameraPosition) * u_ray;
Vector3D intersect = General.Map.VisualCamera.Position + (General.Map.VisualCamera.Target - General.Map.VisualCamera.Position) * u_ray;
// Calculate offsets
Vector3D dragdelta = intersect - dragorigin;

View file

@ -146,8 +146,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
private void PickTarget()
{
// Find the object we are aiming at
Vector3D start = CameraPosition;
Vector3D delta = CameraTarget - CameraPosition;
Vector3D start = General.Map.VisualCamera.Position;
Vector3D delta = General.Map.VisualCamera.Target - General.Map.VisualCamera.Position;
delta = delta.GetFixedLength(General.Settings.ViewDistance * PICK_RANGE);
VisualPickResult newtarget = PickObject(start, start + delta);
@ -205,32 +205,34 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Setup the move multiplier depending on gravity
Vector3D movemultiplier = new Vector3D(1.0f, 1.0f, 1.0f);
if(BuilderPlug.Me.UseGravity) movemultiplier.z = 0.0f;
base.MoveMultiplier = movemultiplier;
General.Map.VisualCamera.MoveMultiplier = movemultiplier;
// Apply gravity?
if(BuilderPlug.Me.UseGravity && (CameraSector != null))
if(BuilderPlug.Me.UseGravity && (General.Map.VisualCamera.Sector != null))
{
// Camera below floor level?
if(base.CameraPosition.z <= (CameraSector.FloorHeight + CAMERA_FLOOR_OFFSET + 0.1f))
if(General.Map.VisualCamera.Position.z <= (General.Map.VisualCamera.Sector.FloorHeight + CAMERA_FLOOR_OFFSET + 0.1f))
{
// Stay above floor
gravity = new Vector3D(0.0f, 0.0f, 0.0f);
base.CameraPosition = new Vector3D(base.CameraPosition.x, base.CameraPosition.y,
CameraSector.FloorHeight + CAMERA_FLOOR_OFFSET);
General.Map.VisualCamera.Position = new Vector3D(General.Map.VisualCamera.Position.x,
General.Map.VisualCamera.Position.y,
General.Map.VisualCamera.Sector.FloorHeight + CAMERA_FLOOR_OFFSET);
}
else
{
// Fall down
gravity += new Vector3D(0.0f, 0.0f, (float)(GRAVITY * deltatime));
base.CameraPosition = base.CameraPosition + gravity;
General.Map.VisualCamera.Position += gravity;
}
// Camera above ceiling level?
if(base.CameraPosition.z >= (CameraSector.CeilHeight - CAMERA_CEILING_OFFSET - 0.1f))
if(General.Map.VisualCamera.Position.z >= (General.Map.VisualCamera.Sector.CeilHeight - CAMERA_CEILING_OFFSET - 0.1f))
{
// Stay below ceiling
base.CameraPosition = new Vector3D(base.CameraPosition.x, base.CameraPosition.y,
CameraSector.CeilHeight - CAMERA_CEILING_OFFSET);
General.Map.VisualCamera.Position = new Vector3D(General.Map.VisualCamera.Position.x,
General.Map.VisualCamera.Position.y,
General.Map.VisualCamera.Sector.CeilHeight - CAMERA_CEILING_OFFSET);
}
}
else

View file

@ -35,6 +35,7 @@ using CodeImp.DoomBuilder.Actions;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Plugins;
using CodeImp.DoomBuilder.Compilers;
using CodeImp.DoomBuilder.VisualModes;
#endregion
@ -86,6 +87,7 @@ namespace CodeImp.DoomBuilder
private ThingsFilter thingsfilter;
private ScriptEditorForm scriptwindow;
private List<CompilerError> errors;
private VisualCamera visualcamera;
// Disposing
private bool isdisposed = false;
@ -117,6 +119,7 @@ namespace CodeImp.DoomBuilder
public ThingsFilter ThingsFilter { get { return thingsfilter; } }
internal List<CompilerError> Errors { get { return errors; } }
internal ScriptEditorForm ScriptEditor { get { return scriptwindow; } }
public VisualCamera VisualCamera { get { return visualcamera; } set { visualcamera = value; } }
public bool IsScriptsWindowOpen { get { return (scriptwindow != null) && !scriptwindow.IsDisposed; } }
#endregion
@ -172,6 +175,7 @@ namespace CodeImp.DoomBuilder
if(renderer2d != null) renderer2d.Dispose();
if(renderer3d != null) renderer3d.Dispose();
if(graphics != null) graphics.Dispose();
visualcamera = null;
grid = null;
launcher = null;
copypaste = null;
@ -268,7 +272,8 @@ namespace CodeImp.DoomBuilder
// Bind any methods
General.Actions.BindMethods(this);
// Set default mode
// Set defaults
this.visualcamera = new VisualCamera();
General.Editing.ChangeMode("VerticesMode");
ClassicMode cmode = (General.Editing.Mode as ClassicMode);
if(cmode != null) cmode.SetZoom(0.5f);
@ -292,7 +297,7 @@ namespace CodeImp.DoomBuilder
this.filepathname = filepathname;
this.changed = false;
this.options = options;
General.WriteLogLine("Opening map '" + options.CurrentName + "' with configuration '" + options.ConfigFile + "'");
// Initiate graphics
@ -357,7 +362,8 @@ namespace CodeImp.DoomBuilder
// Bind any methods
General.Actions.BindMethods(this);
// Set default mode
// Set defaults
this.visualcamera = new VisualCamera();
General.Editing.ChangeMode("VerticesMode");
renderer2d.SetViewMode((ViewMode)General.Settings.DefaultViewMode);
@ -1326,7 +1332,8 @@ namespace CodeImp.DoomBuilder
// Let the plugin and editing mode know
General.Plugins.OnMapSetChangeBegin();
if(General.Editing.Mode != null) General.Editing.Mode.OnMapSetChangeBegin();
this.visualcamera.Sector = null;
// Can't have a selection in an old map set
map.ClearAllSelected();

View file

@ -0,0 +1,155 @@
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Map;
#endregion
namespace CodeImp.DoomBuilder.VisualModes
{
public class VisualCamera
{
#region ================== Constants
private const float ANGLE_FROM_MOUSE = 0.0001f;
public const float MAX_ANGLEZ_LOW = 100f / Angle2D.PIDEG;
public const float MAX_ANGLEZ_HIGH = (360f - 100f) / Angle2D.PIDEG;
#endregion
#region ================== Variables
// Properties
private Vector3D position;
private Vector3D target;
private Vector3D movemultiplier;
private float anglexy, anglez;
private Sector sector;
#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; } }
public Vector3D MoveMultiplier { get { return movemultiplier; } set { movemultiplier = value; } }
#endregion
#region ================== Constructor / Destructor
// Constructor
public VisualCamera()
{
// Initialize
this.movemultiplier = new Vector3D(1.0f, 1.0f, 1.0f);
this.position = position;
this.anglexy = 0.0f;
this.anglez = Angle2D.PI;
this.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;
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 bool PositionAtThing()
{
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;
// Found one?
if(modething != null)
{
int z = 0;
if(sector != null)
z = (int)position.z - sector.FloorHeight;
// Position camera here
modething.DetermineSector();
position = modething.Position + new Vector3D(0.0f, 0.0f, 96.0f);
anglexy = modething.Angle + Angle2D.PI;
anglez = Angle2D.PI;
return true;
}
else
{
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 bool ApplyToThing()
{
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;
// Found one?
if(modething != null)
{
int z = 0;
if(sector != null)
z = (int)position.z - sector.FloorHeight;
// Position the thing to match camera
modething.Move((int)position.x, (int)position.y, z);
modething.Rotate(anglexy - Angle2D.PI);
return true;
}
else
{
return false;
}
}
#endregion
}
}

View file

@ -45,9 +45,6 @@ namespace CodeImp.DoomBuilder.VisualModes
{
#region ================== Constants
private const float ANGLE_FROM_MOUSE = 0.0001f;
public const float MAX_ANGLEZ_LOW = 100f / Angle2D.PIDEG;
public const float MAX_ANGLEZ_HIGH = (360f - 100f) / Angle2D.PIDEG;
private const double MOVE_SPEED_MULTIPLIER = 0.001d;
#endregion
@ -61,13 +58,6 @@ namespace CodeImp.DoomBuilder.VisualModes
protected IRenderer3D renderer;
private Renderer3D renderer3d;
// Camera
private Vector3D campos;
private Vector3D camtarget;
private Vector3D movemultiplier;
private float camanglexy, camanglez;
private Sector camsector;
// Options
private bool processgeometry;
private bool processthings;
@ -92,14 +82,8 @@ namespace CodeImp.DoomBuilder.VisualModes
#region ================== Properties
public Vector3D CameraPosition { get { return campos; } set { campos = value; } }
public Vector3D CameraTarget { get { return camtarget; } }
public float CameraAngleXY { get { return camanglexy; } set { camanglexy = value; } }
public float CameraAngleZ { get { return camanglez; } set { camanglez = value; } }
public Sector CameraSector { get { return camsector; } }
public bool ProcessGeometry { get { return processgeometry; } set { processgeometry = value; } }
public bool ProcessThings { get { return processthings; } set { processthings = value; } }
public Vector3D MoveMultiplier { get { return movemultiplier; } set { movemultiplier = value; } }
public VisualBlockMap BlockMap { get { return blockmap; } }
#endregion
@ -114,9 +98,6 @@ namespace CodeImp.DoomBuilder.VisualModes
// Initialize
this.renderer = General.Map.Renderer3D;
this.renderer3d = (Renderer3D)General.Map.Renderer3D;
this.campos = new Vector3D(0.0f, 0.0f, 96.0f);
this.movemultiplier = new Vector3D(1.0f, 1.0f, 1.0f);
this.camanglez = Angle2D.PI;
this.blockmap = new VisualBlockMap();
this.allsectors = new Dictionary<Sector, VisualSector>(General.Map.Map.Sectors.Count);
this.allthings = new Dictionary<Thing,VisualThing>(General.Map.Map.Things.Count);
@ -161,24 +142,10 @@ namespace CodeImp.DoomBuilder.VisualModes
// Update the used textures
General.Map.Data.UpdateUsedTextures();
// Fill the blockmap
FillBlockMap();
// Find a 3D Mode thing
foreach(Thing t in General.Map.Map.Things)
if(t.Type == General.Map.Config.Start3DModeThingType) modething = t;
// Found one?
if(modething != null)
{
// Position camera here
modething.DetermineSector();
campos = modething.Position + new Vector3D(0.0f, 0.0f, 96.0f);
camanglexy = modething.Angle + Angle2D.PI;
camanglez = Angle2D.PI;
}
// Start special input mode
General.Interface.SetProcessorState(true);
General.Interface.StartExclusiveMouseInput();
@ -197,13 +164,11 @@ namespace CodeImp.DoomBuilder.VisualModes
foreach(KeyValuePair<Thing, VisualThing> vt in allthings)
vt.Value.Dispose();
// Do we have a 3D Mode thing?
if(modething != null)
{
// Position the thing to match camera
modething.Move((int)campos.x, (int)campos.y, 0);
modething.Rotate(camanglexy - Angle2D.PI);
}
// Apply camera position to thing
General.Map.VisualCamera.ApplyToThing();
// Do not leave the sector on the camera
General.Map.VisualCamera.Sector = null;
// Stop special input mode
General.Interface.SetProcessorState(false);
@ -256,18 +221,7 @@ namespace CodeImp.DoomBuilder.VisualModes
public override void OnMouseInput(Vector2D delta)
{
base.OnMouseInput(delta);
// Change camera angles with the mouse changes
camanglexy -= delta.x * ANGLE_FROM_MOUSE;
camanglez += delta.y * ANGLE_FROM_MOUSE;
// Normalize angles
camanglexy = Angle2D.Normalized(camanglexy);
camanglez = Angle2D.Normalized(camanglez);
// Limit vertical angle
if(camanglez < MAX_ANGLEZ_LOW) camanglez = MAX_ANGLEZ_LOW;
if(camanglez > MAX_ANGLEZ_HIGH) camanglez = MAX_ANGLEZ_HIGH;
General.Map.VisualCamera.ProcessMouseInput(delta);
}
[BeginAction("moveforward", BaseAction = true)]
@ -338,7 +292,7 @@ namespace CodeImp.DoomBuilder.VisualModes
private void DoCulling()
{
Dictionary<Linedef, Linedef> visiblelines = new Dictionary<Linedef, Linedef>(200);
Vector2D campos2d = (Vector2D)campos;
Vector2D campos2d = (Vector2D)General.Map.VisualCamera.Position;
float viewdist = General.Settings.ViewDistance;
// Make collections
@ -410,7 +364,7 @@ namespace CodeImp.DoomBuilder.VisualModes
Linedef nld = MapSet.NearestLinedef(visiblelines.Values, campos2d);
if(nld != null)
{
camsector = GetCameraSectorFromLinedef(nld);
General.Map.VisualCamera.Sector = GetCameraSectorFromLinedef(nld);
}
else
{
@ -422,10 +376,10 @@ namespace CodeImp.DoomBuilder.VisualModes
nld = General.Map.Map.NearestLinedef(campos2d);
if(nld != null)
{
camsector = GetCameraSectorFromLinedef(nld);
if(camsector != null)
General.Map.VisualCamera.Sector = GetCameraSectorFromLinedef(nld);
if(General.Map.VisualCamera.Sector != null)
{
foreach(Sidedef sd in camsector.Sidedefs)
foreach(Sidedef sd in General.Map.VisualCamera.Sector.Sidedefs)
{
float side = sd.Line.SideOfLine(campos2d);
if(((side < 0) && sd.IsFront) ||
@ -436,13 +390,13 @@ namespace CodeImp.DoomBuilder.VisualModes
else
{
// Too far away from the map to see anything
camsector = null;
General.Map.VisualCamera.Sector = null;
}
}
else
{
// Map is empty
camsector = null;
General.Map.VisualCamera.Sector = null;
}
}
}
@ -483,7 +437,7 @@ namespace CodeImp.DoomBuilder.VisualModes
// This returns the camera sector from linedef
private Sector GetCameraSectorFromLinedef(Linedef ld)
{
if(ld.SideOfLine(campos) < 0)
if(ld.SideOfLine(General.Map.VisualCamera.Position) < 0)
{
if(ld.Front != null)
return ld.Front.Sector;
@ -524,10 +478,10 @@ namespace CodeImp.DoomBuilder.VisualModes
List<IVisualPickable> pickables = new List<IVisualPickable>(blocks.Count * 10);
// Add geometry from the camera sector
if((camsector != null) && allsectors.ContainsKey(camsector))
if((General.Map.VisualCamera.Sector != null) && allsectors.ContainsKey(General.Map.VisualCamera.Sector))
{
VisualSector vs = allsectors[camsector];
sectors.Add(camsector, vs);
VisualSector vs = allsectors[General.Map.VisualCamera.Sector];
sectors.Add(General.Map.VisualCamera.Sector, vs);
foreach(VisualGeometry g in vs.FixedGeometry) pickables.Add(g);
}
@ -741,22 +695,24 @@ namespace CodeImp.DoomBuilder.VisualModes
base.OnProcess(deltatime);
// Calculate camera direction vectors
Vector3D camvec = Vector3D.FromAngleXYZ(camanglexy, camanglez);
Vector3D camvecstrafe = Vector3D.FromAngleXY(camanglexy + Angle2D.PIHALF);
// Camera vectors
Vector3D camvec = Vector3D.FromAngleXYZ(General.Map.VisualCamera.AngleXY, General.Map.VisualCamera.AngleZ);
Vector3D camvecstrafe = Vector3D.FromAngleXY(General.Map.VisualCamera.AngleXY + Angle2D.PIHALF);
Vector3D cammovemul = General.Map.VisualCamera.MoveMultiplier;
Vector3D camdeltapos = new Vector3D();
// Move the camera
if(doublespeed) multiplier = MOVE_SPEED_MULTIPLIER * 2.0f; else multiplier = MOVE_SPEED_MULTIPLIER;
if(keyforward) campos += camvec * movemultiplier * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keybackward) campos -= camvec * movemultiplier * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyleft) campos -= camvecstrafe * movemultiplier * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyright) campos += camvecstrafe * movemultiplier * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyforward) camdeltapos += camvec * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keybackward) camdeltapos -= camvec * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyleft) camdeltapos -= camvecstrafe * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyright) camdeltapos += camvecstrafe * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
// Target the camera
camtarget = campos + camvec;
// Move the camera
General.Map.VisualCamera.ProcessMovement(camdeltapos);
// Apply new camera matrices
renderer.PositionAndLookAt(campos, camtarget);
renderer.PositionAndLookAt(General.Map.VisualCamera.Position, General.Map.VisualCamera.Target);
// Visibility culling
DoCulling();