CodeWalker/Vehicles/VehicleForm.cs

610 lines
16 KiB
C#
Raw Normal View History

2019-01-11 11:24:50 +08:00
using CodeWalker.GameFiles;
using CodeWalker.Properties;
using CodeWalker.Rendering;
using CodeWalker.World;
using SharpDX;
using SharpDX.Direct3D11;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CodeWalker.Vehicles
{
public partial class VehicleForm : Form, DXForm
{
public Form Form { get { return this; } } //for DXForm/DXManager use
public Renderer Renderer = null;
public object RenderSyncRoot { get { return Renderer.RenderSyncRoot; } }
volatile bool formopen = false;
volatile bool running = false;
volatile bool pauserendering = false;
//volatile bool initialised = false;
Stopwatch frametimer = new Stopwatch();
Camera camera;
Timecycle timecycle;
Weather weather;
Clouds clouds;
Entity camEntity = new Entity();
bool MouseLButtonDown = false;
bool MouseRButtonDown = false;
int MouseX;
int MouseY;
System.Drawing.Point MouseDownPoint;
System.Drawing.Point MouseLastPoint;
public GameFileCache GameFileCache { get; } = GameFileCacheFactory.Create();
InputManager Input = new InputManager();
bool initedOk = false;
public VehicleForm()
{
InitializeComponent();
Renderer = new Renderer(this, GameFileCache);
camera = Renderer.camera;
timecycle = Renderer.timecycle;
weather = Renderer.weather;
clouds = Renderer.clouds;
initedOk = Renderer.Init();
Renderer.controllightdir = !Settings.Default.Skydome;
Renderer.rendercollisionmeshes = false;
Renderer.renderclouds = false;
//Renderer.renderclouds = true;
//Renderer.individualcloudfrag = "Contrails";
Renderer.rendermoon = false;
Renderer.renderskeletons = false;
Renderer.SelectionFlagsTestAll = true;
}
public void InitScene(Device device)
{
int width = ClientSize.Width;
int height = ClientSize.Height;
try
{
Renderer.DeviceCreated(device, width, height);
}
catch (Exception ex)
{
MessageBox.Show("Error loading shaders!\n" + ex.ToString());
return;
}
camera.FollowEntity = camEntity;
camera.FollowEntity.Position = Vector3.Zero;// prevworldpos;
camera.FollowEntity.Orientation = Quaternion.LookAtLH(Vector3.Zero, Vector3.Up, Vector3.ForwardLH);
camera.TargetDistance = 2.0f;
camera.CurrentDistance = 2.0f;
camera.TargetRotation.Y = 0.2f;
camera.CurrentRotation.Y = 0.2f;
camera.TargetRotation.X = 0.5f * (float)Math.PI;
camera.CurrentRotation.X = 0.5f * (float)Math.PI;
//LoadSettings();
formopen = true;
new Thread(new ThreadStart(ContentThread)).Start();
frametimer.Start();
}
public void CleanupScene()
{
formopen = false;
Renderer.DeviceDestroyed();
int count = 0;
while (running && (count < 5000)) //wait for the content thread to exit gracefully
{
Thread.Sleep(1);
count++;
}
}
public void RenderScene(DeviceContext context)
{
float elapsed = (float)frametimer.Elapsed.TotalSeconds;
frametimer.Restart();
if (pauserendering) return;
if (!Monitor.TryEnter(Renderer.RenderSyncRoot, 50))
{ return; } //couldn't get a lock, try again next time
//UpdateControlInputs(elapsed);
//space.Update(elapsed);
Renderer.Update(elapsed, MouseLastPoint.X, MouseLastPoint.Y);
//UpdateWidgets();
//BeginMouseHitTest();
Renderer.BeginRender(context);
Renderer.RenderSkyAndClouds();
Renderer.SelectedDrawable = null;// SelectedItem.Drawable;
//if (renderworld)
//{
// RenderWorld();
//}
//else if (rendermaps)
//{
// RenderYmaps();
//}
//else
//{
// RenderSingleItem();
//}
//UpdateMouseHitsFromRenderer();
//RenderSelection();
//RenderGrid(context);
Renderer.RenderQueued();
//Renderer.RenderBounds(MapSelectionMode.Entity);
//Renderer.RenderSelectionGeometry(MapSelectionMode.Entity);
//RenderMoused();
Renderer.RenderFinalPass();
//RenderMarkers();
//RenderWidgets();
Renderer.EndRender();
Monitor.Exit(Renderer.RenderSyncRoot);
//UpdateMarkerSelectionPanelInvoke();
}
public void BuffersResized(int w, int h)
{
Renderer.BuffersResized(w, h);
}
private void Init()
{
//called from VehicleForm_Load
if (!initedOk)
{
Close();
return;
}
MouseWheel += VehicleForm_MouseWheel;
if (!GTAFolder.UpdateGTAFolder(true))
{
Close();
return;
}
Input.Init();
Renderer.Start();
}
private void ContentThread()
{
//main content loading thread.
running = true;
UpdateStatus("Scanning...");
try
{
GTA5Keys.LoadFromPath(GTAFolder.CurrentGTAFolder, Settings.Default.Key);
}
catch
{
MessageBox.Show("Keys not found! This shouldn't happen.");
Close();
return;
}
GameFileCache.EnableDlc = true;
GameFileCache.LoadVehicles = true;
GameFileCache.LoadArchetypes = false;//to speed things up a little
GameFileCache.BuildExtendedJenkIndex = false;//to speed things up a little
GameFileCache.Init(UpdateStatus, LogError);
//UpdateDlcListComboBox(gameFileCache.DlcNameList);
//EnableCacheDependentUI();
LoadWorld();
//initialised = true;
//EnableDLCModsUI();
//UpdateStatus("Ready");
Task.Run(() => {
while (formopen && !IsDisposed) //renderer content loop
{
bool rcItemsPending = Renderer.ContentThreadProc();
if (!rcItemsPending)
{
Thread.Sleep(1); //sleep if there's nothing to do
}
}
});
while (formopen && !IsDisposed) //main asset loop
{
bool fcItemsPending = GameFileCache.ContentThreadProc();
if (!fcItemsPending)
{
Thread.Sleep(1); //sleep if there's nothing to do
}
}
GameFileCache.Clear();
running = false;
}
private void LoadWorld()
{
UpdateStatus("Loading timecycles...");
timecycle.Init(GameFileCache, UpdateStatus);
timecycle.SetTime(Renderer.timeofday);
UpdateStatus("Loading materials...");
BoundsMaterialTypes.Init(GameFileCache);
UpdateStatus("Loading weather...");
weather.Init(GameFileCache, UpdateStatus, timecycle);
//UpdateWeatherTypesComboBox(weather);
UpdateStatus("Loading clouds...");
clouds.Init(GameFileCache, UpdateStatus, weather);
//UpdateCloudTypesComboBox(clouds);
}
private void UpdateStatus(string text)
{
try
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => { UpdateStatus(text); }));
}
else
{
StatusLabel.Text = text;
}
}
catch { }
}
private void LogError(string text)
{
try
{
if (InvokeRequired)
{
Invoke(new Action(() => { LogError(text); }));
}
else
{
//TODO: error logging..
//ConsoleTextBox.AppendText(text + "\r\n");
//StatusLabel.Text = text;
//MessageBox.Show(text);
}
}
catch { }
}
private void UpdateMousePosition(MouseEventArgs e)
{
MouseX = e.X;
MouseY = e.Y;
MouseLastPoint = e.Location;
}
private void RotateCam(int dx, int dy)
{
camera.MouseRotate(dx, dy);
}
private void VehicleForm_Load(object sender, EventArgs e)
{
Init();
}
private void VehicleForm_MouseDown(object sender, MouseEventArgs e)
{
switch (e.Button)
{
case MouseButtons.Left: MouseLButtonDown = true; break;
case MouseButtons.Right: MouseRButtonDown = true; break;
}
//if (!ToolsPanelShowButton.Focused)
//{
// ToolsPanelShowButton.Focus(); //make sure no textboxes etc are focused!
//}
MouseDownPoint = e.Location;
MouseLastPoint = MouseDownPoint;
if (MouseLButtonDown)
{
}
if (MouseRButtonDown)
{
//SelectMousedItem();
}
MouseX = e.X; //to stop jumps happening on mousedown, sometimes the last MouseMove event was somewhere else... (eg after clicked a menu)
MouseY = e.Y;
}
private void VehicleForm_MouseUp(object sender, MouseEventArgs e)
{
switch (e.Button)
{
case MouseButtons.Left: MouseLButtonDown = false; break;
case MouseButtons.Right: MouseRButtonDown = false; break;
}
if (e.Button == MouseButtons.Left)
{
}
}
private void VehicleForm_MouseMove(object sender, MouseEventArgs e)
{
int dx = e.X - MouseX;
int dy = e.Y - MouseY;
//if (MouseInvert)
//{
// dy = -dy;
//}
//if (ControlMode == WorldControlMode.Free && !ControlBrushEnabled)
{
if (MouseLButtonDown)
{
RotateCam(dx, dy);
}
if (MouseRButtonDown)
{
if (Renderer.controllightdir)
{
Renderer.lightdirx += (dx * camera.Sensitivity);
Renderer.lightdiry += (dy * camera.Sensitivity);
}
else if (Renderer.controltimeofday)
{
float tod = Renderer.timeofday;
tod += (dx - dy) / 30.0f;
while (tod >= 24.0f) tod -= 24.0f;
while (tod < 0.0f) tod += 24.0f;
timecycle.SetTime(tod);
Renderer.timeofday = tod;
//float fv = tod * 60.0f;
//TimeOfDayTrackBar.Value = (int)fv;
//UpdateTimeOfDayLabel();
}
}
UpdateMousePosition(e);
}
}
private void VehicleForm_MouseWheel(object sender, MouseEventArgs e)
{
if (e.Delta != 0)
{
camera.MouseZoom(e.Delta);
}
}
private void VehicleForm_KeyDown(object sender, KeyEventArgs e)
{
if (ActiveControl is TextBox)
{
var tb = ActiveControl as TextBox;
if (!tb.ReadOnly) return; //don't move the camera when typing!
}
if (ActiveControl is ComboBox)
{
var cb = ActiveControl as ComboBox;
if (cb.DropDownStyle != ComboBoxStyle.DropDownList) return; //nontypable combobox
}
bool enablemove = true;// (!iseditmode) || (MouseLButtonDown && (GrabbedMarker == null) && (GrabbedWidget == null));
Input.KeyDown(e, enablemove);
var k = e.KeyCode;
var kb = Input.keyBindings;
bool ctrl = Input.CtrlPressed;
bool shift = Input.ShiftPressed;
if (!ctrl)
{
if (k == kb.MoveSlowerZoomIn)
{
camera.MouseZoom(1);
}
if (k == kb.MoveFasterZoomOut)
{
camera.MouseZoom(-1);
}
}
if (!Input.kbmoving) //don't trigger further actions if moving.
{
if (!ctrl)
{
}
else
{
//switch (k)
//{
// //case Keys.N:
// // New();
// // break;
// //case Keys.O:
// // Open();
// // break;
// //case Keys.S:
// // if (shift) SaveAll();
// // else Save();
// // break;
// //case Keys.Z:
// // Undo();
// // break;
// //case Keys.Y:
// // Redo();
// // break;
// //case Keys.C:
// // CopyItem();
// // break;
// //case Keys.V:
// // PasteItem();
// // break;
// //case Keys.U:
// // ToolsPanelShowButton.Visible = !ToolsPanelShowButton.Visible;
// // break;
//}
}
}
//if (ControlMode != WorldControlMode.Free || ControlBrushEnabled)
//{
// e.Handled = true;
//}
}
private void VehicleForm_KeyUp(object sender, KeyEventArgs e)
{
Input.KeyUp(e);
if (ActiveControl is TextBox)
{
var tb = ActiveControl as TextBox;
if (!tb.ReadOnly) return; //don't move the camera when typing!
}
if (ActiveControl is ComboBox)
{
var cb = ActiveControl as ComboBox;
if (cb.DropDownStyle != ComboBoxStyle.DropDownList) return; //non-typable combobox
}
//if (ControlMode != WorldControlMode.Free)
//{
// e.Handled = true;
//}
}
private void VehicleForm_Deactivate(object sender, EventArgs e)
{
//try not to lock keyboard movement if the form loses focus.
Input.KeyboardStop();
}
private void StatsUpdateTimer_Tick(object sender, EventArgs e)
{
StatsLabel.Text = Renderer.GetStatusText();
if (Renderer.timerunning)
{
//float fv = Renderer.timeofday * 60.0f;
////TimeOfDayTrackBar.Value = (int)fv;
//UpdateTimeOfDayLabel();
}
//CameraPositionTextBox.Text = FloatUtil.GetVector3String(camera.Position, "0.##");
}
}
}