CodeWalker/Forms/ModelForm.cs

2713 lines
96 KiB
C#
Raw Normal View History

2017-09-21 18:33:05 +08:00
using CodeWalker.GameFiles;
using CodeWalker.Properties;
using CodeWalker.Rendering;
using CodeWalker.World;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.XInput;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CodeWalker.Forms
{
public partial class ModelForm : Form, DXForm
{
public Form Form { get { return this; } } //for DXForm/DXManager use
DXManager dxman = new DXManager();
public DXManager DXMan { get { return dxman; } }
Device currentdevice;
public Device Device { get { return currentdevice; } }
object rendersyncroot = new object();
public object RenderSyncRoot { get { return rendersyncroot; } }
ShaderManager shaders;
volatile bool formopen = false;
//volatile bool running = false;
volatile bool pauserendering = false;
//volatile bool initialised = false;
Stopwatch frametimer = new Stopwatch();
Camera camera = new Camera();
Timecycle timecycle = new Timecycle();
Weather weather = new Weather();
Clouds clouds = new Clouds();
bool MouseLButtonDown = false;
bool MouseRButtonDown = false;
int MouseX;
int MouseY;
System.Drawing.Point MouseDownPoint;
System.Drawing.Point MouseLastPoint;
//public GameFileCache GameFileCache { get { return gameFileCache; } }
//GameFileCache gameFileCache = new GameFileCache();
RenderableCache renderableCache = new RenderableCache();
Vector3 prevworldpos = new Vector3(0, 0, 0); //also the start pos
Entity camEntity = new Entity();
volatile bool kbmovefwd = false;
volatile bool kbmovebck = false;
volatile bool kbmovelft = false;
volatile bool kbmovergt = false;
volatile bool kbmoveup = false;
volatile bool kbmovedn = false;
volatile bool kbjump = false;
KeyBindings keyBindings = new KeyBindings(Settings.Default.KeyBindings);
//bool iseditmode = false;
float timeofday = 12.0f;
bool controltimeofday = true;
bool timerunning = false;
float timespeed = 0.5f;//min/sec
//string weathertype = "";
string individualcloudfrag = "contrails";
Vector4 currentWindVec = Vector4.Zero;
float currentWindTime = 0.0f;
bool controllightdir = !Settings.Default.Skydome;//true; //if not, use timecycle
float lightdirx = 2.25f;//radians // approx. light dir on map satellite view
float lightdiry = 0.65f;//radians - used for manual light placement
bool renderskydome = Settings.Default.Skydome;
bool rendernaturalambientlight = true;
bool renderartificialambientlight = true;
ShaderGlobalLights globalLights = new ShaderGlobalLights();
double currentRealTime = 0;
int framecount = 0;
float fcelapsed = 0.0f;
int fps = 0;
bool initedOk = false;
private string fileName;
public string FileName
{
get { return fileName; }
set
{
fileName = value;
UpdateFormTitle();
}
}
public string FilePath { get; set; }
YdrFile Ydr = null;
YddFile Ydd = null;
YftFile Yft = null;
YbnFile Ybn = null;
YptFile Ypt = null;
YnvFile Ynv = null;
bool waitforchildrentoload = true;
bool rendercollisionmeshes = false;// Settings.Default.ShowCollisionMeshes;
bool renderskeletons = true;
List<Renderable> renderskeletonlist = new List<Renderable>();
List<VertexTypePC> skeletonLineVerts = new List<VertexTypePC>();
2017-09-21 18:33:05 +08:00
bool CtrlPressed = false;
bool ShiftPressed = false;
Controller xbcontroller = null;
State xbcontrollerstate;
State xbcontrollerstateprev;
Vector4 xbmainaxes = Vector4.Zero;
Vector4 xbmainaxesprev = Vector4.Zero;
Vector2 xbtrigs = Vector2.Zero;
Vector2 xbtrigsprev = Vector2.Zero;
float xbcontrolvelocity = 0.0f;
bool toolsPanelResizing = false;
int toolsPanelResizeStartX = 0;
int toolsPanelResizeStartLeft = 0;
int toolsPanelResizeStartRight = 0;
Dictionary<DrawableBase, bool> DrawableDrawFlags = new Dictionary<DrawableBase, bool>();
Dictionary<DrawableModel, bool> ModelDrawFlags = new Dictionary<DrawableModel, bool>();
Dictionary<DrawableGeometry, bool> GeometryDrawFlags = new Dictionary<DrawableGeometry, bool>();
bool enableGrid = true;
float gridSize = 1.0f;
int gridCount = 40;
List<VertexTypePC> gridVerts = new List<VertexTypePC>();
object gridSyncRoot = new object();
GameFileCache gameFileCache = null;
Archetype currentArchetype = null;
bool updateArchetypeStatus = true;
public ModelForm(ExploreForm ExpForm = null)
{
InitializeComponent();
gameFileCache = ExpForm?.GetFileCache();
initedOk = dxman.Init(this, false);
}
private void Init()
{
//called from WorldForm_Load
if (!initedOk)
{
Close();
return;
}
MouseWheel += ModelForm_MouseWheel;
string fldr = Settings.Default.GTAFolder;
if (string.IsNullOrEmpty(fldr) || !Directory.Exists(fldr))
{
SelectFolderForm f = new SelectFolderForm();
f.ShowDialog();
if (f.Result == DialogResult.OK)
{
fldr = f.SelectedFolder;
}
else
{
Close();
return;
}
}
if (!Directory.Exists(fldr))
{
MessageBox.Show("The specified folder does not exist:\n" + fldr);
Close();
return;
}
if (!File.Exists(fldr + "\\gta5.exe"))
{
MessageBox.Show("GTA5.exe not found in folder:\n" + fldr);
Close();
return;
}
Settings.Default.GTAFolder = fldr; //seems ok, save it for later
MetaName[] texsamplers = RenderableGeometry.GetTextureSamplerList();
foreach (var texsampler in texsamplers)
{
TextureSamplerComboBox.Items.Add(texsampler);
}
//TextureSamplerComboBox.SelectedIndex = 0;//LoadSettings will do this..
UpdateGridVerts();
GridSizeComboBox.SelectedIndex = 1;
GridCountComboBox.SelectedIndex = 1;
InitController();
dxman.Start();
}
private void InitController()
{
xbcontroller = new Controller(UserIndex.One);
if (!xbcontroller.IsConnected)
{
var controllers = new[] { new Controller(UserIndex.Two), new Controller(UserIndex.Three), new Controller(UserIndex.Four) };
foreach (var selectControler in controllers)
{
if (selectControler.IsConnected)
{
xbcontroller = selectControler;
xbcontrollerstate = xbcontroller.GetState();
xbcontrollerstateprev = xbcontrollerstate;
break;
}
}
}
else
{
xbcontrollerstate = xbcontroller.GetState();
xbcontrollerstateprev = xbcontrollerstate;
}
}
public void InitScene(Device device)
{
currentdevice = device;
int width = ClientSize.Width;
int height = ClientSize.Height;
try
{
shaders = new ShaderManager(device, dxman);
shaders.OnWindowResize(width, height); //init the buffers
}
catch (Exception ex)
{
MessageBox.Show("Error loading shaders!\n" + ex.ToString());
return;
}
//shaders.hdrLumBlendSpeed = 1000.0f;
renderableCache.OnDeviceCreated(device);
camera.OnWindowResize(width, height); //init the projection stuff
camera.FollowEntity = camEntity;
camera.FollowEntity.Position = 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;
LoadSettings();
formopen = true;
new Thread(new ThreadStart(ContentThread)).Start();
frametimer.Start();
}
public void CleanupScene()
{
formopen = false;
renderableCache.OnDeviceDestroyed();
shaders.Dispose();
//int count = 0;
//while (running && (count < 5000)) //wait for the content thread to exit gracefully
//{
// Thread.Sleep(1);
// count++;
//}
currentdevice = null;
}
public void BuffersResized(int w, int h)
{
lock (rendersyncroot)
{
camera.OnWindowResize(w, h);
shaders.OnWindowResize(w, h);
}
}
public void RenderScene(DeviceContext context)
{
float elapsed = (float)frametimer.Elapsed.TotalSeconds;
framecount++;
fcelapsed += elapsed;
if (fcelapsed >= 0.5f)
{
fps = framecount * 2;
framecount = 0;
fcelapsed -= 0.5f;
}
if (elapsed > 0.1f) elapsed = 0.1f;
frametimer.Restart();
currentRealTime += elapsed;
if (pauserendering) return;
if (!Monitor.TryEnter(rendersyncroot, 50))
{ return; } //couldn't get a lock, try again next time
//Monitor.Enter(rendersyncroot);
UpdateControlInputs(elapsed);
UpdateTimeOfDay(elapsed);
weather.Update(elapsed);
//clouds.Update(elapsed);
UpdateWindVector(elapsed);
UpdateGlobalLights();
camera.SetMousePosition(MouseLastPoint.X, MouseLastPoint.Y);
camera.Update(elapsed);
//UpdateWidgets();
//HilightBoxes.Clear();
//BoundingBoxes.Clear();
//BoundingSpheres.Clear();
//BeginMouseHitTest();
BeginFrame();
2017-09-21 18:33:05 +08:00
dxman.ClearRenderTarget(context);
shaders.BeginFrame(context, currentRealTime, elapsed);
shaders.EnsureShaderTextures(gameFileCache, renderableCache);
RenderSky(context);
//RenderClouds(context);
shaders.ClearDepth(context);
//if (renderworld || rendermaps)
//{
// RenderWorld();
// if (rendermaps)
// {
// RenderYmaps();
// }
//}
//else
//{
RenderSingleItem();
//}
RenderGrid(context);
shaders.RenderQueued(context, camera, currentWindVec);
RenderSkeletons(context);
2017-09-21 18:33:05 +08:00
//RenderBounds(context);
//RenderSelection(context);
//RenderMoused(context);
//RenderSelectionGeometry(context);
shaders.RenderFinalPass(context);
//RenderMarkers(context);
//RenderWidgets(context);
renderableCache.RenderThreadSync();
Monitor.Exit(rendersyncroot);
//UpdateMarkerSelectionPanelInvoke();
}
private void ContentThread()
{
//main content loading thread.
//running = true;
//UpdateStatus("Scanning...");
//try
//{
// GTA5Keys.LoadFromPath(Settings.Default.GTAFolder); //now loads from magic
//}
//catch
//{
// MessageBox.Show("Keys not found! This shouldn't happen.");
// Close();
// return;
//}
//gameFileCache.Init(UpdateStatus, LogError);
////UpdateDlcListComboBox(gameFileCache.DlcNameList);
////EnableCacheDependentUI();
////LoadWorld();
//initialised = true;
////EnableDLCModsUI();
UpdateStatus("Ready");
while (formopen && !IsDisposed) //main asset loop
{
if ((gameFileCache != null) && (gameFileCache.IsInited))
{
if (!timecycle.Inited)
{
//UpdateStatus("Loading timecycles...");
timecycle.Init(gameFileCache, UpdateStatus);
timecycle.SetTime(timeofday);
//UpdateStatus("Timecycles loaded.");
}
if (renderskydome)
{
if (!weather.Inited)
{
//UpdateStatus("Loading weather...");
weather.Init(gameFileCache, UpdateStatus, timecycle);
//UpdateStatus("Weather loaded.");
}
//if (!clouds.Inited)
//{
// UpdateStatus("Loading clouds...");
// clouds.Init(gameFileCache, UpdateStatus, weather);
// UpdateStatus("Clouds loaded.");
//}
}
}
//if ((gameFileCache != null) && (gameFileCache.IsInited))
//{
// gameFileCache.ContentThreadProc();
//}
renderableCache.ContentThreadProc();
if (!(renderableCache.ItemsStillPending)) //gameFileCache.ItemsStillPending ||
{
Thread.Sleep(1); //sleep if there's nothing to do
}
}
//gameFileCache.Clear();
//running = false;
}
private void LoadSettings()
{
var s = Settings.Default;
//WindowState = s.WindowMaximized ? FormWindowState.Maximized : WindowState;
//FullScreenCheckBox.Checked = s.FullScreen;
WireframeCheckBox.Checked = s.Wireframe;
HDRRenderingCheckBox.Checked = s.HDR;
ShadowsCheckBox.Checked = s.Shadows;
SkydomeCheckBox.Checked = s.Skydome;
RenderModeComboBox.SelectedIndex = Math.Max(RenderModeComboBox.FindString(s.RenderMode), 0);
TextureSamplerComboBox.SelectedIndex = Math.Max(TextureSamplerComboBox.FindString(s.RenderTextureSampler), 0);
TextureCoordsComboBox.SelectedIndex = Math.Max(TextureCoordsComboBox.FindString(s.RenderTextureSamplerCoord), 0);
AnisotropicFilteringCheckBox.Checked = s.AnisotropicFiltering;
//ErrorConsoleCheckBox.Checked = s.ShowErrorConsole;
//StatusBarCheckBox.Checked = s.ShowStatusBar;
}
private Archetype TryGetArchetype(uint hash)
2017-09-21 18:33:05 +08:00
{
if ((gameFileCache == null) || (!gameFileCache.IsInited)) return null;
2017-09-21 18:33:05 +08:00
var arch = gameFileCache.GetArchetype(hash);
2017-09-21 18:33:05 +08:00
if ((arch != null) && (arch != currentArchetype) && (updateArchetypeStatus))
2017-09-21 18:33:05 +08:00
{
UpdateStatus("Archetype: " + arch.Name.ToString());
currentArchetype = arch;
updateArchetypeStatus = false;
2017-09-21 18:33:05 +08:00
}
return arch;
}
2017-09-21 18:33:05 +08:00
private DrawableBase TryGetDrawable(Archetype arche)
{
if (arche == null) return null;
if ((gameFileCache == null) || (!gameFileCache.IsInited)) return null;
2017-09-21 18:33:05 +08:00
uint drawhash = arche.Hash;
DrawableBase drawable = null;
if ((arche.DrawableDict != 0))// && (arche.DrawableDict != arche.Hash))
2017-09-21 18:33:05 +08:00
{
//try get drawable from ydd...
YddFile ydd = gameFileCache.GetYdd(arche.DrawableDict);
if (ydd != null)
2017-09-21 18:33:05 +08:00
{
if (ydd.Loaded && (ydd.Dict != null))
{
Drawable d;
ydd.Dict.TryGetValue(drawhash, out d); //can't out to base class?
drawable = d;
if (drawable == null)
{
return null; //drawable wasn't in dict!!
}
}
else
{
return null; //ydd not loaded yet, or has no dict
}
}
else
{
//return null; //couldn't find drawable dict... quit now?
2017-09-21 18:33:05 +08:00
}
}
if (drawable == null)
2017-09-21 18:33:05 +08:00
{
//try get drawable from ydr.
YdrFile ydr = gameFileCache.GetYdr(drawhash);
if (ydr != null)
2017-09-21 18:33:05 +08:00
{
if (ydr.Loaded)
2017-09-21 18:33:05 +08:00
{
drawable = ydr.Drawable;
}
}
else
{
YftFile yft = gameFileCache.GetYft(drawhash);
if (yft != null)
{
if (yft.Loaded)
2017-09-21 18:33:05 +08:00
{
if (yft.Fragment != null)
2017-09-21 18:33:05 +08:00
{
drawable = yft.Fragment.Drawable;
2017-09-21 18:33:05 +08:00
}
}
}
}
}
return drawable;
2017-09-21 18:33:05 +08:00
}
private Renderable TryGetRenderable(Archetype arche, DrawableBase drawable, uint txdHash = 0)
{
if (drawable == null) return null;
//BUG: only last texdict used!! needs to cache textures per archetype........
//(but is it possible to have the same drawable with different archetypes?)
uint texDict = (arche != null) ? arche.TextureDict.Hash : txdHash;
uint clipDict = (arche != null) ? arche.ClipDict.Hash : 0;
var yptTextDict = Ypt?.PtfxList?.TextureDictionary;
Renderable rndbl = renderableCache.GetRenderable(drawable);
if (rndbl == null) return null;
2017-09-21 18:33:05 +08:00
var gfc = gameFileCache;
if ((gfc != null) && (!gfc.IsInited))
{
gfc = null;
}
2017-09-21 18:33:05 +08:00
//if (clipDict != 0)
//{
// YcdFile ycd = gameFileCache.GetYcd(clipDict);
// if ((ycd != null) && (ycd.Loaded))
// {
// ClipMapEntry cme;
// if (ycd.ClipMap.TryGetValue(arche.Hash, out cme))
// {
// }
// else
// { }
// }
//}
2017-09-21 18:33:05 +08:00
bool alltexsloaded = true;
int missingtexcount = 0;
for (int mi = 0; mi < rndbl.HDModels.Length; mi++)
2017-09-21 18:33:05 +08:00
{
var model = rndbl.HDModels[mi];
2017-09-21 18:33:05 +08:00
//if (!RenderIsModelFinalRender(model) && !renderproxies)
//{
// continue; //filter out reflection proxy models...
//}
foreach (var geom in model.Geometries)
{
if (geom.Textures != null)
{
for (int i = 0; i < geom.Textures.Length; i++)
{
var tex = geom.Textures[i];
var ttex = tex as Texture;
RenderableTexture rdtex = null;
if ((ttex == null) && (tex != null))
{
//TextureRef means this RenderableTexture needs to be loaded from texture dict...
if (yptTextDict != null) //for ypt files, first try the embedded tex dict..
{
var dtex = yptTextDict.Lookup(tex.NameHash);
rdtex = renderableCache.GetRenderableTexture(dtex);
}
else if (texDict != 0)
{
YtdFile ytd = gfc?.GetYtd(texDict);
if ((ytd != null) && (ytd.Loaded) && (ytd.TextureDict != null))
{
var dtex = ytd.TextureDict.Lookup(tex.NameHash);
if (dtex == null)
{
//not present in dictionary... check already loaded texture dicts...
YtdFile ytd2 = gfc?.TryGetTextureDictForTexture(tex.NameHash);
if ((ytd2 != null) && (ytd2.Loaded) && (ytd2.TextureDict != null))
{
dtex = ytd2.TextureDict.Lookup(tex.NameHash);
}
else
{
//couldn't find texture dict?
//first try going through ytd hierarchy...
dtex = gfc?.TryFindTextureInParent(tex.NameHash, texDict);
//if (dtex == null)
//{ //try for a texture dict with the same hash as the archetype?
// dtex = gameFileCache.TryFindTextureInParent(tex.TextureRef.NameHash, arche.Hash);
// if (dtex != null)
// { }
//}
}
}
if (dtex != null)
{
geom.Textures[i] = dtex; //cache it for next time to avoid the lookup...
rdtex = renderableCache.GetRenderableTexture(dtex);
}
if (rdtex == null)
{ } //nothing to see here :(
}
else if ((ytd == null))
{
Texture dtex = null;
if (drawable.ShaderGroup.TextureDictionary != null)
{
dtex = drawable.ShaderGroup.TextureDictionary.Lookup(tex.NameHash);
if (dtex == null)
{
//dtex = drawable.ShaderGroup.TextureDictionary.Textures.data_items[0];
}
}
if (dtex == null)
{
YtdFile ytd2 = gfc?.TryGetTextureDictForTexture(tex.NameHash);
if ((ytd2 != null) && (ytd2.Loaded) && (ytd2.TextureDict != null))
{
dtex = ytd2.TextureDict.Lookup(tex.NameHash);
}
if (dtex == null)
{
dtex = gfc?.TryFindTextureInParent(tex.NameHash, texDict);
}
}
rdtex = renderableCache.GetRenderableTexture(dtex);
if (rdtex == null)
{ missingtexcount -= 2; } //(give extra chance..) couldn't find the texture! :(
}
else if (ytd != null)
{
alltexsloaded = false;//ytd not loaded yet
//missingtexcount++;
}
}
else //no texdict specified, nothing to see here..
{
YtdFile ytd2 = gfc?.TryGetTextureDictForTexture(tex.NameHash);
if ((ytd2 != null) && (ytd2.Loaded) && (ytd2.TextureDict != null))
{
var dtex = ytd2.TextureDict.Lookup(tex.NameHash);
rdtex = renderableCache.GetRenderableTexture(dtex);
}
}
}
else if (ttex != null) //ensure embedded renderable texture
{
rdtex = renderableCache.GetRenderableTexture(ttex);
}
else if (tex == null)
{ } //tex wasn't loaded? shouldn't happen..
geom.RenderableTextures[i] = rdtex;
if (rdtex != null)
{
if (!rdtex.IsLoaded)
{
alltexsloaded = false;
missingtexcount++;
}
}
else
{
//alltexsloaded = false;
missingtexcount++;
}
}
}
}
}
rndbl.AllTexturesLoaded = alltexsloaded || (missingtexcount < 2);
return rndbl;
}
private void BeginFrame()
{
renderskeletonlist.Clear();
}
private void RenderSky(DeviceContext context)
{
if (!renderskydome) return;
if (!weather.Inited) return;
var shader = shaders.Skydome;
shader.UpdateSkyLocals(weather, globalLights);
DrawableBase skydomeydr = null;
YddFile skydomeydd = gameFileCache.GetYdd(2640562617); //skydome hash
if ((skydomeydd != null) && (skydomeydd.Loaded) && (skydomeydd.Dict != null))
{
skydomeydr = skydomeydd.Dict.Values.FirstOrDefault();
}
Texture starfield = null;
//Texture moon = null;
YtdFile skydomeytd = gameFileCache.GetYtd(2640562617); //skydome hash
if ((skydomeytd != null) && (skydomeytd.Loaded) && (skydomeytd.TextureDict != null) && (skydomeytd.TextureDict.Dict != null))
{
skydomeytd.TextureDict.Dict.TryGetValue(1064311147, out starfield); //starfield hash
//skydomeytd.TextureDict.Dict.TryGetValue(234339206, out moon); //moon-new hash
}
Renderable sdrnd = null;
if (skydomeydr != null)
{
sdrnd = renderableCache.GetRenderable(skydomeydr);
}
RenderableTexture sftex = null;
if (starfield != null)
{
sftex = renderableCache.GetRenderableTexture(starfield);
}
//RenderableTexture moontex = null;
//if (moon != null)
//{
// moontex = renderableCache.GetRenderableTexture(moon);
//}
if ((sdrnd != null) && (sdrnd.IsLoaded) && (sftex != null) && (sftex.IsLoaded))
{
shaders.SetDepthStencilMode(context, DepthStencilMode.DisableAll);
shaders.SetRasterizerMode(context, RasterizerMode.Solid);
RenderableInst rinst = new RenderableInst();
rinst.Position = Vector3.Zero;
rinst.CamRel = Vector3.Zero;
rinst.Distance = 0.0f;
rinst.BBMin = skydomeydr.BoundingBoxMin.XYZ();
rinst.BBMax = skydomeydr.BoundingBoxMax.XYZ();
rinst.BSCenter = Vector3.Zero;
rinst.Radius = skydomeydr.BoundingSphereRadius;
rinst.Orientation = Quaternion.Identity;
rinst.Scale = Vector3.One;
rinst.TintPaletteIndex = 0;
rinst.Renderable = sdrnd;
shader.SetShader(context);
shader.SetInputLayout(context, VertexType.PTT);
shader.SetSceneVars(context, camera, null, globalLights);
shader.SetEntityVars(context, ref rinst);
RenderableModel rmod = ((sdrnd.HDModels != null) && (sdrnd.HDModels.Length > 0)) ? sdrnd.HDModels[0] : null;
RenderableGeometry rgeom = ((rmod != null) && (rmod.Geometries != null) && (rmod.Geometries.Length > 0)) ? rmod.Geometries[0] : null;
if ((rgeom != null) && (rgeom.VertexType == VertexType.PTT))
{
shader.SetModelVars(context, rmod);
shader.SetTextures(context, sftex);
rgeom.Render(context);
}
//shaders.SetRasterizerMode(context, RasterizerMode.SolidDblSided);
//shaders.SetDepthStencilMode(context, DepthStencilMode.Enabled);
shader.RenderSun(context, camera, weather, globalLights);
//if ((moontex != null) && (moontex.IsLoaded))
//{
// shader.RenderMoon(context, camera, weather, globalLights, moontex);
//}
shader.UnbindResources(context);
}
}
private void RenderClouds(DeviceContext context)
{
if (!renderskydome) return;
if (!weather.Inited) return;
if (!clouds.Inited) return;
var shader = shaders.Clouds;
shaders.SetDepthStencilMode(context, DepthStencilMode.DisableAll);
shaders.SetRasterizerMode(context, RasterizerMode.Solid);
shaders.SetDefaultBlendState(context);
//shaders.SetAlphaBlendState(context);
shader.SetShader(context);
shader.UpdateCloudsLocals(clouds, globalLights);
shader.SetSceneVars(context, camera, null, globalLights);
var vtype = (VertexType)0;
if (!string.IsNullOrEmpty(individualcloudfrag))
{
//render one cloud fragment.
CloudHatFrag frag = clouds.HatManager.FindFrag(individualcloudfrag);
if (frag == null) return;
for (int i = 0; i < frag.Layers.Length; i++)
{
CloudHatFragLayer layer = frag.Layers[i];
uint dhash = JenkHash.GenHash(layer.Filename.ToLower());
Archetype arch = gameFileCache.GetArchetype(dhash);
if (arch == null)
{ continue; }
if (Math.Max(camera.Position.Z, 0.0f) < layer.HeightTigger) continue;
var drw = TryGetDrawable(arch);
var rnd = TryGetRenderable(arch, drw);
if ((rnd == null) || (rnd.IsLoaded == false) || (rnd.AllTexturesLoaded == false))
{ continue; }
RenderableInst rinst = new RenderableInst();
rinst.Position = frag.Position;// Vector3.Zero;
rinst.CamRel = Vector3.Zero;// - camera.Position;
rinst.Distance = rinst.CamRel.Length();
rinst.BBMin = arch.BBMin;
rinst.BBMax = arch.BBMax;
rinst.BSCenter = frag.Position;
rinst.Radius = arch.BSRadius;
rinst.Orientation = Quaternion.Identity;
rinst.Scale = frag.Scale;// Vector3.One;
rinst.TintPaletteIndex = 0;
rinst.Renderable = rnd;
shader.SetEntityVars(context, ref rinst);
for (int mi = 0; mi < rnd.HDModels.Length; mi++)
{
var model = rnd.HDModels[mi];
for (int gi = 0; gi < model.Geometries.Length; gi++)
{
var geom = model.Geometries[gi];
if (geom.VertexType != vtype)
{
vtype = geom.VertexType;
shader.SetInputLayout(context, vtype);
}
shader.SetGeomVars(context, geom);
geom.Render(context);
}
}
}
}
}
private void UpdateGridVerts()
{
lock (gridSyncRoot)
{
gridVerts.Clear();
float s = gridSize * gridCount * 0.5f;
uint cblack = (uint)SharpDX.Color.Black.ToRgba();
2017-09-21 18:33:05 +08:00
uint cgray = (uint)SharpDX.Color.DimGray.ToRgba();
uint cred = (uint)SharpDX.Color.DarkRed.ToRgba();
uint cgrn = (uint)SharpDX.Color.DarkGreen.ToRgba();
int interval = 10;
for (int i = 0; i <= gridCount; i++)
{
float o = (gridSize * i) - s;
if ((i % interval) != 0)
{
gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, -s, 0), Colour = cgray });
gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, s, 0), Colour = cgray });
gridVerts.Add(new VertexTypePC() { Position = new Vector3(-s, o, 0), Colour = cgray });
gridVerts.Add(new VertexTypePC() { Position = new Vector3(s, o, 0), Colour = cgray });
}
}
for (int i = 0; i <= gridCount; i++) //draw main lines last, so they are on top
{
float o = (gridSize * i) - s;
if ((i % interval) == 0)
{
var cx = (o == 0) ? cred : cblack;
var cy = (o == 0) ? cgrn : cblack;
gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, -s, 0), Colour = cy });
gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, s, 0), Colour = cy });
gridVerts.Add(new VertexTypePC() { Position = new Vector3(-s, o, 0), Colour = cx });
gridVerts.Add(new VertexTypePC() { Position = new Vector3(s, o, 0), Colour = cx });
}
}
}
}
private void RenderGrid(DeviceContext context)
{
if (!enableGrid) return;
lock (gridSyncRoot)
{
if (gridVerts.Count > 0)
{
shaders.SetDepthStencilMode(context, DepthStencilMode.Enabled);
shaders.Paths.RenderLines(context, gridVerts, camera, shaders.GlobalLights);
}
}
}
2017-09-21 18:33:05 +08:00
private void RenderSingleItem()
{
uint hash = 0;
Archetype arch = null;
if (Ydr != null)
{
if (Ydr.Loaded)
{
hash = Ydr?.RpfFileEntry?.ShortNameHash ?? 0;
arch = TryGetArchetype(hash);
RenderDrawable(Ydr.Drawable, arch, null, -camera.Position, hash);
}
}
else if (Ydd != null)
{
//render selected drawable(s)...
if (Ydd.Loaded)
{
foreach (var kvp in Ydd.Dict)
{
if (!DrawableDrawFlags.ContainsKey(kvp.Value))//only render if it's checked...
{
arch = TryGetArchetype(kvp.Key);
RenderDrawable(kvp.Value, arch, null, -camera.Position, Ydd.RpfFileEntry.ShortNameHash);
}
}
}
}
else if (Ypt != null)
{
if ((Ypt.Loaded) && (Ypt.DrawableDict != null))
{
foreach (var kvp in Ypt.DrawableDict)
{
if (!DrawableDrawFlags.ContainsKey(kvp.Value))//only render if it's checked...
{
arch = TryGetArchetype(kvp.Key);
RenderDrawable(kvp.Value, arch, null, -camera.Position, kvp.Key);
}
}
}
}
else if (Yft != null)
{
if (Yft.Loaded)
{
if (Yft.Fragment != null)
{
var f = Yft.Fragment;
hash = Yft?.RpfFileEntry?.ShortNameHash ?? 0;
arch = TryGetArchetype(hash);
RenderDrawable(f.Drawable, arch, null, -camera.Position, hash);
if (f.Unknown_F8h_Data != null) //cloth
{
RenderDrawable(f.Unknown_F8h_Data, arch, null, -camera.Position, hash);
}
//vehicle wheels...
if ((f.PhysicsLODGroup != null) && (f.PhysicsLODGroup.PhysicsLOD1 != null))
{
var pl1 = f.PhysicsLODGroup.PhysicsLOD1;
if ((pl1.Children != null) && (pl1.Children.data_items != null))
{
for (int i = 0; i < pl1.Children.data_items.Length; i++)
{
var pch = pl1.Children.data_items[i];
if ((pch.Drawable1 != null) && (pch.Drawable1.AllModels.Length != 0))
{
//RenderDrawable(pch.Drawable1, null, null, -camera.Position, hash);
}
}
}
}
}
}
}
else if (Ybn != null)
{
if (Ybn.Loaded)
{
RenderCollisionMesh(Ybn.Bounds, null);
}
}
else if (Ypt != null)
{
if (Ypt.Loaded)
{
}
}
else if (Ynv != null)
{
if (Ynv.Loaded)
{
RenderNavmesh(Ynv);
}
}
}
private bool RenderDrawable(DrawableBase drawable, Archetype arche, YmapEntityDef entity, Vector3 camrel, uint txdHash = 0)
2017-09-21 18:33:05 +08:00
{
//enqueue a single drawable for rendering.
2017-09-21 18:33:05 +08:00
if (drawable == null)
return false;
2017-09-21 18:33:05 +08:00
Renderable rndbl = TryGetRenderable(arche, drawable, txdHash);
if (rndbl == null)
return false;
2017-09-21 18:33:05 +08:00
return RenderRenderable(rndbl, arche, entity, camrel);
2017-09-21 18:33:05 +08:00
}
private bool RenderRenderable(Renderable rndbl, Archetype arche, YmapEntityDef entity, Vector3 camrel)
{
//enqueue a single renderable for rendering.
2017-09-21 18:33:05 +08:00
if (!rndbl.IsLoaded) return false;
2017-09-21 18:33:05 +08:00
//if (((SelectionMode == MapSelectionMode.Entity) || (SelectionMode == MapSelectionMode.EntityExtension) || (SelectionMode == MapSelectionMode.ArchetypeExtension)))
//{
// UpdateMouseHit(rndbl, arche, entity, camrel);
//}
2017-09-21 18:33:05 +08:00
bool isselected = true;// (rndbl.Key == SelectedItem.Drawable);
2017-09-21 18:33:05 +08:00
Vector3 position = Vector3.Zero;
Vector3 scale = Vector3.One;
Quaternion orientation = Quaternion.Identity;
uint tintPaletteIndex = 0;
Vector3 bbmin = (arche != null) ? arche.BBMin : rndbl.Key.BoundingBoxMin.XYZ();
Vector3 bbmax = (arche != null) ? arche.BBMax : rndbl.Key.BoundingBoxMax.XYZ();
Vector3 bscen = (arche != null) ? arche.BSCenter : rndbl.Key.BoundingCenter;
float radius = (arche != null) ? arche.BSRadius : rndbl.Key.BoundingSphereRadius;
float distance = (camrel + bscen).Length();
if (entity != null)
2017-09-21 18:33:05 +08:00
{
position = entity.Position;
scale = entity.Scale;
orientation = entity.Orientation;
tintPaletteIndex = entity.CEntityDef.tintValue;
bbmin = entity.BBMin;
bbmax = entity.BBMax;
bscen = entity.BSCenter;
2017-09-21 18:33:05 +08:00
}
if (rendercollisionmeshes)// && collisionmeshlayerdrawable)
2017-09-21 18:33:05 +08:00
{
Drawable sdrawable = rndbl.Key as Drawable;
if ((sdrawable != null) && (sdrawable.Bound != null))
2017-09-21 18:33:05 +08:00
{
RenderCollisionMesh(sdrawable.Bound, entity);
2017-09-21 18:33:05 +08:00
}
}
if (renderskeletons)
{
if (rndbl.HasSkeleton)
2017-09-21 18:33:05 +08:00
{
RenderSkeleton(rndbl);
2017-09-21 18:33:05 +08:00
}
}
bool retval = true;// false;
if (rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload))
2017-09-21 18:33:05 +08:00
{
RenderableGeometryInst rginst = new RenderableGeometryInst();
rginst.Inst.Renderable = rndbl;
rginst.Inst.CamRel = camrel;
rginst.Inst.Position = position;
rginst.Inst.Scale = scale;
rginst.Inst.Orientation = orientation;
rginst.Inst.TintPaletteIndex = tintPaletteIndex;
rginst.Inst.BBMin = bbmin;
rginst.Inst.BBMax = bbmax;
rginst.Inst.BSCenter = bscen;
rginst.Inst.Radius = radius;
rginst.Inst.Distance = distance;
2017-09-21 18:33:05 +08:00
RenderableModel[] models = isselected ? rndbl.AllModels : rndbl.HDModels;
2017-09-21 18:33:05 +08:00
for (int mi = 0; mi < models.Length; mi++)
2017-09-21 18:33:05 +08:00
{
var model = models[mi];
2017-09-21 18:33:05 +08:00
if (isselected)
{
if (ModelDrawFlags.ContainsKey(model.DrawableModel))
{ continue; } //filter out models in selected item that aren't flagged for drawing.
}
2017-09-21 18:33:05 +08:00
if (!RenderIsModelFinalRender(model))// && !renderproxies)
{ continue; } //filter out reflection proxy models...
2017-09-21 18:33:05 +08:00
for (int gi = 0; gi < model.Geometries.Length; gi++)
{
var geom = model.Geometries[gi];
2017-09-21 18:33:05 +08:00
if (isselected)
{
if (GeometryDrawFlags.ContainsKey(geom.DrawableGeom))
{ continue; } //filter out geometries in selected item that aren't flagged for drawing.
}
2017-09-21 18:33:05 +08:00
rginst.Geom = geom;
2017-09-21 18:33:05 +08:00
shaders.Enqueue(rginst);
}
}
}
else
{
retval = false;
}
return retval;
}
2017-09-21 18:33:05 +08:00
private void RenderCollisionMesh(Bounds bounds, YmapEntityDef entity)
{
//enqueue a single collision mesh for rendering.
2017-09-21 18:33:05 +08:00
Vector3 position;
Vector3 scale;
Quaternion orientation;
if (entity != null)
{
position = entity.Position;
scale = entity.Scale;
orientation = entity.Orientation;
}
else
{
position = Vector3.Zero;
scale = Vector3.One;
orientation = Quaternion.Identity;
}
2017-09-21 18:33:05 +08:00
switch (bounds.Type)
{
case 10: //BoundComposite
BoundComposite boundcomp = bounds as BoundComposite;
if (boundcomp != null)
2017-09-21 18:33:05 +08:00
{
RenderableBoundComposite rndbc = renderableCache.GetRenderableBoundComp(boundcomp);
if (rndbc.IsLoaded)
{
RenderableBoundGeometryInst rbginst = new RenderableBoundGeometryInst();
rbginst.Inst.Renderable = rndbc;
rbginst.Inst.Orientation = orientation;
rbginst.Inst.Scale = scale;
foreach (var geom in rndbc.Geometries)
{
if (geom == null) continue;
rbginst.Geom = geom;
rbginst.Inst.Position = position + orientation.Multiply(geom.BoundGeom.CenterGeom * scale);
rbginst.Inst.CamRel = rbginst.Inst.Position - camera.Position;
shaders.Enqueue(rbginst);
}
//UpdateMouseHits(rndbc, entity);
}
2017-09-21 18:33:05 +08:00
}
else
{ }
break;
case 3: //BoundBox - found in drawables - TODO
BoundBox boundbox = bounds as BoundBox;
if (boundbox == null)
{ }
break;
case 0: //BoundSphere - found in drawables - TODO
BoundSphere boundsphere = bounds as BoundSphere;
if (boundsphere == null)
{ }
break;
default:
break;
}
}
2017-09-21 18:33:05 +08:00
private void RenderNavmesh(YnvFile ynv)
{
RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(ynv);
if ((rnd != null) && (rnd.IsLoaded))
{
shaders.Enqueue(rnd);
2017-09-21 18:33:05 +08:00
}
}
2017-09-21 18:33:05 +08:00
private bool RenderIsModelFinalRender(RenderableModel model)
{
if ((model.Unk2Ch & 1) == 0) //smallest bit is proxy/"final render" bit? seems to work...
2017-09-21 18:33:05 +08:00
{
return false;// renderproxies;
2017-09-21 18:33:05 +08:00
}
return true;
2017-09-21 18:33:05 +08:00
//switch (model.Unk2Ch)
//{
// case 65784: //0000010000000011111000 //reflection proxy?
// case 65788: //0000010000000011111100
// case 131312: //0000100000000011110000 //reflection proxy?
// case 131320: //0000100000000011111000 //reflection proxy?
// case 131324: //0000100000000011111100 //shadow/reflection proxy?
// case 196834: //0000110000000011100010 //shadow proxy? (tree branches)
// case 196848: //0000110000000011110000 //reflection proxy?
// case 196856: //0000110000000011111000 //reflection proxy? hotel nr golf course
// case 262392: //0001000000000011111000 //reflection proxy?
// case 327932: //0001010000000011111100 //reflection proxy? (alamo/sandy shores)
// case 983268: //0011110000000011100100 //big reflection proxy?
// case 2293988://1000110000000011100100 //big reflection proxy?
// //case 1442047://golf course water proxy, but other things also
// //case 1114367://mike house water proxy, but other things also
// return renderproxies;
//}
//return true;
2017-09-21 18:33:05 +08:00
}
private void RenderSkeleton(Renderable renderable)
{
renderskeletonlist.Add(renderable);
}
2017-09-21 18:33:05 +08:00
private void RenderSkeletons(DeviceContext context)
2017-09-21 18:33:05 +08:00
{
skeletonLineVerts.Clear();
2017-09-21 18:33:05 +08:00
const uint cgrn = 4278255360;// (uint)new Color4(0.0f, 1.0f, 0.0f, 1.0f).ToRgba();
const uint cblu = 4294901760;// (uint)new Color4(0.0f, 0.0f, 1.0f, 1.0f).ToRgba();
VertexTypePC v1 = new VertexTypePC();
VertexTypePC v2 = new VertexTypePC();
v1.Colour = cgrn;
v2.Colour = cblu;
foreach (var renderable in renderskeletonlist)
2017-09-21 18:33:05 +08:00
{
DrawableBase drawable = renderable.Key;
Skeleton skeleton = drawable?.Skeleton;
if (skeleton == null) continue;
2017-09-21 18:33:05 +08:00
var pinds = skeleton.ParentIndices;
var bones = skeleton.Bones;
if ((pinds == null) || (bones == null)) continue;
var xforms = skeleton.Transformations;
2017-09-21 18:33:05 +08:00
int cnt = Math.Min(pinds.Length, bones.Count);
for (int i = 0; i < cnt; i++)
{
var pind = pinds[i];
var bone = bones[i];
var pbone = bone.Parent;
if (pbone == null) continue; //nothing to draw for the root bone
if (xforms != null)//how to use xforms? bind pose?
{
var xform = (i < xforms.Length) ? xforms[i] : Matrix.Identity;
var pxform = (pind < xforms.Length) ? xforms[pind] : Matrix.Identity;
}
else
{
}
2017-09-21 18:33:05 +08:00
//draw line from bone's position to parent position...
Vector3 lbeg = Vector3.Zero;
Vector3 lend = bone.Translation;// bone.Rotation.Multiply();
while (pbone != null)
{
lbeg = pbone.Rotation.Multiply(lbeg) + pbone.Translation;
lend = pbone.Rotation.Multiply(lend) + pbone.Translation;
pbone = pbone.Parent;
}
v1.Position = lbeg;
v2.Position = lend;
skeletonLineVerts.Add(v1);
skeletonLineVerts.Add(v2);
2017-09-21 18:33:05 +08:00
}
}
2017-09-21 18:33:05 +08:00
if (skeletonLineVerts.Count > 0)
{
shaders.SetDepthStencilMode(context, DepthStencilMode.DisableAll);
shaders.Paths.RenderLines(context, skeletonLineVerts, camera, shaders.GlobalLights);
}
}
2017-09-21 18:33:05 +08:00
public void LoadModel(YdrFile ydr)
{
if (ydr == null) return;
2017-09-21 18:33:05 +08:00
FileName = ydr.Name;
Ydr = ydr;
2017-09-21 18:33:05 +08:00
UpdateModelsUI(ydr.Drawable);
}
public void LoadModels(YddFile ydd)
{
if (ydd == null) return;
2017-09-21 18:33:05 +08:00
FileName = ydd.Name;
Ydd = ydd;
2017-09-21 18:33:05 +08:00
UpdateModelsUI(ydd.Dict);
2017-09-21 18:33:05 +08:00
DetailsPropertyGrid.SelectedObject = ydd;
}
public void LoadModel(YftFile yft)
2017-09-21 18:33:05 +08:00
{
if (yft == null) return;
2017-09-21 18:33:05 +08:00
FileName = yft.Name;
Yft = yft;
2017-09-21 18:33:05 +08:00
UpdateModelsUI(yft.Fragment.Drawable);
2017-09-21 18:33:05 +08:00
}
public void LoadModel(YbnFile ybn)
2017-09-21 18:33:05 +08:00
{
if (ybn == null) return;
FileName = ybn.Name;
Ybn = ybn;
UpdateBoundsUI(ybn.Bounds);
2017-09-21 18:33:05 +08:00
}
public void LoadParticles(YptFile ypt)
2017-09-21 18:33:05 +08:00
{
if (ypt == null) return;
FileName = ypt.Name;
Ypt = ypt;
UpdateModelsUI(ypt.DrawableDict);
DetailsPropertyGrid.SelectedObject = ypt;//.PtfxList;
2017-09-21 18:33:05 +08:00
}
public void LoadNavmesh(YnvFile ynv)
2017-09-21 18:33:05 +08:00
{
if (ynv == null) return;
2017-09-21 18:33:05 +08:00
FileName = ynv.Name;
Ynv = ynv;
2017-09-21 18:33:05 +08:00
//UpdateModelsUI(ypt.Particles.Drawable);
}
2017-09-21 18:33:05 +08:00
private void UpdateFormTitle()
2017-09-21 18:33:05 +08:00
{
Text = fileName + " - CodeWalker by dexyfex";
}
2017-09-21 18:33:05 +08:00
private void UpdateStatus(string text)
{
try
2017-09-21 18:33:05 +08:00
{
if (InvokeRequired)
2017-09-21 18:33:05 +08:00
{
BeginInvoke(new Action(() => { UpdateStatus(text); }));
}
else
{
StatusLabel.Text = text;
2017-09-21 18:33:05 +08:00
}
}
catch { }
2017-09-21 18:33:05 +08:00
}
private void LogError(string text)
2017-09-21 18:33:05 +08:00
{
try
{
if (InvokeRequired)
{
Invoke(new Action(() => { LogError(text); }));
}
else
{
ConsoleTextBox.AppendText(text + "\r\n");
}
}
catch { }
2017-09-21 18:33:05 +08:00
}
private void UpdateTimeOfDayLabel()
2017-09-21 18:33:05 +08:00
{
int v = TimeOfDayTrackBar.Value;
float fh = v / 60.0f;
int ih = (int)fh;
int im = v - (ih * 60);
if (ih == 24) ih = 0;
TimeOfDayLabel.Text = string.Format("{0:00}:{1:00}", ih, im);
}
2017-09-21 18:33:05 +08:00
private void UpdateTimeOfDay(float elapsed)
{
if (timerunning)
2017-09-21 18:33:05 +08:00
{
float helapsed = elapsed * timespeed / 60.0f;
timeofday += helapsed;
while (timeofday >= 24.0f) timeofday -= 24.0f;
while (timeofday < 0.0f) timeofday += 24.0f;
timecycle.SetTime(timeofday);
}
2017-09-21 18:33:05 +08:00
}
2017-09-21 18:33:05 +08:00
private void UpdateGlobalLights()
{
Vector3 lightdir = Vector3.Zero;//will be updated before each frame from X and Y vars
Color4 lightdircolour = Color4.White;
Color4 lightdirambcolour = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
Color4 lightnaturalupcolour = new Color4(0.0f);
Color4 lightnaturaldowncolour = new Color4(0.0f);
Color4 lightartificialupcolour = new Color4(0.0f);
Color4 lightartificialdowncolour = new Color4(0.0f);
bool hdr = shaders.hdr;
float hdrint = 1.0f;
Vector3 sundir = Vector3.Up;
Vector3 moondir = Vector3.Down;
Vector3 moonax = Vector3.UnitZ;
2017-09-21 18:33:05 +08:00
if (controllightdir || !timecycle.Inited)
{
float cryd = (float)Math.Cos(lightdiry);
lightdir.X = -(float)Math.Sin(-lightdirx) * cryd;
lightdir.Y = -(float)Math.Cos(-lightdirx) * cryd;
lightdir.Z = (float)Math.Sin(lightdiry);
lightdircolour = Color4.White;
lightdirambcolour = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
if (hdr && weather.Inited)
2017-09-21 18:33:05 +08:00
{
lightdircolour *= weather.CurrentValues.skyHdr;
lightdircolour.Alpha = 1.0f;
lightdirambcolour *= weather.CurrentValues.skyHdr;
lightdirambcolour.Alpha = 1.0f;
hdrint = weather.CurrentValues.skyHdr;
2017-09-21 18:33:05 +08:00
}
sundir = lightdir;
moondir = -lightdir;
moonax = Vector3.Normalize(Vector3.UnitY);
}
else
{
float sunroll = timecycle.sun_roll * (float)Math.PI / 180.0f; //122
float moonroll = timecycle.moon_roll * (float)Math.PI / 180.0f; //-122
float moonwobamp = timecycle.moon_wobble_amp; //0.2
float moonwobfreq = timecycle.moon_wobble_freq; //2
float moonwoboffs = timecycle.moon_wobble_offset; //0.375
float dayval = (0.5f + (timeofday - 6.0f) / 14.0f);
float nightval = (((timeofday > 12.0f) ? (timeofday - 7.0f) : (timeofday + 17.0f)) / 9.0f);
float daycyc = (float)Math.PI * dayval;
float nightcyc = (float)Math.PI * nightval;
Vector3 sdir = new Vector3((float)Math.Sin(daycyc), -(float)Math.Cos(daycyc), 0.0f);
Vector3 mdir = new Vector3(-(float)Math.Sin(nightcyc), 0.0f, -(float)Math.Cos(nightcyc));
Quaternion saxis = Quaternion.RotationYawPitchRoll(0.0f, sunroll, 0.0f);
Quaternion maxis = Quaternion.RotationYawPitchRoll(0.0f, -moonroll, 0.0f);
sundir = Vector3.Normalize(saxis.Multiply(sdir));
moondir = Vector3.Normalize(maxis.Multiply(mdir));
moonax = Vector3.Normalize(maxis.Multiply(Vector3.UnitY));
//bool usemoon = false;
2017-09-21 18:33:05 +08:00
lightdir = sundir;
2017-09-21 18:33:05 +08:00
//if (lightdir.Z < -0.5f) lightdir.Z = -lightdir.Z; //make sure the lightsource is always above the horizon...
2017-09-21 18:33:05 +08:00
if ((timeofday < 5.0f) || (timeofday > 21.0f))
2017-09-21 18:33:05 +08:00
{
lightdir = moondir;
//usemoon = true;
2017-09-21 18:33:05 +08:00
}
if (lightdir.Z < 0)
2017-09-21 18:33:05 +08:00
{
lightdir.Z = 0; //don't let the light source go below the horizon...
2017-09-21 18:33:05 +08:00
}
//lightdir = Vector3.Normalize(weather.CurrentValues.sunDirection);
if (weather != null && weather.Inited)
2017-09-21 18:33:05 +08:00
{
lightdircolour = (Color4)weather.CurrentValues.lightDirCol;
lightdirambcolour = (Color4)weather.CurrentValues.lightDirAmbCol;
lightnaturalupcolour = (Color4)weather.CurrentValues.lightNaturalAmbUp;
lightnaturaldowncolour = (Color4)weather.CurrentValues.lightNaturalAmbDown;
lightartificialupcolour = (Color4)weather.CurrentValues.lightArtificialExtUp;
lightartificialdowncolour = (Color4)weather.CurrentValues.lightArtificialExtDown;
float lamult = weather.CurrentValues.lightDirAmbIntensityMult;
float abounce = weather.CurrentValues.lightDirAmbBounce;
float minmult = hdr ? 0.1f : 0.5f;
lightdircolour *= Math.Max(lightdircolour.Alpha, minmult);
lightdirambcolour *= lightdirambcolour.Alpha * lamult; // 0.1f * lamult;
//if (usemoon)
//{
// lightdircolour *= weather.CurrentValues.skyMoonIten;
//}
lightnaturalupcolour *= lightnaturalupcolour.Alpha * weather.CurrentValues.lightNaturalAmbUpIntensityMult;
lightnaturaldowncolour *= lightnaturaldowncolour.Alpha;
lightartificialupcolour *= lightartificialupcolour.Alpha;
lightartificialdowncolour *= lightartificialdowncolour.Alpha;
if (!hdr)
2017-09-21 18:33:05 +08:00
{
Color4 maxdirc = new Color4(1.0f);
Color4 maxambc = new Color4(0.5f);
lightdircolour = Color4.Min(lightdircolour, maxdirc);
lightdirambcolour = Color4.Min(lightdirambcolour, maxambc);
lightnaturalupcolour = Color4.Min(lightnaturalupcolour, maxambc);
lightnaturaldowncolour = Color4.Min(lightnaturaldowncolour, maxambc);
lightartificialupcolour = Color4.Min(lightartificialupcolour, maxambc);
lightartificialdowncolour = Color4.Min(lightartificialdowncolour, maxambc);
2017-09-21 18:33:05 +08:00
}
else
{
hdrint = weather.CurrentValues.skyHdr;//.lightDirCol.W;
2017-09-21 18:33:05 +08:00
}
}
}
2017-09-21 18:33:05 +08:00
globalLights.Weather = weather;
globalLights.HdrEnabled = hdr;
globalLights.SpecularEnabled = true;// !MapViewEnabled;//disable specular for map view.
globalLights.HdrIntensity = Math.Max(hdrint, 1.0f);
globalLights.CurrentSunDir = sundir;
globalLights.CurrentMoonDir = moondir;
globalLights.MoonAxis = moonax;
globalLights.Params.LightDir = lightdir;
globalLights.Params.LightDirColour = lightdircolour;
globalLights.Params.LightDirAmbColour = lightdirambcolour;
globalLights.Params.LightNaturalAmbUp = rendernaturalambientlight ? lightnaturalupcolour : Color4.Black;
globalLights.Params.LightNaturalAmbDown = rendernaturalambientlight ? lightnaturaldowncolour : Color4.Black;
globalLights.Params.LightArtificialAmbUp = renderartificialambientlight ? lightartificialupcolour : Color4.Black;
globalLights.Params.LightArtificialAmbDown = renderartificialambientlight ? lightartificialdowncolour : Color4.Black;
2017-09-21 18:33:05 +08:00
if (shaders != null)
2017-09-21 18:33:05 +08:00
{
shaders.SetGlobalLightParams(globalLights);
2017-09-21 18:33:05 +08:00
}
}
private void UpdateWindVector(float elapsed)
2017-09-21 18:33:05 +08:00
{
//wind still needs a lot of work.
//currently just feed the wind vector with small oscillations...
currentWindTime += elapsed;
if (currentWindTime >= 200.0f) currentWindTime -= 200.0f;
2017-09-21 18:33:05 +08:00
float dirval = (float)(currentWindTime * 0.01 * Math.PI);
float dirval1 = (float)Math.Sin(currentWindTime * 0.100 * Math.PI) * 0.3f;
float dirval2 = (float)(currentWindTime * 0.333 * Math.PI);
float dirval3 = (float)(currentWindTime * 0.5 * Math.PI);
float dirval4 = (float)Math.Sin(currentWindTime * 0.223 * Math.PI) * 0.4f;
float dirval5 = (float)Math.Sin(currentWindTime * 0.4 * Math.PI) * 5.5f;
2017-09-21 18:33:05 +08:00
currentWindVec.Z = (float)Math.Sin(dirval) * dirval1 + (float)Math.Cos(dirval2) * dirval4;
currentWindVec.W = (float)Math.Cos(dirval) * dirval5 + (float)Math.Sin(dirval3) * dirval4;
2017-09-21 18:33:05 +08:00
float strval = (float)(currentWindTime * 0.1 * Math.PI);
float strval2 = (float)(currentWindTime * 0.825 * Math.PI);
float strval3 = (float)(currentWindTime * 0.333 * Math.PI);
float strval4 = (float)(currentWindTime * 0.666 * Math.PI);
float strbase = 0.1f * ((float)Math.Sin(strval * 0.5));
float strbase2 = 0.02f * ((float)Math.Sin(strval2 * 0.1));
2017-09-21 18:33:05 +08:00
currentWindVec.X = (float)Math.Sin(strval) * strbase + ((float)Math.Cos(strval3) * strbase2);
currentWindVec.Y = (float)Math.Cos(strval2) * strbase + ((float)Math.Sin(strval4 - strval3) * strbase2);
}
2017-09-21 18:33:05 +08:00
private void UpdateControlInputs(float elapsed)
{
var s = Settings.Default;
2017-09-21 18:33:05 +08:00
float moveSpeed = 10.0f;
2017-09-21 18:33:05 +08:00
bool xbenable = (xbcontroller != null) && (xbcontroller.IsConnected);
float lx = 0, ly = 0, rx = 0, ry = 0, lt = 0, rt = 0; //input axes
if (xbenable)
2017-09-21 18:33:05 +08:00
{
xbcontrollerstateprev = xbcontrollerstate;
xbcontrollerstate = xbcontroller.GetState();
xbmainaxesprev = xbmainaxes;
xbtrigsprev = xbtrigs;
xbmainaxes = ControllerMainAxes();
xbtrigs = ControllerTriggers();
lx = xbmainaxes.X;
ly = xbmainaxes.Y;
rx = xbmainaxes.Z;
ry = xbmainaxes.W;
lt = xbtrigs.X;
rt = xbtrigs.Y;
float lamt = s.XInputLThumbSensitivity * elapsed;
float ramt = s.XInputRThumbSensitivity * elapsed;
ly = s.XInputLThumbInvert ? ly : -ly;
ry = s.XInputRThumbInvert ? ry : -ry;
lx *= lamt;
ly *= lamt;
rx *= ramt;
ry *= ramt;
2017-09-21 18:33:05 +08:00
//if (ControllerButtonJustPressed(GamepadButtonFlags.Start))
2017-09-21 18:33:05 +08:00
//{
// SetControlMode(ControlMode == WorldControlMode.Free ? WorldControlMode.Ped : WorldControlMode.Free);
2017-09-21 18:33:05 +08:00
//}
}
2017-09-21 18:33:05 +08:00
Vector3 movevec = Vector3.Zero;
//if (MapViewEnabled == true)
//{
// if (kbmovefwd) movevec.Y += 1.0f;
// if (kbmovebck) movevec.Y -= 1.0f;
// if (kbmovelft) movevec.X -= 1.0f;
// if (kbmovergt) movevec.X += 1.0f;
// if (kbmoveup) movevec.Y += 1.0f;
// if (kbmovedn) movevec.Y -= 1.0f;
// movevec *= elapsed * 100.0f * Math.Min(camera.OrthographicTargetSize * 0.01f, 30.0f);
// float mapviewscale = 1.0f / camera.Height;
// float fdx = MapViewDragX * mapviewscale;
// float fdy = MapViewDragY * mapviewscale;
// movevec.X -= fdx * camera.OrthographicSize;
// movevec.Y += fdy * camera.OrthographicSize;
//}
//else
2017-09-21 18:33:05 +08:00
{
//normal movement
if (kbmovefwd) movevec.Z -= 1.0f;
if (kbmovebck) movevec.Z += 1.0f;
if (kbmovelft) movevec.X -= 1.0f;
if (kbmovergt) movevec.X += 1.0f;
if (kbmoveup) movevec.Y += 1.0f;
if (kbmovedn) movevec.Y -= 1.0f;
movevec *= elapsed * moveSpeed * Math.Min(camera.TargetDistance, 50.0f);
}
2017-09-21 18:33:05 +08:00
Vector3 movewvec = camera.ViewInvQuaternion.Multiply(movevec);
camEntity.Position += movewvec;
2017-09-21 18:33:05 +08:00
//MapViewDragX = 0;
//MapViewDragY = 0;
2017-09-21 18:33:05 +08:00
if (xbenable)
{
camera.ControllerRotate(lx + rx, ly + ry);
2017-09-21 18:33:05 +08:00
float zoom = 0.0f;
float zoomspd = s.XInputZoomSpeed;
float zoomamt = zoomspd * elapsed;
if (ControllerButtonPressed(GamepadButtonFlags.DPadUp)) zoom += zoomamt;
if (ControllerButtonPressed(GamepadButtonFlags.DPadDown)) zoom -= zoomamt;
2017-09-21 18:33:05 +08:00
camera.ControllerZoom(zoom);
2017-09-21 18:33:05 +08:00
float acc = 0.0f;
float accspd = s.XInputMoveSpeed;//actually accel speed...
acc += rt * accspd;
acc -= lt * accspd;
2017-09-21 18:33:05 +08:00
Vector3 newdir = camera.ViewDirection; //maybe use the "vehicle" direction...?
xbcontrolvelocity += (acc * elapsed);
2017-09-21 18:33:05 +08:00
if (ControllerButtonPressed(GamepadButtonFlags.A | GamepadButtonFlags.RightShoulder)) //handbrake...
{
xbcontrolvelocity *= Math.Max(0.75f - elapsed, 0);//not ideal for low fps...
//xbcontrolvelocity = 0.0f;
if (Math.Abs(xbcontrolvelocity) < 0.001f) xbcontrolvelocity = 0.0f;
}
2017-09-21 18:33:05 +08:00
camEntity.Velocity = newdir * xbcontrolvelocity;
camEntity.Position += camEntity.Velocity * elapsed;
2017-09-21 18:33:05 +08:00
//fire!
//if (ControllerButtonJustPressed(GamepadButtonFlags.LeftShoulder))
//{
// SpawnTestEntity(true);
//}
}
2017-09-21 18:33:05 +08:00
}
private Vector4 ControllerMainAxes()
2017-09-21 18:33:05 +08:00
{
var gp = xbcontrollerstate.Gamepad;
var ldz = Gamepad.LeftThumbDeadZone;
var rdz = Gamepad.RightThumbDeadZone;
float ltnrng = -(short.MinValue + ldz);
float ltprng = (short.MaxValue - ldz);
float rtnrng = -(short.MinValue + rdz);
float rtprng = (short.MaxValue - rdz);
2017-09-21 18:33:05 +08:00
float lx = (gp.LeftThumbX < 0) ? Math.Min((gp.LeftThumbX + ldz) / ltnrng, 0) :
(gp.LeftThumbX > 0) ? Math.Max((gp.LeftThumbX - ldz) / ltprng, 0) : 0;
float ly = (gp.LeftThumbY < 0) ? Math.Min((gp.LeftThumbY + ldz) / ltnrng, 0) :
(gp.LeftThumbY > 0) ? Math.Max((gp.LeftThumbY - ldz) / ltprng, 0) : 0;
float rx = (gp.RightThumbX < 0) ? Math.Min((gp.RightThumbX + rdz) / rtnrng, 0) :
(gp.RightThumbX > 0) ? Math.Max((gp.RightThumbX - rdz) / rtprng, 0) : 0;
float ry = (gp.RightThumbY < 0) ? Math.Min((gp.RightThumbY + rdz) / rtnrng, 0) :
(gp.RightThumbY > 0) ? Math.Max((gp.RightThumbY - rdz) / rtprng, 0) : 0;
2017-09-21 18:33:05 +08:00
return new Vector4(lx, ly, rx, ry);
}
private Vector2 ControllerTriggers()
{
var gp = xbcontrollerstate.Gamepad;
var tt = Gamepad.TriggerThreshold;
float trng = byte.MaxValue - tt;
float lt = Math.Max((gp.LeftTrigger - tt) / trng, 0);
float rt = Math.Max((gp.RightTrigger - tt) / trng, 0);
return new Vector2(lt, rt);
}
private bool ControllerButtonPressed(GamepadButtonFlags b)
{
return ((xbcontrollerstate.Gamepad.Buttons & b) != 0);
}
private bool ControllerButtonJustPressed(GamepadButtonFlags b)
{
return (((xbcontrollerstate.Gamepad.Buttons & b) != 0) && ((xbcontrollerstateprev.Gamepad.Buttons & b) == 0));
}
2017-09-21 18:33:05 +08:00
private void UpdateModelsUI(DrawableBase drawable)
{
DetailsPropertyGrid.SelectedObject = drawable;
2017-09-21 18:33:05 +08:00
DrawableDrawFlags.Clear();
ModelDrawFlags.Clear();
GeometryDrawFlags.Clear();
ModelsTreeView.Nodes.Clear();
ModelsTreeView.ShowRootLines = false;
TexturesTreeView.Nodes.Clear();
if (drawable != null)
2017-09-21 18:33:05 +08:00
{
AddDrawableModelsTreeNodes(drawable.DrawableModelsHigh, "High Detail", true);
AddDrawableModelsTreeNodes(drawable.DrawableModelsMedium, "Medium Detail", false);
AddDrawableModelsTreeNodes(drawable.DrawableModelsLow, "Low Detail", false);
AddDrawableModelsTreeNodes(drawable.DrawableModelsVeryLow, "Very Low Detail", false);
//AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false);
2017-09-21 18:33:05 +08:00
}
}
private void UpdateModelsUI(FragType frag)
{
DetailsPropertyGrid.SelectedObject = frag;
2017-09-21 18:33:05 +08:00
var drawable = frag.Drawable;
2017-09-21 18:33:05 +08:00
DrawableDrawFlags.Clear();
ModelDrawFlags.Clear();
GeometryDrawFlags.Clear();
ModelsTreeView.Nodes.Clear();
ModelsTreeView.ShowRootLines = false;
TexturesTreeView.Nodes.Clear();
if (drawable != null)
2017-09-21 18:33:05 +08:00
{
AddDrawableModelsTreeNodes(drawable.DrawableModelsHigh, "High Detail", true);
AddDrawableModelsTreeNodes(drawable.DrawableModelsMedium, "Medium Detail", false);
AddDrawableModelsTreeNodes(drawable.DrawableModelsLow, "Low Detail", false);
AddDrawableModelsTreeNodes(drawable.DrawableModelsVeryLow, "Very Low Detail", false);
//AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false);
}
}
private void UpdateModelsUI(Dictionary<uint, Drawable> dict)
{
//DetailsPropertyGrid.SelectedObject = dict; //this won't look good...
2017-09-21 18:33:05 +08:00
DrawableDrawFlags.Clear();
ModelDrawFlags.Clear();
GeometryDrawFlags.Clear();
ModelsTreeView.Nodes.Clear();
ModelsTreeView.ShowRootLines = true;
TexturesTreeView.Nodes.Clear();
2017-09-21 18:33:05 +08:00
bool check = true;
if (dict != null)
{
foreach (var kvp in dict)
2017-09-21 18:33:05 +08:00
{
AddDrawableTreeNode(kvp.Value, kvp.Key, check);
check = false;
}
}
2017-09-21 18:33:05 +08:00
ToolsPanel.Visible = true; //show the panel by default for dictionaries...
}
private void UpdateBoundsUI(Bounds bounds)
{
DetailsPropertyGrid.SelectedObject = bounds;
}
private void UpdateNavmeshUI(YnvFile ynv)
{
DetailsPropertyGrid.SelectedObject = ynv.Nav;
}
2017-09-21 18:33:05 +08:00
private void AddDrawableTreeNode(DrawableBase drawable, uint hash, bool check)
{
MetaHash mhash = new MetaHash(hash);
var dnode = ModelsTreeView.Nodes.Add(mhash.ToString());
dnode.Tag = drawable;
dnode.Checked = check;
2017-09-21 18:33:05 +08:00
AddDrawableModelsTreeNodes(drawable.DrawableModelsHigh, "High Detail", true, dnode);
AddDrawableModelsTreeNodes(drawable.DrawableModelsMedium, "Medium Detail", false, dnode);
AddDrawableModelsTreeNodes(drawable.DrawableModelsLow, "Low Detail", false, dnode);
AddDrawableModelsTreeNodes(drawable.DrawableModelsVeryLow, "Very Low Detail", false, dnode);
//AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false, dnode);
2017-09-21 18:33:05 +08:00
}
private void AddDrawableModelsTreeNodes(ResourcePointerList64<DrawableModel> models, string prefix, bool check, TreeNode parentDrawableNode = null)
{
if (models == null) return;
if (models.data_items == null) return;
2017-09-21 18:33:05 +08:00
for (int mi = 0; mi < models.data_items.Length; mi++)
2017-09-21 18:33:05 +08:00
{
var tnc = (parentDrawableNode != null) ? parentDrawableNode.Nodes : ModelsTreeView.Nodes;
2017-09-21 18:33:05 +08:00
var model = models.data_items[mi];
string mprefix = prefix + " " + (mi + 1).ToString();
var mnode = tnc.Add(mprefix + " " + model.ToString());
mnode.Tag = model;
mnode.Checked = check;
2017-09-21 18:33:05 +08:00
var tmnode = TexturesTreeView.Nodes.Add(mprefix + " " + model.ToString());
tmnode.Tag = model;
2017-09-21 18:33:05 +08:00
if (!check)
{
ModelDrawFlags[model] = false;
}
2017-09-21 18:33:05 +08:00
if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue;
foreach (var geom in model.Geometries.data_items)
{
var gname = geom.ToString();
var gnode = mnode.Nodes.Add(gname);
gnode.Tag = geom;
gnode.Checked = true;// check;
var tgnode = tmnode.Nodes.Add(gname);
tgnode.Tag = geom;
if ((geom.Shader != null) && (geom.Shader.ParametersList != null) && (geom.Shader.ParametersList.Hashes != null))
2017-09-21 18:33:05 +08:00
{
var pl = geom.Shader.ParametersList;
var h = pl.Hashes;
var p = pl.Parameters;
for (int ip = 0; ip < h.Length; ip++)
2017-09-21 18:33:05 +08:00
{
var hash = pl.Hashes[ip];
var parm = pl.Parameters[ip];
var tex = parm.Data as TextureBase;
if (tex != null)
2017-09-21 18:33:05 +08:00
{
var t = tex as Texture;
var tstr = tex.Name.Trim();
if (t != null)
{
tstr = string.Format("{0} ({1}x{2}, embedded)", tex.Name, t.Width, t.Height);
}
var tnode = tgnode.Nodes.Add(hash.ToString().Trim() + ": " + tstr);
tnode.Tag = tex;
2017-09-21 18:33:05 +08:00
}
}
tgnode.Expand();
2017-09-21 18:33:05 +08:00
}
}
2017-09-21 18:33:05 +08:00
mnode.Expand();
tmnode.Expand();
2017-09-21 18:33:05 +08:00
}
}
private void UpdateSelectionDrawFlags(TreeNode node)
2017-09-21 18:33:05 +08:00
{
//update the selection draw flags depending on tag and checked/unchecked
var drwbl = node.Tag as DrawableBase;
var model = node.Tag as DrawableModel;
var geom = node.Tag as DrawableGeometry;
bool rem = node.Checked;
lock (rendersyncroot)
2017-09-21 18:33:05 +08:00
{
if (drwbl != null)
{
if (rem)
{
if (DrawableDrawFlags.ContainsKey(drwbl))
{
DrawableDrawFlags.Remove(drwbl);
}
}
else
{
DrawableDrawFlags[drwbl] = false;
}
}
if (model != null)
{
if (rem)
{
if (ModelDrawFlags.ContainsKey(model))
{
ModelDrawFlags.Remove(model);
}
}
else
{
ModelDrawFlags[model] = false;
}
}
if (geom != null)
{
if (rem)
{
if (GeometryDrawFlags.ContainsKey(geom))
{
GeometryDrawFlags.Remove(geom);
}
}
else
{
GeometryDrawFlags[geom] = false;
}
}
updateArchetypeStatus = true;
2017-09-21 18:33:05 +08:00
}
}
private void ModelForm_Load(object sender, EventArgs e)
{
Init();
}
private void ModelForm_MouseDown(object sender, MouseEventArgs e)
{
switch (e.Button)
{
case MouseButtons.Left: MouseLButtonDown = true; break;
case MouseButtons.Right: MouseRButtonDown = true; break;
}
MouseDownPoint = e.Location;
MouseLastPoint = MouseDownPoint;
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 ModelForm_MouseUp(object sender, MouseEventArgs e)
{
switch (e.Button)
{
case MouseButtons.Left: MouseLButtonDown = false; break;
case MouseButtons.Right: MouseRButtonDown = false; break;
}
//lock (MouseControlSyncRoot)
//{
// MouseControlButtons &= ~e.Button;
//}
}
private void ModelForm_MouseMove(object sender, MouseEventArgs e)
{
int dx = e.X - MouseX;
int dy = e.Y - MouseY;
if (MouseLButtonDown)
{
camera.MouseRotate(dx, dy);
}
if (MouseRButtonDown)
{
if (controllightdir)
{
lightdirx += (dx * camera.Sensitivity);
lightdiry += (dy * camera.Sensitivity);
}
else if (controltimeofday)
{
timeofday += (dx - dy) / 30.0f;
while (timeofday >= 24.0f) timeofday -= 24.0f;
while (timeofday < 0.0f) timeofday += 24.0f;
timecycle.SetTime(timeofday);
float fv = timeofday * 60.0f;
TimeOfDayTrackBar.Value = (int)fv;
UpdateTimeOfDayLabel();
}
}
MouseX = e.X;
MouseY = e.Y;
MouseLastPoint = e.Location;
}
private void ModelForm_MouseWheel(object sender, MouseEventArgs e)
{
if (e.Delta != 0)
{
//if (ControlMode == WorldControlMode.Free)
//{
camera.MouseZoom(e.Delta);
//}
//else
//{
// lock (MouseControlSyncRoot)
// {
// MouseControlWheel += e.Delta;
// }
//}
}
}
private void ModelForm_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
}
var k = e.KeyCode;
bool ctrl = (e.Modifiers & Keys.Control) > 0;
bool shift = (e.Modifiers & Keys.Shift) > 0;
CtrlPressed = ctrl;
ShiftPressed = shift;
bool enablemove = true;// (!iseditmode) || (MouseLButtonDown && (GrabbedMarker == null) && (GrabbedWidget == null));
enablemove = enablemove && (!ctrl);
//WASD move the camera entity...
if (enablemove)
{
if (k == keyBindings.MoveForward) kbmovefwd = true;
if (k == keyBindings.MoveBackward) kbmovebck = true;
if (k == keyBindings.MoveLeft) kbmovelft = true;
if (k == keyBindings.MoveRight) kbmovergt = true;
if (k == keyBindings.MoveUp) kbmoveup = true;
if (k == keyBindings.MoveDown) kbmovedn = true;
if (k == keyBindings.Jump) kbjump = true;
}
bool moving = kbmovefwd || kbmovebck || kbmovelft || kbmovergt || kbmoveup || kbmovedn || kbjump;
if (!ctrl)
{
if (k == keyBindings.MoveSlowerZoomIn)
{
camera.MouseZoom(1);
}
if (k == keyBindings.MoveFasterZoomOut)
{
camera.MouseZoom(-1);
}
}
if (!moving) //don't trigger further actions if moving.
{
if (!ctrl)
{
//switch widget modes and spaces.
//if ((k == keyBindings.ExitEditMode))
//{
// if (Widget.Mode == WidgetMode.Default) ToggleWidgetSpace();
// else SetWidgetMode("Default");
//}
//if ((k == keyBindings.EditPosition))// && !enablemove)
//{
// if (Widget.Mode == WidgetMode.Position) ToggleWidgetSpace();
// else SetWidgetMode("Position");
//}
//if ((k == keyBindings.EditRotation))// && !enablemove)
//{
// if (Widget.Mode == WidgetMode.Rotation) ToggleWidgetSpace();
// else SetWidgetMode("Rotation");
//}
//if ((k == keyBindings.EditScale))// && !enablemove)
//{
// if (Widget.Mode == WidgetMode.Scale) ToggleWidgetSpace();
// else SetWidgetMode("Scale");
//}
//if (k == keyBindings.ToggleMouseSelect)
//{
// SetMouseSelect(!MouseSelectEnabled);
//}
//if (k == keyBindings.ToggleToolbar)
//{
// ToggleToolbar();
//}
//if (k == Keys.P)
//{
// //TEMPORARY!
// SetControlMode((ControlMode == WorldControlMode.Free) ? WorldControlMode.Ped : WorldControlMode.Free);
//}
}
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 (k == Keys.Escape) //temporary? panic get cursor back
//{
// if (ControlMode != WorldControlMode.Free) SetControlMode(WorldControlMode.Free);
//}
}
//if (ControlMode != WorldControlMode.Free)
//{
// e.Handled = true;
//}
}
private void ModelForm_KeyUp(object sender, KeyEventArgs e)
{
bool ctrl = (e.Modifiers & Keys.Control) > 0;
bool shift = (e.Modifiers & Keys.Shift) > 0;
CtrlPressed = ctrl;
ShiftPressed = shift;
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
}
var k = e.KeyCode;
if (k == keyBindings.MoveForward) kbmovefwd = false;
if (k == keyBindings.MoveBackward) kbmovebck = false;
if (k == keyBindings.MoveLeft) kbmovelft = false;
if (k == keyBindings.MoveRight) kbmovergt = false;
if (k == keyBindings.MoveUp) kbmoveup = false;
if (k == keyBindings.MoveDown) kbmovedn = false;
if (k == keyBindings.Jump) kbjump = false;
//if (ControlMode != WorldControlMode.Free)
//{
// e.Handled = true;
//}
}
2017-09-26 08:27:18 +08:00
private void ModelForm_Deactivate(object sender, EventArgs e)
{
//try not to lock keyboard movement if the form loses focus.
kbmovefwd = false;
kbmovebck = false;
kbmovelft = false;
kbmovergt = false;
kbmoveup = false;
kbmovedn = false;
kbjump = false;
}
private void StatsUpdateTimer_Tick(object sender, EventArgs e)
{
int rgc = (shaders != null) ? shaders.RenderedGeometries : 0;
int crc = renderableCache.LoadedRenderableCount;
int ctc = renderableCache.LoadedTextureCount;
int tcrc = renderableCache.MemCachedRenderableCount;
int tctc = renderableCache.MemCachedTextureCount;
long vr = renderableCache.TotalGraphicsMemoryUse + (shaders != null ? shaders.TotalGraphicsMemoryUse : 0);
string vram = TextUtil.GetBytesReadable(vr);
//StatsLabel.Text = string.Format("Drawn: {0} geom, Loaded: {1}/{5} dr, {2}/{6} tx, Vram: {3}, Fps: {4}", rgc, crc, ctc, vram, fps, tcrc, tctc);
StatsLabel.Text = string.Format("Drawn: {0} geom, Loaded: {1} dr, {2} tx, Vram: {3}, Fps: {4}", rgc, crc, ctc, vram, fps);
if (timerunning)
{
float fv = timeofday * 60.0f;
//TimeOfDayTrackBar.Value = (int)fv;
UpdateTimeOfDayLabel();
}
//CameraPositionTextBox.Text = FloatUtil.GetVector3String(camera.Position, "0.##");
}
2017-09-21 18:33:05 +08:00
private void ToolsPanelShowButton_Click(object sender, EventArgs e)
{
ToolsPanel.Visible = true;
}
private void ToolsPanelHideButton_Click(object sender, EventArgs e)
{
ToolsPanel.Visible = false;
}
private void ToolsDragPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
toolsPanelResizing = true;
toolsPanelResizeStartX = e.X + ToolsPanel.Left + ToolsDragPanel.Left;
toolsPanelResizeStartLeft = ToolsPanel.Left;
toolsPanelResizeStartRight = ToolsPanel.Right;
}
}
private void ToolsDragPanel_MouseUp(object sender, MouseEventArgs e)
{
toolsPanelResizing = false;
}
private void ToolsDragPanel_MouseMove(object sender, MouseEventArgs e)
{
if (toolsPanelResizing)
{
int rx = e.X + ToolsPanel.Left + ToolsDragPanel.Left;
int dx = rx - toolsPanelResizeStartX;
ToolsPanel.Width = toolsPanelResizeStartRight - toolsPanelResizeStartLeft + dx;
}
}
private void ModelsTreeView_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Node != null)
{
UpdateSelectionDrawFlags(e.Node);
}
}
private void ModelsTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Node != null)
{
e.Node.Checked = !e.Node.Checked;
//UpdateSelectionDrawFlags(e.Node);
}
}
private void ModelsTreeView_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true; //stops annoying ding sound...
}
private void HDRRenderingCheckBox_CheckedChanged(object sender, EventArgs e)
{
lock (rendersyncroot)
{
shaders.hdr = HDRRenderingCheckBox.Checked;
}
}
private void ShadowsCheckBox_CheckedChanged(object sender, EventArgs e)
{
lock (rendersyncroot)
{
shaders.shadows = ShadowsCheckBox.Checked;
}
}
private void SkydomeCheckBox_CheckedChanged(object sender, EventArgs e)
{
renderskydome = SkydomeCheckBox.Checked;
//controllightdir = !renderskydome;
}
private void ControlLightDirCheckBox_CheckedChanged(object sender, EventArgs e)
{
controllightdir = ControlLightDirCheckBox.Checked;
}
private void TimeOfDayTrackBar_Scroll(object sender, EventArgs e)
{
int v = TimeOfDayTrackBar.Value;
float fh = v / 60.0f;
UpdateTimeOfDayLabel();
lock (rendersyncroot)
{
timeofday = fh;
timecycle.SetTime(timeofday);
}
}
private void ShowBoundsCheckBox_CheckedChanged(object sender, EventArgs e)
{
rendercollisionmeshes = ShowBoundsCheckBox.Checked;
}
private void WireframeCheckBox_CheckedChanged(object sender, EventArgs e)
{
shaders.wireframe = WireframeCheckBox.Checked;
}
private void AnisotropicFilteringCheckBox_CheckedChanged(object sender, EventArgs e)
{
shaders.AnisotropicFiltering = AnisotropicFilteringCheckBox.Checked;
}
private void RenderModeComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
TextureSamplerComboBox.Enabled = false;
TextureCoordsComboBox.Enabled = false;
switch (RenderModeComboBox.Text)
{
default:
case "Default":
shaders.RenderMode = WorldRenderMode.Default;
break;
case "Single texture":
shaders.RenderMode = WorldRenderMode.SingleTexture;
TextureSamplerComboBox.Enabled = true;
TextureCoordsComboBox.Enabled = true;
break;
case "Vertex normals":
shaders.RenderMode = WorldRenderMode.VertexNormals;
break;
case "Vertex tangents":
shaders.RenderMode = WorldRenderMode.VertexTangents;
break;
case "Vertex colour 1":
shaders.RenderMode = WorldRenderMode.VertexColour;
shaders.RenderVertexColourIndex = 1;
break;
case "Vertex colour 2":
shaders.RenderMode = WorldRenderMode.VertexColour;
shaders.RenderVertexColourIndex = 2;
break;
case "Vertex colour 3":
shaders.RenderMode = WorldRenderMode.VertexColour;
shaders.RenderVertexColourIndex = 3;
break;
case "Texture coord 1":
shaders.RenderMode = WorldRenderMode.TextureCoord;
shaders.RenderTextureCoordIndex = 1;
break;
case "Texture coord 2":
shaders.RenderMode = WorldRenderMode.TextureCoord;
shaders.RenderTextureCoordIndex = 2;
break;
case "Texture coord 3":
shaders.RenderMode = WorldRenderMode.TextureCoord;
shaders.RenderTextureCoordIndex = 3;
break;
}
}
private void TextureSamplerComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (TextureSamplerComboBox.SelectedItem is MetaName)
{
shaders.RenderTextureSampler = (MetaName)TextureSamplerComboBox.SelectedItem;
}
}
private void TextureCoordsComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
switch (TextureCoordsComboBox.Text)
{
default:
case "Texture coord 1":
shaders.RenderTextureSamplerCoord = 1;
break;
case "Texture coord 2":
shaders.RenderTextureSamplerCoord = 2;
break;
case "Texture coord 3":
shaders.RenderTextureSamplerCoord = 3;
break;
}
}
private void GridCheckBox_CheckedChanged(object sender, EventArgs e)
{
enableGrid = GridCheckBox.Checked;
}
private void GridSizeComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
float newgs;
float.TryParse(GridSizeComboBox.Text, out newgs);
if (newgs != gridSize)
{
gridSize = newgs;
UpdateGridVerts();
}
}
private void GridCountComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
int newgc;
int.TryParse(GridCountComboBox.Text, out newgc);
if (newgc != gridCount)
{
gridCount = newgc;
UpdateGridVerts();
}
}
private void SkeletonsCheckBox_CheckedChanged(object sender, EventArgs e)
{
renderskeletons = SkeletonsCheckBox.Checked;
}
2017-09-21 18:33:05 +08:00
private void ErrorConsoleCheckBox_CheckedChanged(object sender, EventArgs e)
{
ConsolePanel.Visible = ErrorConsoleCheckBox.Checked;
}
private void StatusBarCheckBox_CheckedChanged(object sender, EventArgs e)
{
StatusStrip.Visible = StatusBarCheckBox.Checked;
}
}
}