diff --git a/CodeWalker.csproj b/CodeWalker.csproj index 851ede2..9b7e7d6 100644 --- a/CodeWalker.csproj +++ b/CodeWalker.csproj @@ -344,6 +344,7 @@ + @@ -392,6 +393,8 @@ + + diff --git a/ExploreForm.cs b/ExploreForm.cs index 4cda937..881a937 100644 --- a/ExploreForm.cs +++ b/ExploreForm.cs @@ -90,9 +90,9 @@ namespace CodeWalker { if (FileCache.IsInited) { - FileCache.ContentThreadProc(); + bool fcItemsPending = FileCache.ContentThreadProc(); - if (!FileCache.ItemsStillPending) + if (!fcItemsPending) { Thread.Sleep(10); } diff --git a/Forms/ModelForm.Designer.cs b/Forms/ModelForm.Designer.cs index fb927a6..e912f8d 100644 --- a/Forms/ModelForm.Designer.cs +++ b/Forms/ModelForm.Designer.cs @@ -51,7 +51,7 @@ this.label19 = new System.Windows.Forms.Label(); this.TimeOfDayTrackBar = new System.Windows.Forms.TrackBar(); this.ControlLightDirCheckBox = new System.Windows.Forms.CheckBox(); - this.ShowBoundsCheckBox = new System.Windows.Forms.CheckBox(); + this.ShowCollisionMeshesCheckBox = new System.Windows.Forms.CheckBox(); this.GridCheckBox = new System.Windows.Forms.CheckBox(); this.GridCountComboBox = new System.Windows.Forms.ComboBox(); this.label2 = new System.Windows.Forms.Label(); @@ -258,7 +258,7 @@ this.ToolsOptionsTabPage.Controls.Add(this.label19); this.ToolsOptionsTabPage.Controls.Add(this.TimeOfDayTrackBar); this.ToolsOptionsTabPage.Controls.Add(this.ControlLightDirCheckBox); - this.ToolsOptionsTabPage.Controls.Add(this.ShowBoundsCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.ShowCollisionMeshesCheckBox); this.ToolsOptionsTabPage.Controls.Add(this.GridCheckBox); this.ToolsOptionsTabPage.Controls.Add(this.GridCountComboBox); this.ToolsOptionsTabPage.Controls.Add(this.label2); @@ -341,16 +341,16 @@ this.ControlLightDirCheckBox.UseVisualStyleBackColor = true; this.ControlLightDirCheckBox.CheckedChanged += new System.EventHandler(this.ControlLightDirCheckBox_CheckedChanged); // - // ShowBoundsCheckBox + // ShowCollisionMeshesCheckBox // - this.ShowBoundsCheckBox.AutoSize = true; - this.ShowBoundsCheckBox.Location = new System.Drawing.Point(19, 176); - this.ShowBoundsCheckBox.Name = "ShowBoundsCheckBox"; - this.ShowBoundsCheckBox.Size = new System.Drawing.Size(124, 17); - this.ShowBoundsCheckBox.TabIndex = 7; - this.ShowBoundsCheckBox.Text = "Show Model Bounds"; - this.ShowBoundsCheckBox.UseVisualStyleBackColor = true; - this.ShowBoundsCheckBox.CheckedChanged += new System.EventHandler(this.ShowBoundsCheckBox_CheckedChanged); + this.ShowCollisionMeshesCheckBox.AutoSize = true; + this.ShowCollisionMeshesCheckBox.Location = new System.Drawing.Point(19, 176); + this.ShowCollisionMeshesCheckBox.Name = "ShowCollisionMeshesCheckBox"; + this.ShowCollisionMeshesCheckBox.Size = new System.Drawing.Size(132, 17); + this.ShowCollisionMeshesCheckBox.TabIndex = 7; + this.ShowCollisionMeshesCheckBox.Text = "Show collision meshes"; + this.ShowCollisionMeshesCheckBox.UseVisualStyleBackColor = true; + this.ShowCollisionMeshesCheckBox.CheckedChanged += new System.EventHandler(this.ShowCollisionMeshesCheckBox_CheckedChanged); // // GridCheckBox // @@ -681,7 +681,7 @@ private System.Windows.Forms.Label label2; private System.Windows.Forms.ComboBox GridSizeComboBox; private System.Windows.Forms.Label label1; - private System.Windows.Forms.CheckBox ShowBoundsCheckBox; + private System.Windows.Forms.CheckBox ShowCollisionMeshesCheckBox; private System.Windows.Forms.CheckBox ControlLightDirCheckBox; private System.Windows.Forms.Label TimeOfDayLabel; private System.Windows.Forms.Label label19; diff --git a/Forms/ModelForm.cs b/Forms/ModelForm.cs index bbcf60c..0a3b15d 100644 --- a/Forms/ModelForm.cs +++ b/Forms/ModelForm.cs @@ -23,14 +23,9 @@ 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; + private Renderer Renderer = null; + volatile bool formopen = false; //volatile bool running = false; @@ -38,10 +33,10 @@ namespace CodeWalker.Forms //volatile bool initialised = false; Stopwatch frametimer = new Stopwatch(); - Camera camera = new Camera(); - Timecycle timecycle = new Timecycle(); - Weather weather = new Weather(); - Clouds clouds = new Clouds(); + Camera camera; + Timecycle timecycle; + Weather weather; + Clouds clouds; bool MouseLButtonDown = false; bool MouseRButtonDown = false; @@ -52,49 +47,13 @@ namespace CodeWalker.Forms - //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; @@ -117,25 +76,10 @@ namespace CodeWalker.Forms YptFile Ypt = null; YnvFile Ynv = null; - bool waitforchildrentoload = true; - bool rendercollisionmeshes = false;// Settings.Default.ShowCollisionMeshes; - - bool renderskeletons = true; - List renderskeletonlist = new List(); - List skeletonLineVerts = new List(); - bool CtrlPressed = false; - bool ShiftPressed = false; + InputManager Input = new InputManager(); - 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; @@ -143,8 +87,6 @@ namespace CodeWalker.Forms int toolsPanelResizeStartRight = 0; Dictionary DrawableDrawFlags = new Dictionary(); - Dictionary ModelDrawFlags = new Dictionary(); - Dictionary GeometryDrawFlags = new Dictionary(); bool enableGrid = true; @@ -163,14 +105,27 @@ namespace CodeWalker.Forms InitializeComponent(); - gameFileCache = ExpForm?.GetFileCache(); + gameFileCache = ExpForm?.GetFileCache(); - initedOk = dxman.Init(this, false); + 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.rendermoon = false; + Renderer.renderskeletons = true; + Renderer.SelectionFlagsTestAll = true; } private void Init() { - //called from WorldForm_Load + //called from ModelForm_Load if (!initedOk) { @@ -228,49 +183,21 @@ namespace CodeWalker.Forms - InitController(); + Input.Init(); - 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; - } - + Renderer.Start(); } 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 + Renderer.DeviceCreated(device, width, height); } catch (Exception ex) { @@ -280,9 +207,7 @@ namespace CodeWalker.Forms //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); @@ -303,10 +228,7 @@ namespace CodeWalker.Forms { formopen = false; - renderableCache.OnDeviceDestroyed(); - - shaders.Dispose(); - + Renderer.DeviceDestroyed(); //int count = 0; //while (running && (count < 5000)) //wait for the content thread to exit gracefully @@ -314,114 +236,48 @@ namespace CodeWalker.Forms // Thread.Sleep(1); // count++; //} - - currentdevice = null; } public void BuffersResized(int w, int h) { - lock (rendersyncroot) - { - camera.OnWindowResize(w, h); - shaders.OnWindowResize(w, h); - } + Renderer.BuffersResized(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)) + if (!Monitor.TryEnter(Renderer.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(); - dxman.ClearRenderTarget(context); + Renderer.Update(elapsed, MouseLastPoint.X, MouseLastPoint.Y); - shaders.BeginFrame(context, currentRealTime, elapsed); - shaders.EnsureShaderTextures(gameFileCache, renderableCache); + Renderer.BeginRender(context); - RenderSky(context); + Renderer.RenderSkyAndClouds(); - //RenderClouds(context); - shaders.ClearDepth(context); - - //if (renderworld || rendermaps) - //{ - // RenderWorld(); - // if (rendermaps) - // { - // RenderYmaps(); - // } - //} - //else - //{ RenderSingleItem(); - //} + RenderGrid(context); - shaders.RenderQueued(context, camera, currentWindVec); - RenderSkeletons(context); + Renderer.RenderQueued(); - //RenderBounds(context); - //RenderSelection(context); + Renderer.RenderFinalPass(); - //RenderMoused(context); - //RenderSelectionGeometry(context); + Renderer.EndRender(); - shaders.RenderFinalPass(context); - - //RenderMarkers(context); - - //RenderWidgets(context); - - renderableCache.RenderThreadSync(); - - Monitor.Exit(rendersyncroot); - - //UpdateMarkerSelectionPanelInvoke(); + Monitor.Exit(Renderer.RenderSyncRoot); } @@ -466,10 +322,10 @@ namespace CodeWalker.Forms { //UpdateStatus("Loading timecycles..."); timecycle.Init(gameFileCache, UpdateStatus); - timecycle.SetTime(timeofday); + timecycle.SetTime(Renderer.timeofday); //UpdateStatus("Timecycles loaded."); } - if (renderskydome) + if (Renderer.renderskydome) { if (!weather.Inited) { @@ -493,9 +349,9 @@ namespace CodeWalker.Forms // gameFileCache.ContentThreadProc(); //} - renderableCache.ContentThreadProc(); + bool rcItemsPending = Renderer.ContentThreadProc(); - if (!(renderableCache.ItemsStillPending)) //gameFileCache.ItemsStillPending || + if (!(rcItemsPending)) //gameFileCache.ItemsStillPending || { Thread.Sleep(1); //sleep if there's nothing to do } @@ -549,444 +405,6 @@ namespace CodeWalker.Forms return arch; } - private DrawableBase TryGetDrawable(Archetype arche) - { - if (arche == null) return null; - if ((gameFileCache == null) || (!gameFileCache.IsInited)) return null; - - uint drawhash = arche.Hash; - DrawableBase drawable = null; - if ((arche.DrawableDict != 0))// && (arche.DrawableDict != arche.Hash)) - { - //try get drawable from ydd... - YddFile ydd = gameFileCache.GetYdd(arche.DrawableDict); - if (ydd != null) - { - 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? - } - } - if (drawable == null) - { - //try get drawable from ydr. - YdrFile ydr = gameFileCache.GetYdr(drawhash); - if (ydr != null) - { - if (ydr.Loaded) - { - drawable = ydr.Drawable; - } - } - else - { - YftFile yft = gameFileCache.GetYft(drawhash); - if (yft != null) - { - if (yft.Loaded) - { - if (yft.Fragment != null) - { - drawable = yft.Fragment.Drawable; - } - } - } - } - } - - return drawable; - } - - 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; - - - var gfc = gameFileCache; - if ((gfc != null) && (!gfc.IsInited)) - { - gfc = null; - } - - - //if (clipDict != 0) - //{ - // YcdFile ycd = gameFileCache.GetYcd(clipDict); - // if ((ycd != null) && (ycd.Loaded)) - // { - // ClipMapEntry cme; - // if (ycd.ClipMap.TryGetValue(arche.Hash, out cme)) - // { - // } - // else - // { } - // } - //} - - - bool alltexsloaded = true; - int missingtexcount = 0; - for (int mi = 0; mi < rndbl.HDModels.Length; mi++) - { - var model = rndbl.HDModels[mi]; - - //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.ToLowerInvariant()); - 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); - } - } - - } - - - } - - - - } - @@ -1042,8 +460,7 @@ namespace CodeWalker.Forms { if (gridVerts.Count > 0) { - shaders.SetDepthStencilMode(context, DepthStencilMode.Enabled); - shaders.Paths.RenderLines(context, gridVerts, camera, shaders.GlobalLights); + Renderer.RenderLines(gridVerts); } } } @@ -1067,7 +484,7 @@ namespace CodeWalker.Forms hash = Ydr?.RpfFileEntry?.ShortNameHash ?? 0; arch = TryGetArchetype(hash); - RenderDrawable(Ydr.Drawable, arch, null, -camera.Position, hash); + Renderer.RenderDrawable(Ydr.Drawable, arch, null, hash); } } else if (Ydd != null) @@ -1081,7 +498,7 @@ namespace CodeWalker.Forms { arch = TryGetArchetype(kvp.Key); - RenderDrawable(kvp.Value, arch, null, -camera.Position, Ydd.RpfFileEntry.ShortNameHash); + Renderer.RenderDrawable(kvp.Value, arch, null, Ydd.RpfFileEntry.ShortNameHash); } } } @@ -1096,7 +513,7 @@ namespace CodeWalker.Forms { arch = TryGetArchetype(kvp.Key); - RenderDrawable(kvp.Value, arch, null, -camera.Position, kvp.Key); + Renderer.RenderDrawable(kvp.Value, arch, null, kvp.Key); } } } @@ -1112,7 +529,7 @@ namespace CodeWalker.Forms hash = Yft?.RpfFileEntry?.ShortNameHash ?? 0; arch = TryGetArchetype(hash); - RenderFragment(arch, null, f, hash); + Renderer.RenderFragment(arch, null, f, hash); } } } @@ -1120,7 +537,7 @@ namespace CodeWalker.Forms { if (Ybn.Loaded) { - RenderCollisionMesh(Ybn.Bounds, null); + Renderer.RenderCollisionMesh(Ybn.Bounds, null); } } else if (Ypt != null) @@ -1133,7 +550,7 @@ namespace CodeWalker.Forms { if (Ynv.Loaded) { - RenderNavmesh(Ynv); + Renderer.RenderNavMesh(Ynv); } } @@ -1147,366 +564,6 @@ namespace CodeWalker.Forms - - - - - - private bool RenderFragment(Archetype arch, YmapEntityDef ent, FragType f, uint txdhash = 0) - { - var pos = ent?.Position ?? Vector3.Zero; - - RenderDrawable(f.Drawable, arch, ent, pos - camera.Position, txdhash); - - if (f.Unknown_F8h_Data != null) //cloth - { - RenderDrawable(f.Unknown_F8h_Data, arch, ent, pos - camera.Position, txdhash); - } - - //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, arch, ent, -camera.Position, hash); - } - } - } - } - - return true; - } - - private bool RenderDrawable(DrawableBase drawable, Archetype arche, YmapEntityDef entity, Vector3 camrel, uint txdHash = 0) - { - //enqueue a single drawable for rendering. - - if (drawable == null) - return false; - - Renderable rndbl = TryGetRenderable(arche, drawable, txdHash); - if (rndbl == null) - return false; - - return RenderRenderable(rndbl, arche, entity, camrel); - } - - private bool RenderRenderable(Renderable rndbl, Archetype arche, YmapEntityDef entity, Vector3 camrel) - { - //enqueue a single renderable for rendering. - - if (!rndbl.IsLoaded) return false; - - - //if (((SelectionMode == MapSelectionMode.Entity) || (SelectionMode == MapSelectionMode.EntityExtension) || (SelectionMode == MapSelectionMode.ArchetypeExtension))) - //{ - // UpdateMouseHit(rndbl, arche, entity, camrel); - //} - - bool isselected = true;// (rndbl.Key == SelectedItem.Drawable); - - 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) - { - position = entity.Position; - scale = entity.Scale; - orientation = entity.Orientation; - tintPaletteIndex = entity.CEntityDef.tintValue; - bbmin = entity.BBMin; - bbmax = entity.BBMax; - bscen = entity.BSCenter; - } - - - if (rendercollisionmeshes)// && collisionmeshlayerdrawable) - { - Drawable sdrawable = rndbl.Key as Drawable; - if ((sdrawable != null) && (sdrawable.Bound != null)) - { - RenderCollisionMesh(sdrawable.Bound, entity); - } - } - if (renderskeletons) - { - if (rndbl.HasSkeleton) - { - RenderSkeleton(rndbl); - } - } - - - - bool retval = true;// false; - if (rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload)) - { - 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; - - - RenderableModel[] models = isselected ? rndbl.AllModels : rndbl.HDModels; - - for (int mi = 0; mi < models.Length; mi++) - { - var model = models[mi]; - - if (isselected) - { - if (ModelDrawFlags.ContainsKey(model.DrawableModel)) - { continue; } //filter out models in selected item that aren't flagged for drawing. - } - - if (!RenderIsModelFinalRender(model))// && !renderproxies) - { continue; } //filter out reflection proxy models... - - for (int gi = 0; gi < model.Geometries.Length; gi++) - { - var geom = model.Geometries[gi]; - - if (isselected) - { - if (GeometryDrawFlags.ContainsKey(geom.DrawableGeom)) - { continue; } //filter out geometries in selected item that aren't flagged for drawing. - } - - rginst.Geom = geom; - - shaders.Enqueue(rginst); - } - } - } - else - { - retval = false; - } - return retval; - } - - - private void RenderCollisionMesh(Bounds bounds, YmapEntityDef entity) - { - //enqueue a single collision mesh for rendering. - - 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; - } - - switch (bounds.Type) - { - case 10: //BoundComposite - BoundComposite boundcomp = bounds as BoundComposite; - if (boundcomp != null) - { - 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); - } - } - 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; - } - } - - - private void RenderNavmesh(YnvFile ynv) - { - RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(ynv); - if ((rnd != null) && (rnd.IsLoaded)) - { - shaders.Enqueue(rnd); - } - } - - - - private bool RenderIsModelFinalRender(RenderableModel model) - { - - if ((model.Unk2Ch & 1) == 0) //smallest bit is proxy/"final render" bit? seems to work... - { - return false;// renderproxies; - } - return true; - - //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; - } - - - - - - - - private void RenderSkeleton(Renderable renderable) - { - renderskeletonlist.Add(renderable); - } - - private void RenderSkeletons(DeviceContext context) - { - - skeletonLineVerts.Clear(); - - 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) - { - DrawableBase drawable = renderable.Key; - Skeleton skeleton = drawable?.Skeleton; - if (skeleton == null) continue; - - var pinds = skeleton.ParentIndices; - var bones = skeleton.Bones; - if ((pinds == null) || (bones == null)) continue; - var xforms = skeleton.Transformations; - - 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 - { - } - - - //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); - - } - - - } - - - - - - if (skeletonLineVerts.Count > 0) - { - shaders.SetDepthStencilMode(context, DepthStencilMode.DisableAll); - shaders.Paths.RenderLines(context, skeletonLineVerts, camera, shaders.GlobalLights); - } - - - - } - - - - - - - - - - public void LoadModel(YdrFile ydr) { if (ydr == null) return; @@ -1625,220 +682,22 @@ namespace CodeWalker.Forms TimeOfDayLabel.Text = string.Format("{0:00}:{1:00}", ih, im); } - private void UpdateTimeOfDay(float elapsed) - { - if (timerunning) - { - 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); - } - - } - - 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; - - 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) - { - lightdircolour *= weather.CurrentValues.skyHdr; - lightdircolour.Alpha = 1.0f; - lightdirambcolour *= weather.CurrentValues.skyHdr; - lightdirambcolour.Alpha = 1.0f; - hdrint = weather.CurrentValues.skyHdr; - } - 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; - - lightdir = sundir; - - //if (lightdir.Z < -0.5f) lightdir.Z = -lightdir.Z; //make sure the lightsource is always above the horizon... - - if ((timeofday < 5.0f) || (timeofday > 21.0f)) - { - lightdir = moondir; - //usemoon = true; - } - - if (lightdir.Z < 0) - { - lightdir.Z = 0; //don't let the light source go below the horizon... - } - - //lightdir = Vector3.Normalize(weather.CurrentValues.sunDirection); - - if (weather != null && weather.Inited) - { - 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) - { - 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); - } - else - { - hdrint = weather.CurrentValues.skyHdr;//.lightDirCol.W; - } - } - - - } - - 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; - - - if (shaders != null) - { - shaders.SetGlobalLightParams(globalLights); - } - - } - - private void UpdateWindVector(float elapsed) - { - //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; - - 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; - - currentWindVec.Z = (float)Math.Sin(dirval) * dirval1 + (float)Math.Cos(dirval2) * dirval4; - currentWindVec.W = (float)Math.Cos(dirval) * dirval5 + (float)Math.Sin(dirval3) * dirval4; - - 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)); - - 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); - } private void UpdateControlInputs(float elapsed) { + if (elapsed > 0.1f) elapsed = 0.1f; + var s = Settings.Default; float moveSpeed = 10.0f; - bool xbenable = (xbcontroller != null) && (xbcontroller.IsConnected); - float lx = 0, ly = 0, rx = 0, ry = 0, lt = 0, rt = 0; //input axes - if (xbenable) - { - 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; + Input.Update(elapsed); + + if (Input.xbenable) + { //if (ControllerButtonJustPressed(GamepadButtonFlags.Start)) //{ // SetControlMode(ControlMode == WorldControlMode.Free ? WorldControlMode.Ped : WorldControlMode.Free); @@ -1847,125 +706,84 @@ namespace CodeWalker.Forms - Vector3 movevec = Vector3.Zero; + if (Input.ShiftPressed) + { + moveSpeed *= 5.0f; + } + if (Input.CtrlPressed) + { + moveSpeed *= 0.2f; + } - //if (MapViewEnabled == true) + Vector3 movevec = Input.KeyboardMoveVec(false); + + + //if (MapViewEnabled == true) + //{ + // 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 + { + //normal movement + movevec *= elapsed * moveSpeed * Math.Min(camera.TargetDistance, 50.0f); + } + + + Vector3 movewvec = camera.ViewInvQuaternion.Multiply(movevec); + camEntity.Position += movewvec; + + //MapViewDragX = 0; + //MapViewDragY = 0; + + + + + if (Input.xbenable) + { + camera.ControllerRotate(Input.xblx + Input.xbrx, Input.xbly + Input.xbry); + + float zoom = 0.0f; + float zoomspd = s.XInputZoomSpeed; + float zoomamt = zoomspd * elapsed; + if (Input.ControllerButtonPressed(GamepadButtonFlags.DPadUp)) zoom += zoomamt; + if (Input.ControllerButtonPressed(GamepadButtonFlags.DPadDown)) zoom -= zoomamt; + + camera.ControllerZoom(zoom); + + float acc = 0.0f; + float accspd = s.XInputMoveSpeed;//actually accel speed... + acc += Input.xbrt * accspd; + acc -= Input.xblt * accspd; + + Vector3 newdir = camera.ViewDirection; //maybe use the "vehicle" direction...? + Input.xbcontrolvelocity += (acc * elapsed); + + if (Input.ControllerButtonPressed(GamepadButtonFlags.A | GamepadButtonFlags.RightShoulder)) //handbrake... + { + Input.xbcontrolvelocity *= Math.Max(0.75f - elapsed, 0);//not ideal for low fps... + //xbcontrolvelocity = 0.0f; + if (Math.Abs(Input.xbcontrolvelocity) < 0.001f) Input.xbcontrolvelocity = 0.0f; + } + + camEntity.Velocity = newdir * Input.xbcontrolvelocity; + camEntity.Position += camEntity.Velocity * elapsed; + + + //fire! + //if (ControllerButtonJustPressed(GamepadButtonFlags.LeftShoulder)) //{ - // 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; + // SpawnTestEntity(true); //} - //else - { - //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); - } - - Vector3 movewvec = camera.ViewInvQuaternion.Multiply(movevec); - camEntity.Position += movewvec; - - //MapViewDragX = 0; - //MapViewDragY = 0; + } - - if (xbenable) - { - camera.ControllerRotate(lx + rx, ly + ry); - - float zoom = 0.0f; - float zoomspd = s.XInputZoomSpeed; - float zoomamt = zoomspd * elapsed; - if (ControllerButtonPressed(GamepadButtonFlags.DPadUp)) zoom += zoomamt; - if (ControllerButtonPressed(GamepadButtonFlags.DPadDown)) zoom -= zoomamt; - - camera.ControllerZoom(zoom); - - float acc = 0.0f; - float accspd = s.XInputMoveSpeed;//actually accel speed... - acc += rt * accspd; - acc -= lt * accspd; - - Vector3 newdir = camera.ViewDirection; //maybe use the "vehicle" direction...? - xbcontrolvelocity += (acc * elapsed); - - 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; - } - - camEntity.Velocity = newdir * xbcontrolvelocity; - camEntity.Position += camEntity.Velocity * elapsed; - - - //fire! - //if (ControllerButtonJustPressed(GamepadButtonFlags.LeftShoulder)) - //{ - // SpawnTestEntity(true); - //} - - } - - - - } - - private Vector4 ControllerMainAxes() - { - 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); - - 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; - - 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)); } @@ -1976,8 +794,8 @@ namespace CodeWalker.Forms DetailsPropertyGrid.SelectedObject = drawable; DrawableDrawFlags.Clear(); - ModelDrawFlags.Clear(); - GeometryDrawFlags.Clear(); + Renderer.SelectionModelDrawFlags.Clear(); + Renderer.SelectionGeometryDrawFlags.Clear(); ModelsTreeView.Nodes.Clear(); ModelsTreeView.ShowRootLines = false; TexturesTreeView.Nodes.Clear(); @@ -1997,8 +815,8 @@ namespace CodeWalker.Forms var drawable = frag.Drawable; DrawableDrawFlags.Clear(); - ModelDrawFlags.Clear(); - GeometryDrawFlags.Clear(); + Renderer.SelectionModelDrawFlags.Clear(); + Renderer.SelectionGeometryDrawFlags.Clear(); ModelsTreeView.Nodes.Clear(); ModelsTreeView.ShowRootLines = false; TexturesTreeView.Nodes.Clear(); @@ -2016,8 +834,8 @@ namespace CodeWalker.Forms //DetailsPropertyGrid.SelectedObject = dict; //this won't look good... DrawableDrawFlags.Clear(); - ModelDrawFlags.Clear(); - GeometryDrawFlags.Clear(); + Renderer.SelectionModelDrawFlags.Clear(); + Renderer.SelectionGeometryDrawFlags.Clear(); ModelsTreeView.Nodes.Clear(); ModelsTreeView.ShowRootLines = true; TexturesTreeView.Nodes.Clear(); @@ -2079,7 +897,7 @@ namespace CodeWalker.Forms if (!check) { - ModelDrawFlags[model] = false; + Renderer.SelectionModelDrawFlags[model] = false; } if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue; @@ -2132,7 +950,7 @@ namespace CodeWalker.Forms var model = node.Tag as DrawableModel; var geom = node.Tag as DrawableGeometry; bool rem = node.Checked; - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { if (drwbl != null) { @@ -2152,28 +970,28 @@ namespace CodeWalker.Forms { if (rem) { - if (ModelDrawFlags.ContainsKey(model)) + if (Renderer.SelectionModelDrawFlags.ContainsKey(model)) { - ModelDrawFlags.Remove(model); + Renderer.SelectionModelDrawFlags.Remove(model); } } else { - ModelDrawFlags[model] = false; + Renderer.SelectionModelDrawFlags[model] = false; } } if (geom != null) { if (rem) { - if (GeometryDrawFlags.ContainsKey(geom)) + if (Renderer.SelectionGeometryDrawFlags.ContainsKey(geom)) { - GeometryDrawFlags.Remove(geom); + Renderer.SelectionGeometryDrawFlags.Remove(geom); } } else { - GeometryDrawFlags[geom] = false; + Renderer.SelectionGeometryDrawFlags[geom] = false; } } updateArchetypeStatus = true; @@ -2239,19 +1057,21 @@ namespace CodeWalker.Forms } if (MouseRButtonDown) { - if (controllightdir) + if (Renderer.controllightdir) { - lightdirx += (dx * camera.Sensitivity); - lightdiry += (dy * camera.Sensitivity); + Renderer.lightdirx += (dx * camera.Sensitivity); + Renderer.lightdiry += (dy * camera.Sensitivity); } - else if (controltimeofday) + else if (Renderer.controltimeofday) { - timeofday += (dx - dy) / 30.0f; - while (timeofday >= 24.0f) timeofday -= 24.0f; - while (timeofday < 0.0f) timeofday += 24.0f; - timecycle.SetTime(timeofday); + 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 = timeofday * 60.0f; + float fv = tod * 60.0f; TimeOfDayTrackBar.Value = (int)fv; UpdateTimeOfDayLabel(); } @@ -2297,49 +1117,31 @@ namespace CodeWalker.Forms 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); + Input.KeyDown(e, enablemove); - //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; + var k = e.KeyCode; + var kb = Input.keyBindings; + bool ctrl = Input.CtrlPressed; + bool shift = Input.ShiftPressed; if (!ctrl) { - if (k == keyBindings.MoveSlowerZoomIn) + if (k == kb.MoveSlowerZoomIn) { camera.MouseZoom(1); } - if (k == keyBindings.MoveFasterZoomOut) + if (k == kb.MoveFasterZoomOut) { camera.MouseZoom(-1); } } - - if (!moving) //don't trigger further actions if moving. + if (!Input.kbmoving) //don't trigger further actions if moving. { - if (!ctrl) { //switch widget modes and spaces. @@ -2422,10 +1224,7 @@ namespace CodeWalker.Forms 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; + Input.KeyUp(e); if (ActiveControl is TextBox) { @@ -2438,17 +1237,6 @@ namespace CodeWalker.Forms 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; @@ -2458,30 +1246,16 @@ namespace CodeWalker.Forms 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; + Input.KeyboardStop(); } 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); + StatsLabel.Text = Renderer.GetStatusText(); - if (timerunning) + if (Renderer.timerunning) { - float fv = timeofday * 60.0f; + float fv = Renderer.timeofday * 60.0f; //TimeOfDayTrackBar.Value = (int)fv; UpdateTimeOfDayLabel(); } @@ -2549,29 +1323,29 @@ namespace CodeWalker.Forms private void HDRRenderingCheckBox_CheckedChanged(object sender, EventArgs e) { - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - shaders.hdr = HDRRenderingCheckBox.Checked; + Renderer.shaders.hdr = HDRRenderingCheckBox.Checked; } } private void ShadowsCheckBox_CheckedChanged(object sender, EventArgs e) { - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - shaders.shadows = ShadowsCheckBox.Checked; + Renderer.shaders.shadows = ShadowsCheckBox.Checked; } } private void SkydomeCheckBox_CheckedChanged(object sender, EventArgs e) { - renderskydome = SkydomeCheckBox.Checked; - //controllightdir = !renderskydome; + Renderer.renderskydome = SkydomeCheckBox.Checked; + //Renderer.controllightdir = !Renderer.renderskydome; } private void ControlLightDirCheckBox_CheckedChanged(object sender, EventArgs e) { - controllightdir = ControlLightDirCheckBox.Checked; + Renderer.controllightdir = ControlLightDirCheckBox.Checked; } private void TimeOfDayTrackBar_Scroll(object sender, EventArgs e) @@ -2579,26 +1353,27 @@ namespace CodeWalker.Forms int v = TimeOfDayTrackBar.Value; float fh = v / 60.0f; UpdateTimeOfDayLabel(); - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - timeofday = fh; - timecycle.SetTime(timeofday); + Renderer.timeofday = fh; + timecycle.SetTime(Renderer.timeofday); } } - private void ShowBoundsCheckBox_CheckedChanged(object sender, EventArgs e) + private void ShowCollisionMeshesCheckBox_CheckedChanged(object sender, EventArgs e) { - rendercollisionmeshes = ShowBoundsCheckBox.Checked; + Renderer.rendercollisionmeshes = ShowCollisionMeshesCheckBox.Checked; + Renderer.rendercollisionmeshlayerdrawable = ShowCollisionMeshesCheckBox.Checked; } private void WireframeCheckBox_CheckedChanged(object sender, EventArgs e) { - shaders.wireframe = WireframeCheckBox.Checked; + Renderer.shaders.wireframe = WireframeCheckBox.Checked; } private void AnisotropicFilteringCheckBox_CheckedChanged(object sender, EventArgs e) { - shaders.AnisotropicFiltering = AnisotropicFilteringCheckBox.Checked; + Renderer.shaders.AnisotropicFiltering = AnisotropicFilteringCheckBox.Checked; } private void RenderModeComboBox_SelectedIndexChanged(object sender, EventArgs e) @@ -2609,42 +1384,42 @@ namespace CodeWalker.Forms { default: case "Default": - shaders.RenderMode = WorldRenderMode.Default; + Renderer.shaders.RenderMode = WorldRenderMode.Default; break; case "Single texture": - shaders.RenderMode = WorldRenderMode.SingleTexture; + Renderer.shaders.RenderMode = WorldRenderMode.SingleTexture; TextureSamplerComboBox.Enabled = true; TextureCoordsComboBox.Enabled = true; break; case "Vertex normals": - shaders.RenderMode = WorldRenderMode.VertexNormals; + Renderer.shaders.RenderMode = WorldRenderMode.VertexNormals; break; case "Vertex tangents": - shaders.RenderMode = WorldRenderMode.VertexTangents; + Renderer.shaders.RenderMode = WorldRenderMode.VertexTangents; break; case "Vertex colour 1": - shaders.RenderMode = WorldRenderMode.VertexColour; - shaders.RenderVertexColourIndex = 1; + Renderer.shaders.RenderMode = WorldRenderMode.VertexColour; + Renderer.shaders.RenderVertexColourIndex = 1; break; case "Vertex colour 2": - shaders.RenderMode = WorldRenderMode.VertexColour; - shaders.RenderVertexColourIndex = 2; + Renderer.shaders.RenderMode = WorldRenderMode.VertexColour; + Renderer.shaders.RenderVertexColourIndex = 2; break; case "Vertex colour 3": - shaders.RenderMode = WorldRenderMode.VertexColour; - shaders.RenderVertexColourIndex = 3; + Renderer.shaders.RenderMode = WorldRenderMode.VertexColour; + Renderer.shaders.RenderVertexColourIndex = 3; break; case "Texture coord 1": - shaders.RenderMode = WorldRenderMode.TextureCoord; - shaders.RenderTextureCoordIndex = 1; + Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord; + Renderer.shaders.RenderTextureCoordIndex = 1; break; case "Texture coord 2": - shaders.RenderMode = WorldRenderMode.TextureCoord; - shaders.RenderTextureCoordIndex = 2; + Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord; + Renderer.shaders.RenderTextureCoordIndex = 2; break; case "Texture coord 3": - shaders.RenderMode = WorldRenderMode.TextureCoord; - shaders.RenderTextureCoordIndex = 3; + Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord; + Renderer.shaders.RenderTextureCoordIndex = 3; break; } } @@ -2653,7 +1428,7 @@ namespace CodeWalker.Forms { if (TextureSamplerComboBox.SelectedItem is MetaName) { - shaders.RenderTextureSampler = (MetaName)TextureSamplerComboBox.SelectedItem; + Renderer.shaders.RenderTextureSampler = (MetaName)TextureSamplerComboBox.SelectedItem; } } @@ -2663,13 +1438,13 @@ namespace CodeWalker.Forms { default: case "Texture coord 1": - shaders.RenderTextureSamplerCoord = 1; + Renderer.shaders.RenderTextureSamplerCoord = 1; break; case "Texture coord 2": - shaders.RenderTextureSamplerCoord = 2; + Renderer.shaders.RenderTextureSamplerCoord = 2; break; case "Texture coord 3": - shaders.RenderTextureSamplerCoord = 3; + Renderer.shaders.RenderTextureSamplerCoord = 3; break; } } @@ -2703,7 +1478,7 @@ namespace CodeWalker.Forms private void SkeletonsCheckBox_CheckedChanged(object sender, EventArgs e) { - renderskeletons = SkeletonsCheckBox.Checked; + Renderer.renderskeletons = SkeletonsCheckBox.Checked; } private void ErrorConsoleCheckBox_CheckedChanged(object sender, EventArgs e) diff --git a/GameFiles/GameFileCache.cs b/GameFiles/GameFileCache.cs index 87c5899..b003cfa 100644 --- a/GameFiles/GameFileCache.cs +++ b/GameFiles/GameFileCache.cs @@ -18,7 +18,6 @@ namespace CodeWalker.GameFiles private Action ErrorLog; public long CurrentMemoryUsage = 0; public int MaxItemsPerLoop = 1; //to keep things flowing... - public bool ItemsStillPending = false; //whether or not we need another content thread loop private ConcurrentStack requestQueue = new ConcurrentStack(); @@ -1842,7 +1841,7 @@ namespace CodeWalker.GameFiles - public void ContentThreadProc() + public bool ContentThreadProc() { Monitor.Enter(updateSyncRoot); @@ -1912,10 +1911,14 @@ namespace CodeWalker.GameFiles //loadedsomething = true; } - ItemsStillPending = (itemcount >= MaxItemsPerLoop); + //whether or not we need another content thread loop + bool itemsStillPending = (itemcount >= MaxItemsPerLoop); Monitor.Exit(updateSyncRoot); + + + return itemsStillPending; } @@ -1991,6 +1994,75 @@ namespace CodeWalker.GameFiles + public DrawableBase TryGetDrawable(Archetype arche) + { + if (arche == null) return null; + uint drawhash = arche.Hash; + DrawableBase drawable = null; + if ((arche.DrawableDict != 0))// && (arche.DrawableDict != arche.Hash)) + { + //try get drawable from ydd... + YddFile ydd = GetYdd(arche.DrawableDict); + if (ydd != null) + { + 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? + } + } + if (drawable == null) + { + //try get drawable from ydr. + YdrFile ydr = GetYdr(drawhash); + if (ydr != null) + { + if (ydr.Loaded) + { + drawable = ydr.Drawable; + } + } + else + { + YftFile yft = GetYft(drawhash); + if (yft != null) + { + if (yft.Loaded) + { + if (yft.Fragment != null) + { + drawable = yft.Fragment.Drawable; + } + } + } + } + } + + return drawable; + } + + + + + + + + + private string[] GetExcludePaths() diff --git a/Rendering/RenderableCache.cs b/Rendering/RenderableCache.cs index d428304..6add1c4 100644 --- a/Rendering/RenderableCache.cs +++ b/Rendering/RenderableCache.cs @@ -21,7 +21,6 @@ namespace CodeWalker.Rendering public double CacheTime = Settings.Default.GPUCacheTime;// 10.0; //seconds to keep something that's not used public double UnloadTime = Settings.Default.GPUCacheFlushTime;// 0.1; //seconds between running unload cycles public int MaxItemsPerLoop = 1; //to keep things flowing - public bool ItemsStillPending = false; //whether or not we need another content thread loop public long TotalGraphicsMemoryUse { @@ -92,9 +91,9 @@ namespace CodeWalker.Rendering waterquads.Clear(); } - public void ContentThreadProc() + public bool ContentThreadProc() { - if (currentDevice == null) return; //can't do anything with no device + if (currentDevice == null) return false; //can't do anything with no device Monitor.Enter(updateSyncRoot); @@ -109,13 +108,14 @@ namespace CodeWalker.Rendering int waterquadcount = waterquads.LoadProc(currentDevice, MaxItemsPerLoop); - ItemsStillPending = (renderablecount >= MaxItemsPerLoop) || - (texturecount >= MaxItemsPerLoop) || - (boundcompcount >= MaxItemsPerLoop) || - (instbatchcount >= MaxItemsPerLoop) || - (distlodlightcount >= MaxItemsPerLoop) || - (pathbatchcount >= MaxItemsPerLoop) || - (waterquadcount >= MaxItemsPerLoop); + bool itemsStillPending = + (renderablecount >= MaxItemsPerLoop) || + (texturecount >= MaxItemsPerLoop) || + (boundcompcount >= MaxItemsPerLoop) || + (instbatchcount >= MaxItemsPerLoop) || + (distlodlightcount >= MaxItemsPerLoop) || + (pathbatchcount >= MaxItemsPerLoop) || + (waterquadcount >= MaxItemsPerLoop); //todo: change this to unload only when necessary (ie when something is loaded) @@ -141,6 +141,8 @@ namespace CodeWalker.Rendering LastUpdate = DateTime.UtcNow; Monitor.Exit(updateSyncRoot); + + return itemsStillPending; } public void RenderThreadSync() diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs new file mode 100644 index 0000000..beb6312 --- /dev/null +++ b/Rendering/Renderer.cs @@ -0,0 +1,2658 @@ +using CodeWalker.GameFiles; +using CodeWalker.Properties; +using CodeWalker.World; +using SharpDX; +using SharpDX.Direct3D11; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace CodeWalker.Rendering +{ + public class Renderer + { + private DXForm Form; + private GameFileCache gameFileCache; + private RenderableCache renderableCache; + + private DXManager dxman = new DXManager(); + public DXManager DXMan { get { return dxman; } } + private Device currentdevice; + public Device Device { get { return currentdevice; } } + private object rendersyncroot = new object(); + public object RenderSyncRoot { get { return rendersyncroot; } } + + public ShaderManager shaders; + + public Camera camera = new Camera(); + + private double currentRealTime = 0; + private float currentElapsedTime = 0; + private int framecount = 0; + private float fcelapsed = 0.0f; + private int fps = 0; + + private DeviceContext context; + + + public float timeofday = 12.0f; + public bool controltimeofday = true; + public bool timerunning = false; + public float timespeed = 0.5f;//min/sec + public string weathertype = ""; + public string individualcloudfrag = "contrails"; + + private Vector4 currentWindVec = Vector4.Zero; + private float currentWindTime = 0.0f; + + + public bool usedynamiclod = Settings.Default.DynamicLOD; //for ymap view + public float lodthreshold = 50.0f / (0.1f + (float)Settings.Default.DetailDist); //to match formula for the DetailTrackBar value + public bool waitforchildrentoload = true; + + + public bool controllightdir = false; //if not, use timecycle + public float lightdirx = 2.25f;//radians // approx. light dir on map satellite view + public float lightdiry = 0.65f;//radians - used for manual light placement + public bool renderskydome = Settings.Default.Skydome; + public bool renderclouds = true; + public bool rendermoon = true; + + + public Timecycle timecycle = new Timecycle(); + public Weather weather = new Weather(); + public Clouds clouds = new Clouds(); + + + + private ShaderGlobalLights globalLights = new ShaderGlobalLights(); + public bool rendernaturalambientlight = true; + public bool renderartificialambientlight = true; + + + public bool MapViewEnabled = false; + public float MapViewDetail = 1.0f; + + + private UnitQuad markerquad = null; + public bool markerdepthclip = Settings.Default.MarkerDepthClip; + + + + private List renderworldentities = new List(); //used when rendering world view. + private List renderworldrenderables = new List(); + + + public bool ShowScriptedYmaps = true; + public List VisibleYmaps = new List(); + + public Unk_1264241711 renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD; + public float renderworldLodDistMult = 1.0f; + public float renderworldDetailDistMult = 1.0f; + + public bool rendertimedents = Settings.Default.ShowTimedEntities; + public bool rendertimedentsalways = false; + public bool renderinteriors = true; + public bool renderproxies = false; + public bool renderchildents = false;//when rendering single ymap, render root only or not... + + public bool rendergrass = true; + public bool renderdistlodlights = true; + + public bool rendercollisionmeshes = Settings.Default.ShowCollisionMeshes; + public bool rendercollisionmeshlayerdrawable = true; + + public bool renderskeletons = false; + private List renderskeletonlist = new List(); + private List skeletonLineVerts = new List(); + + + public BoundsShaderMode boundsmode = BoundsShaderMode.None; + public bool renderboundsclip = Settings.Default.BoundsDepthClip; + public float renderboundsmaxrad = 20000.0f; + public float renderboundsmaxdist = 10000.0f; + public List BoundingBoxes = new List(); + public List BoundingSpheres = new List(); + public List HilightSpheres = new List(); + public List HilightBoxes = new List(); + public List SelectionBoxes = new List(); + public List WhiteBoxes = new List(); + public List SelectionSpheres = new List(); + public List WhiteSpheres = new List(); + public List SelectionLineVerts = new List(); + public List SelectionTriVerts = new List(); + + + private YmapEntityDef SelectedCarGenEntity = new YmapEntityDef(); //placeholder entity object for drawing cars + + public DrawableBase SelectedDrawable = null; + public Dictionary SelectionModelDrawFlags = new Dictionary(); + public Dictionary SelectionGeometryDrawFlags = new Dictionary(); + public bool SelectionFlagsTestAll = false; //to test all renderables for draw flags; for model form + + + + + public List RenderedDrawables = new List(); //queued here for later hit tests... + public List RenderedBoundComps = new List(); + public bool RenderedDrawablesListEnable = false; //whether or not to add rendered drawables to the list + public bool RenderedBoundCompsListEnable = false; //whether or not to add rendered bound comps to the list + + + + + + + + + public Renderer(DXForm form, GameFileCache cache) + { + Form = form; + gameFileCache = cache; + if (gameFileCache == null) + { + gameFileCache = new GameFileCache(); + } + renderableCache = new RenderableCache(); + } + + + public bool Init() + { + return dxman.Init(Form, false); + } + + public void Start() + { + dxman.Start(); + } + + public void DeviceCreated(Device device, int width, int height) + { + currentdevice = device; + + shaders = new ShaderManager(device, dxman); + shaders.OnWindowResize(width, height); //init the buffers + + renderableCache.OnDeviceCreated(device); + + camera.OnWindowResize(width, height); //init the projection stuff + + + markerquad = new UnitQuad(device); + + } + + public void DeviceDestroyed() + { + renderableCache.OnDeviceDestroyed(); + + markerquad.Dispose(); + + shaders.Dispose(); + + currentdevice = null; + } + + public void BuffersResized(int width, int height) + { + lock (rendersyncroot) + { + camera.OnWindowResize(width, height); + shaders.OnWindowResize(width, height); + } + } + + public void ReloadShaders() + { + if (shaders != null) + { + shaders.Dispose(); + } + shaders = new ShaderManager(currentdevice, dxman); + } + + + public void Update(float elapsed, int mouseX, int mouseY) + { + framecount++; + fcelapsed += elapsed; + if (fcelapsed >= 0.5f) + { + fps = framecount * 2; + framecount = 0; + fcelapsed -= 0.5f; + } + if (elapsed > 0.1f) elapsed = 0.1f; + currentRealTime += elapsed; + currentElapsedTime = elapsed; + + + + UpdateTimeOfDay(elapsed); + + + weather.Update(elapsed); + + clouds.Update(elapsed); + + + UpdateWindVector(elapsed); + + UpdateGlobalLights(); + + + camera.SetMousePosition(mouseX, mouseY); + + camera.Update(elapsed); + } + + + public void BeginRender(DeviceContext ctx) + { + context = ctx; + + dxman.ClearRenderTarget(context); + + shaders.BeginFrame(context, currentRealTime, currentElapsedTime); + + shaders.EnsureShaderTextures(gameFileCache, renderableCache); + + + + + SelectionLineVerts.Clear(); + SelectionTriVerts.Clear(); + WhiteBoxes.Clear(); + WhiteSpheres.Clear(); + SelectionBoxes.Clear(); + SelectionSpheres.Clear(); + HilightBoxes.Clear(); + HilightSpheres.Clear(); + BoundingBoxes.Clear(); + BoundingSpheres.Clear(); + + RenderedDrawables.Clear(); + RenderedBoundComps.Clear(); + + renderskeletonlist.Clear(); + } + + public void RenderSkyAndClouds() + { + RenderSky(); + + RenderClouds(); + + shaders.ClearDepth(context); + } + + public void RenderQueued() + { + shaders.RenderQueued(context, camera, currentWindVec); + + RenderSkeletons(); + } + + public void RenderFinalPass() + { + shaders.RenderFinalPass(context); + } + + public void EndRender() + { + renderableCache.RenderThreadSync(); + } + + public bool ContentThreadProc() + { + bool rcItemsPending = renderableCache.ContentThreadProc(); + + return rcItemsPending; + } + + + + public void SetTimeOfDay(float hour) + { + timeofday = hour; + timecycle.SetTime(timeofday); + } + + public void SetWeatherType(string name) + { + if (!Monitor.TryEnter(rendersyncroot, 50)) + { return; } //couldn't get a lock... + weathertype = name; + weather.SetNextWeather(weathertype); + Monitor.Exit(rendersyncroot); + } + + public void SetCameraMode(string modestr) + { + lock (rendersyncroot) + { + switch (modestr) + { + case "Perspective": + camera.IsOrthographic = false; + MapViewEnabled = false; + camera.UpdateProj = true; + break; + case "Orthographic": + camera.IsOrthographic = true; + MapViewEnabled = false; + break; + case "2D Map": + camera.IsOrthographic = true; + MapViewEnabled = true; + break; + } + camera.IsMapView = MapViewEnabled; + } + } + + + public string GetStatusText() + { + 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); + return string.Format("Drawn: {0} geom, Loaded: {1} dr, {2} tx, Vram: {3}, Fps: {4}", rgc, crc, ctc, vram, fps); + } + + + + public void Invalidate(BasePathData path) + { + //used to update path graphics. + renderableCache.Invalidate(path); + } + + + public void UpdateSelectionDrawFlags(DrawableModel model, DrawableGeometry geom, bool rem) + { + lock (rendersyncroot) + { + if (model != null) + { + if (rem) + { + if (SelectionModelDrawFlags.ContainsKey(model)) + { + SelectionModelDrawFlags.Remove(model); + } + } + else + { + SelectionModelDrawFlags[model] = false; + } + } + if (geom != null) + { + if (rem) + { + if (SelectionGeometryDrawFlags.ContainsKey(geom)) + { + SelectionGeometryDrawFlags.Remove(geom); + } + } + else + { + SelectionGeometryDrawFlags[geom] = false; + } + } + } + } + + + + private void UpdateTimeOfDay(float elapsed) + { + if (timerunning) + { + 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); + } + } + + 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; + + if (controllightdir) + { + 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 != null) && (weather.Inited)) + { + lightdircolour *= weather.CurrentValues.skyHdr; + lightdircolour.Alpha = 1.0f; + lightdirambcolour *= weather.CurrentValues.skyHdr; + lightdirambcolour.Alpha = 1.0f; + hdrint = weather.CurrentValues.skyHdr; + } + sundir = lightdir; + moondir = -lightdir; + } + 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; + + lightdir = sundir; + + //if (lightdir.Z < -0.5f) lightdir.Z = -lightdir.Z; //make sure the lightsource is always above the horizon... + + if ((timeofday < 5.0f) || (timeofday > 21.0f)) + { + lightdir = moondir; + //usemoon = true; + } + + if (lightdir.Z < 0) + { + lightdir.Z = 0; //don't let the light source go below the horizon... + } + + //lightdir = Vector3.Normalize(weather.CurrentValues.sunDirection); + + if (weather != null && weather.Inited) + { + 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) + { + 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); + } + else + { + hdrint = weather.CurrentValues.skyHdr;//.lightDirCol.W; + } + } + + + } + + globalLights.Weather = weather; + globalLights.HdrEnabled = hdr; + globalLights.SpecularEnabled = !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; + + + if (shaders != null) + { + shaders.SetGlobalLightParams(globalLights); + } + + } + + private void UpdateWindVector(float elapsed) + { + //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; + + 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; + + currentWindVec.Z = (float)Math.Sin(dirval) * dirval1 + (float)Math.Cos(dirval2) * dirval4; + currentWindVec.W = (float)Math.Cos(dirval) * dirval5 + (float)Math.Sin(dirval3) * dirval4; + + 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)); + + 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); + } + + + + + + + + public void RenderMarkers(List batch) + { + + shaders.SetRasterizerMode(context, RasterizerMode.SolidDblSided); //hmm they are backwards + shaders.SetDepthStencilMode(context, markerdepthclip ? DepthStencilMode.Enabled : DepthStencilMode.DisableAll); + shaders.SetDefaultBlendState(context); + + var shader = shaders.Marker; + shader.SetShader(context); + shader.SetInputLayout(context, VertexType.Default); + shader.SetSceneVars(context, camera, null, globalLights); + + MapIcon icon = null; + foreach (var marker in batch) + { + icon = marker.Icon; + Vector2 texs = new Vector2(icon.TexWidth, icon.TexHeight); + Vector2 size = texs * marker.Distance; + Vector2 offset = (new Vector2(texs.X, -texs.Y) - new Vector2(icon.Center.X, -icon.Center.Y) * 2.0f) * marker.Distance; + shader.SetMarkerVars(context, marker.CamRelPos, size, offset); + shader.SetTexture(context, icon.TexView); + markerquad.Draw(context); + } + + shader.UnbindResources(context); + + } + + + + public void RenderTransformWidget(TransformWidget widget) + { + var dsmode = DepthStencilMode.Enabled; + if (widget.Mode == WidgetMode.Rotation) + { + dsmode = DepthStencilMode.DisableAll; + } + + shaders.SetRasterizerMode(context, RasterizerMode.SolidDblSided); + shaders.SetDepthStencilMode(context, dsmode); + shaders.SetDefaultBlendState(context); + shaders.ClearDepth(context, false); + + var shader = shaders.Widgets; + + widget.Render(context, camera, shader); + } + + + + + public void RenderSelectionEntityPivot(YmapEntityDef ent) + { + uint cred = (uint)new Color4(1.0f, 0.0f, 0.0f, 1.0f).ToRgba(); + uint cgrn = (uint)new Color4(0.0f, 1.0f, 0.0f, 1.0f).ToRgba(); + uint cblu = (uint)new Color4(0.0f, 0.0f, 1.0f, 1.0f).ToRgba(); + + var pos = ent.WidgetPosition; + var ori = ent.WidgetOrientation; + + float pxsize = 120.0f; + float sssize = pxsize / camera.Height; + float dist = (pos - camera.Position).Length(); + float size = sssize * dist; + if (camera.IsMapView || camera.IsOrthographic) + { + size = sssize * camera.OrthographicSize; + } + float rad = size * 0.066f; + + RenderSelectionArrowOutline(pos, Vector3.UnitX, Vector3.UnitY, ori, size, rad, cred); + RenderSelectionArrowOutline(pos, Vector3.UnitY, Vector3.UnitX, ori, size, rad, cgrn); + RenderSelectionArrowOutline(pos, Vector3.UnitZ, Vector3.UnitY, ori, size, rad, cblu); + + } + + public void RenderSelectionArrowOutline(Vector3 pos, Vector3 dir, Vector3 up, Quaternion ori, float len, float rad, uint colour) + { + Vector3 ax = Vector3.Cross(dir, up); + Vector3 sx = ax * rad; + Vector3 sy = up * rad; + Vector3 sz = dir * len; + VertexTypePC[] c = new VertexTypePC[8]; + Vector3 d0 = -sx - sy; + Vector3 d1 = -sx + sy; + Vector3 d2 = +sx - sy; + Vector3 d3 = +sx + sy; + c[0].Position = d0; + c[1].Position = d1; + c[2].Position = d2; + c[3].Position = d3; + c[4].Position = d0 + sz; + c[5].Position = d1 + sz; + c[6].Position = d2 + sz; + c[7].Position = d3 + sz; + for (int i = 0; i < 8; i++) + { + c[i].Colour = colour; + c[i].Position = pos + ori.Multiply(c[i].Position); + } + + SelectionLineVerts.Add(c[0]); + SelectionLineVerts.Add(c[1]); + SelectionLineVerts.Add(c[1]); + SelectionLineVerts.Add(c[3]); + SelectionLineVerts.Add(c[3]); + SelectionLineVerts.Add(c[2]); + SelectionLineVerts.Add(c[2]); + SelectionLineVerts.Add(c[0]); + SelectionLineVerts.Add(c[4]); + SelectionLineVerts.Add(c[5]); + SelectionLineVerts.Add(c[5]); + SelectionLineVerts.Add(c[7]); + SelectionLineVerts.Add(c[7]); + SelectionLineVerts.Add(c[6]); + SelectionLineVerts.Add(c[6]); + SelectionLineVerts.Add(c[4]); + SelectionLineVerts.Add(c[0]); + SelectionLineVerts.Add(c[4]); + SelectionLineVerts.Add(c[1]); + SelectionLineVerts.Add(c[5]); + SelectionLineVerts.Add(c[2]); + SelectionLineVerts.Add(c[6]); + SelectionLineVerts.Add(c[3]); + SelectionLineVerts.Add(c[7]); + + c[0].Position = pos + ori.Multiply(dir * (len + rad * 5.0f)); + c[4].Position += ori.Multiply(d0); + c[5].Position += ori.Multiply(d1); + c[6].Position += ori.Multiply(d2); + c[7].Position += ori.Multiply(d3); + SelectionLineVerts.Add(c[4]); + SelectionLineVerts.Add(c[5]); + SelectionLineVerts.Add(c[5]); + SelectionLineVerts.Add(c[7]); + SelectionLineVerts.Add(c[7]); + SelectionLineVerts.Add(c[6]); + SelectionLineVerts.Add(c[6]); + SelectionLineVerts.Add(c[4]); + SelectionLineVerts.Add(c[0]); + SelectionLineVerts.Add(c[4]); + SelectionLineVerts.Add(c[0]); + SelectionLineVerts.Add(c[5]); + SelectionLineVerts.Add(c[0]); + SelectionLineVerts.Add(c[6]); + SelectionLineVerts.Add(c[0]); + SelectionLineVerts.Add(c[7]); + + + } + + public void RenderSelectionNavPoly(YnvPoly poly) + { + ////draw poly triangles + var pcolour = new Color4(0.6f, 0.95f, 0.6f, 1.0f); + var colourval = (uint)pcolour.ToRgba(); + var ynv = poly.Ynv; + var ic = poly._RawData.IndexCount; + var startid = poly._RawData.IndexID; + var endid = startid + ic; + var lastid = endid - 1; + var vc = ynv.Vertices.Count; + var startind = ynv.Indices[startid]; + VertexTypePC v0 = new VertexTypePC(); + VertexTypePC v1 = new VertexTypePC(); + VertexTypePC v2 = new VertexTypePC(); + v0.Position = ynv.Vertices[startind]; + v0.Colour = colourval; + v1.Colour = colourval; + v2.Colour = colourval; + int tricount = ic - 2; + for (int t = 0; t < tricount; t++) + { + int tid = startid + t; + int ind1 = ynv.Indices[tid + 1]; + int ind2 = ynv.Indices[tid + 2]; + if ((ind1 >= vc) || (ind2 >= vc)) + { continue; } + v1.Position = ynv.Vertices[ind1]; + v2.Position = ynv.Vertices[ind2]; + SelectionTriVerts.Add(v0); + SelectionTriVerts.Add(v1); + SelectionTriVerts.Add(v2); + SelectionTriVerts.Add(v0); + SelectionTriVerts.Add(v2); + SelectionTriVerts.Add(v1); + } + } + + public void RenderSelectionGeometry(MapSelectionMode mode) + { + + bool clip = true; + switch (mode) + { + case MapSelectionMode.NavMesh: + case MapSelectionMode.WaterQuad: + case MapSelectionMode.MloInstance: + clip = false; + break; + } + + + shaders.SetDepthStencilMode(context, clip ? DepthStencilMode.Enabled : DepthStencilMode.DisableAll); + + var pshader = shaders.Paths; + if (SelectionTriVerts.Count > 0) + { + pshader.RenderTriangles(context, SelectionTriVerts, camera, shaders.GlobalLights); + } + if (SelectionLineVerts.Count > 0) + { + pshader.RenderLines(context, SelectionLineVerts, camera, shaders.GlobalLights); + } + + + + + Vector3 coloursel = new Vector3(0, 1, 0) * globalLights.HdrIntensity * 5.0f; + Vector3 colourwht = new Vector3(1, 1, 1) * globalLights.HdrIntensity * 10.0f; + var shader = shaders.Bounds; + + if ((WhiteBoxes.Count > 0) || (SelectionBoxes.Count > 0)) + { + shader.SetMode(BoundsShaderMode.Box); + shader.SetShader(context); + shader.SetInputLayout(context, VertexType.Default); + shader.SetSceneVars(context, camera, null, globalLights); + shader.SetColourVars(context, new Vector4(colourwht, 1)); + for (int i = 0; i < WhiteBoxes.Count; i++) + { + MapBox mb = WhiteBoxes[i]; + shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale); + shader.DrawBox(context); + } + shader.SetColourVars(context, new Vector4(coloursel, 1)); + for (int i = 0; i < SelectionBoxes.Count; i++) + { + MapBox mb = SelectionBoxes[i]; + shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale); + shader.DrawBox(context); + } + shader.UnbindResources(context); + } + + if ((WhiteSpheres.Count > 0) || (SelectionSpheres.Count > 0)) + { + shader.SetMode(BoundsShaderMode.Sphere); + shader.SetShader(context); + shader.SetInputLayout(context, VertexType.Default); + shader.SetSceneVars(context, camera, null, globalLights); + shader.SetColourVars(context, new Vector4(colourwht, 1)); + for (int i = 0; i < WhiteSpheres.Count; i++) + { + MapSphere ms = WhiteSpheres[i]; + shader.SetSphereVars(context, ms.CamRelPos, ms.Radius); + shader.DrawSphere(context); + } + shader.SetColourVars(context, new Vector4(coloursel, 1)); + for (int i = 0; i < SelectionSpheres.Count; i++) + { + MapSphere ms = SelectionSpheres[i]; + shader.SetSphereVars(context, ms.CamRelPos, ms.Radius); + shader.DrawSphere(context); + } + shader.UnbindResources(context); + } + + + } + + public void RenderMouseHit(BoundsShaderMode mode, bool clip, ref Vector3 camrel, ref Vector3 bbmin, ref Vector3 bbmax, ref Vector3 scale, ref Quaternion ori, float bsphrad) + { + Vector3 colour = new Vector3(1, 1, 1); + colour *= globalLights.HdrIntensity * 5.0f; + + shaders.SetDepthStencilMode(context, clip ? DepthStencilMode.Enabled : DepthStencilMode.DisableAll); + + //render moused object box. + var shader = shaders.Bounds; + shader.SetMode(mode); + shader.SetShader(context); + shader.SetInputLayout(context, VertexType.Default); + shader.SetSceneVars(context, camera, null, globalLights); + shader.SetColourVars(context, new Vector4(colour, 1)); //white box + + if (mode == BoundsShaderMode.Box) + { + shader.SetBoxVars(context, camrel, bbmin, bbmax, ori, scale); + shader.DrawBox(context); + } + else if (mode == BoundsShaderMode.Sphere) + { + shader.SetSphereVars(context, camrel, bsphrad); + shader.DrawSphere(context); + } + + shader.UnbindResources(context); + } + + + public void RenderBounds(MapSelectionMode mode) + { + //immediately render the entity bounding boxes/spheres - depending on boundsmode + + bool clip = renderboundsclip; + + switch (mode) + { + case MapSelectionMode.WaterQuad: + case MapSelectionMode.MloInstance: + clip = false; + break; + } + + + Vector3 colour = new Vector3(0, 0, 1) * globalLights.HdrIntensity; + Vector3 colourhi = new Vector3(0, 1, 1) * globalLights.HdrIntensity; + + shaders.SetDepthStencilMode(context, clip ? DepthStencilMode.Enabled : DepthStencilMode.DisableAll); + var shader = shaders.Bounds; + + if ((BoundingBoxes.Count > 0) || (HilightBoxes.Count > 0)) + { + shader.SetMode(BoundsShaderMode.Box); + shader.SetShader(context); + shader.SetInputLayout(context, VertexType.Default); + shader.SetSceneVars(context, camera, null, globalLights); + shader.SetColourVars(context, new Vector4(colour, 1)); + + for (int i = 0; i < BoundingBoxes.Count; i++) + { + MapBox mb = BoundingBoxes[i]; + shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale); + shader.DrawBox(context); + } + shader.SetColourVars(context, new Vector4(colourhi, 1)); + for (int i = 0; i < HilightBoxes.Count; i++) + { + MapBox mb = HilightBoxes[i]; + shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale); + shader.DrawBox(context); + } + } + + if ((BoundingSpheres.Count > 0) || (HilightSpheres.Count > 0)) + { + shader.SetMode(BoundsShaderMode.Sphere); + shader.SetShader(context); + shader.SetInputLayout(context, VertexType.Default); + shader.SetSceneVars(context, camera, null, globalLights); + shader.SetColourVars(context, new Vector4(colour, 1)); + + for (int i = 0; i < BoundingSpheres.Count; i++) + { + MapSphere ms = BoundingSpheres[i]; + shader.SetSphereVars(context, ms.CamRelPos, ms.Radius); + shader.DrawSphere(context); + } + shader.SetColourVars(context, new Vector4(colourhi, 1)); + for (int i = 0; i < HilightSpheres.Count; i++) + { + MapSphere ms = HilightSpheres[i]; + shader.SetSphereVars(context, ms.CamRelPos, ms.Radius); + shader.DrawSphere(context); + } + } + + + + shader.UnbindResources(context); + } + + + + + + + + + private void RenderSkeleton(Renderable renderable, YmapEntityDef entity) + { + RenderSkeletonItem item = new RenderSkeletonItem(); + item.Renderable = renderable; + item.Entity = entity; + renderskeletonlist.Add(item); + } + + private void RenderSkeletons() + { + + skeletonLineVerts.Clear(); + + 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 item in renderskeletonlist) + { + YmapEntityDef entity = item.Entity; + DrawableBase drawable = item.Renderable.Key; + Skeleton skeleton = drawable?.Skeleton; + if (skeleton == null) continue; + + var pinds = skeleton.ParentIndices; + var bones = skeleton.Bones; + if ((pinds == null) || (bones == null)) continue; + var xforms = skeleton.Transformations; + + 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 + { + } + + + //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; + } + + + if (entity != null) + { + lbeg = entity.Position + entity.Orientation.Multiply(lbeg * entity.Scale); + lend = entity.Position + entity.Orientation.Multiply(lend * entity.Scale); + } + + v1.Position = lbeg; + v2.Position = lend; + skeletonLineVerts.Add(v1); + skeletonLineVerts.Add(v2); + + } + + + } + + + + + + if (skeletonLineVerts.Count > 0) + { + RenderLines(skeletonLineVerts, DepthStencilMode.DisableAll); + } + + } + + + + public void RenderLines(List linelist, DepthStencilMode dsmode = DepthStencilMode.Enabled) + { + shaders.SetDepthStencilMode(context, dsmode); + shaders.Paths.RenderLines(context, linelist, camera, shaders.GlobalLights); + } + + + + + + + private void RenderSky() + { + if (MapViewEnabled) return; + 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 + + if (rendermoon) + { + 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 ((rendermoon) && (moontex != null) && (moontex.IsLoaded)) + { + shader.RenderMoon(context, camera, weather, globalLights, moontex); + } + + + + shader.UnbindResources(context); + } + + } + + private void RenderClouds() + { + if (MapViewEnabled) return; + if (!renderclouds) return; + 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.ToLowerInvariant()); + Archetype arch = gameFileCache.GetArchetype(dhash); + if (arch == null) + { continue; } + + if (Math.Max(camera.Position.Z, 0.0f) < layer.HeightTigger) continue; + + var drw = gameFileCache.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); + } + } + + } + + + } + + + + } + + + + public void RenderWaterQuads(List waterquads) + { + foreach (var quad in waterquads) + { + RenderableWaterQuad rquad = renderableCache.GetRenderableWaterQuad(quad); + if ((rquad != null) && (rquad.IsLoaded)) + { + rquad.CamRel = -camera.Position; + shaders.Enqueue(rquad); + } + } + } + + public void RenderPaths(List ynds) + { + foreach (var ynd in ynds) + { + RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(ynd); + if ((rnd != null) && (rnd.IsLoaded)) + { + shaders.Enqueue(rnd); + } + } + } + + public void RenderTrainTracks(List tracks) + { + foreach (var track in tracks) + { + RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(track); + if ((rnd != null) && (rnd.IsLoaded)) + { + shaders.Enqueue(rnd); + } + } + } + + public void RenderNavMeshes(List ynvs) + { + foreach (var ynv in ynvs) + { + RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(ynv); + if ((rnd != null) && (rnd.IsLoaded)) + { + shaders.Enqueue(rnd); + } + } + } + + public void RenderNavMesh(YnvFile ynv) + { + RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(ynv); + if ((rnd != null) && (rnd.IsLoaded)) + { + shaders.Enqueue(rnd); + } + } + + public void RenderScenarios(List ymts) + { + foreach (var scenario in ymts) + { + RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(scenario.ScenarioRegion); + if ((rnd != null) && (rnd.IsLoaded)) + { + shaders.Enqueue(rnd); + } + } + } + + public void RenderPopZones(PopZones zones) + { + RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(zones); + if ((rnd != null) && (rnd.IsLoaded)) + { + shaders.Enqueue(rnd); + } + } + + + + + + + public void RenderWorld(Dictionary renderworldVisibleYmapDict, IEnumerable spaceEnts) + { + + renderworldentities.Clear(); + renderworldrenderables.Clear(); + + VisibleYmaps.Clear(); + foreach (var ymap in renderworldVisibleYmapDict.Values) + { + if (!RenderWorldYmapIsVisible(ymap)) continue; + VisibleYmaps.Add(ymap); + } + + if (spaceEnts != null) + { + foreach (var ae in spaceEnts) //used by active space entities (eg "bullets") + { + if (ae.EntityDef == null) continue; //nothing to render... + RenderWorldCalcEntityVisibility(camera, ae.EntityDef); + renderworldentities.Add(ae.EntityDef); + } + } + + //float minZ = float.MaxValue; + float maxZ = float.MinValue; + float cvwidth = camera.OrthographicSize * camera.AspectRatio * 0.5f; + float cvheight = camera.OrthographicSize * 0.5f; + float cvwmin = camera.Position.X - cvwidth; + float cvwmax = camera.Position.X + cvwidth; + float cvhmin = camera.Position.Y - cvheight; + float cvhmax = camera.Position.Y + cvheight; + + foreach (var ymap in VisibleYmaps) + { + if (ymap.AllEntities != null) + { + for (int i = 0; i < ymap.AllEntities.Length; i++) + { + var ent = ymap.AllEntities[i]; + ent.LargestChildLodDist = 0; + ent.ChildrenLoading = false; + ent.Rendered = false; + ent.ChildRendered = false; + if (MapViewEnabled) + { + //find the max Z value for positioning camera in map view, to help shadows + if ((ent.Position.Z < 1000.0f) && (ent.BSRadius < 500.0f)) + { + float r = ent.BSRadius; + if (((ent.Position.X + r) > cvwmin) && ((ent.Position.X - r) < cvwmax) && ((ent.Position.Y + r) > cvhmin) && ((ent.Position.Y - r) < cvhmax)) + { + //minZ = Math.Min(minZ, ent.BBMin.Z); + maxZ = Math.Max(maxZ, ent.BBMax.Z + 50.0f);//add some bias to avoid clipping things... + } + } + } + } + } + } + + if (MapViewEnabled) + { + //move the camera closer to the geometry, to help shadows in map view. + if (maxZ == float.MinValue) maxZ = 1000.0f; + camera.Position.Z = Math.Min(maxZ, 1000.0f); + } + + + foreach (var ymap in VisibleYmaps) + { + if (ymap.RootEntities != null) + { + YmapFile pymap; + renderworldVisibleYmapDict.TryGetValue(ymap.CMapData.parent, out pymap); + for (int i = 0; i < ymap.RootEntities.Length; i++) + { + var ent = ymap.RootEntities[i]; + int pind = ent.CEntityDef.parentIndex; + if (pind >= 0) //connect root entities to parents if they have them.. + { + YmapEntityDef p = null; + if ((pymap != null) && (pymap.AllEntities != null)) + { + if ((pind < pymap.AllEntities.Length)) + { + p = pymap.AllEntities[pind]; + ent.Parent = p; + ent.ParentGuid = p.CEntityDef.guid; + ent.ParentName = p.CEntityDef.archetypeName; + } + } + else + { }//should only happen if parent ymap not loaded yet... + } + RenderWorldRecurseCalcEntityVisibility(camera, ent); + } + } + } + + foreach (var ymap in VisibleYmaps) + { + if (ymap.RootEntities != null) + { + for (int i = 0; i < ymap.RootEntities.Length; i++) + { + var ent = ymap.RootEntities[i]; + RenderWorldRecurseAddEntities(ent, renderworldentities); + } + } + } + + + //go through the render list, and try ensure renderables and textures for all. + //if an entity is not fully loaded, set a flag for its parent, then traverse to root + //until found an entity that is fully loaded. + //on a second loop, build a final render list based on the flags. + + for (int i = 0; i < renderworldentities.Count; i++) + { + var ent = renderworldentities[i]; + var arch = ent.Archetype; + var pent = ent.Parent; + + if (renderinteriors && ent.IsMlo) //render Mlo child entities... + { + if ((ent.MloInstance != null) && (ent.MloInstance.Entities != null)) + { + for (int j = 0; j < ent.MloInstance.Entities.Length; j++) + { + var intent = ent.MloInstance.Entities[j]; + var intarch = intent.Archetype; + if (intarch == null) continue; //missing archetype... + + if (!RenderIsEntityFinalRender(intent)) continue; //proxy or something.. + + intent.CamRel = intent.Position - camera.Position; + intent.Distance = intent.CamRel.Length(); + intent.IsVisible = true; + + var bscent = intent.CamRel + intent.BSCenter; + float bsrad = intent.BSRadius; + if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref bscent, bsrad)) + { + continue; //frustum cull interior ents + } + var intdrbl = gameFileCache.TryGetDrawable(intarch); + var intrndbl = TryGetRenderable(intarch, intdrbl); + if (intrndbl == null) continue; //no renderable + if (!(intrndbl.IsLoaded && (intrndbl.AllTexturesLoaded || !waitforchildrentoload))) continue; //not loaded yet + + RenderableEntity intrent = new RenderableEntity(); + intrent.Entity = intent; + intrent.Renderable = intrndbl; + renderworldrenderables.Add(intrent); + } + } + if (rendercollisionmeshes) + { + RenderInteriorCollisionMesh(ent); + } + } + + ent.Rendered = true; + var drawable = gameFileCache.TryGetDrawable(arch); + Renderable rndbl = TryGetRenderable(arch, drawable); + if ((rndbl != null) && rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload)) + { + RenderableEntity rent = new RenderableEntity(); + rent.Entity = ent; + rent.Renderable = rndbl; + renderworldrenderables.Add(rent); + + if (pent != null) + { + pent.ChildRendered = true; + } + } + else if (waitforchildrentoload) + { + //todo: render parent if children loading....... + } + } + + for (int i = 0; i < renderworldrenderables.Count; i++) + { + var ent = renderworldrenderables[i].Entity; + if (ent.ChildRendered && !ent.ChildrenLoading) + { + ent.ChildrenRendered = true; + } + } + + for (int i = 0; i < renderworldrenderables.Count; i++) + { + var rent = renderworldrenderables[i]; + var ent = rent.Entity; + var arch = ent.Archetype; + + RenderArchetype(arch, ent, rent.Renderable, false); + } + + + + if (rendergrass) + { + foreach (var ymap in renderworldVisibleYmapDict.Values) + { + if (ymap.GrassInstanceBatches != null) + { + RenderYmapGrass(ymap); + } + } + } + if (renderdistlodlights && timecycle.IsNightTime) + { + foreach (var ymap in renderworldVisibleYmapDict.Values) + { + if (ymap.DistantLODLights != null) + { + RenderYmapDistantLODLights(ymap); + } + } + } + } + private bool RenderWorldYmapIsVisible(YmapFile ymap) + { + if (!ShowScriptedYmaps) + { + if ((ymap._CMapData.flags & 1) > 0) + return false; + } + + return true; + } + private void RenderWorldCalcEntityVisibility(Camera cam, YmapEntityDef ent) + { + ent.CamRel = ent.Position - cam.Position; + ent.Distance = ent.CamRel.Length(); + float distval = ent.Distance; + + if (MapViewEnabled) + { + distval = cam.OrthographicSize / MapViewDetail; + } + + + var loddist = ent.CEntityDef.lodDist; + var cloddist = ent.CEntityDef.childLodDist; + + var loddistmultdef = renderworldLodDistMult * 1.0f; + var loddistmultorph = renderworldDetailDistMult * 1.5f; + var loddistmultarch = renderworldLodDistMult * 1.0f; + + if (loddist <= 0.0f)//usually -1 or -2 + { + if (ent.Archetype != null) + { + loddist = ent.Archetype.LodDist * loddistmultarch; + } + } + else if (ent.CEntityDef.lodLevel == Unk_1264241711.LODTYPES_DEPTH_ORPHANHD) + { + loddist *= loddistmultorph; //orphan view dist adjustment... + } + else + { + loddist *= loddistmultdef; + } + + + if (cloddist <= 0) + { + if (ent.Archetype != null) + { + cloddist = ent.Archetype.LodDist * loddistmultarch; + //cloddist = ent.Archetype.BSRadius * 50.0f; + } + } + else + { + cloddist *= loddistmultdef; + } + if (cloddist == 0) + { + //cloddist = loddist;//always try to show children, based on their loddist + } + + + ent.IsVisible = (distval <= loddist); + ent.ChildrenVisible = (distval <= cloddist) && (ent.CEntityDef.numChildren > 0); + ent.ChildrenLoading = false; + + if ((ent.Parent != null) && (ent.CEntityDef.lodLevel != Unk_1264241711.LODTYPES_DEPTH_ORPHANHD)) + { + if (ent.Parent.CEntityDef.childLodDist == 0.0f) + { + ent.Parent.LargestChildLodDist = Math.Max(ent.Parent.LargestChildLodDist, loddist); + } + } + + if (renderworldMaxLOD != Unk_1264241711.LODTYPES_DEPTH_ORPHANHD) + { + if ((ent.CEntityDef.lodLevel == Unk_1264241711.LODTYPES_DEPTH_ORPHANHD) || + (ent.CEntityDef.lodLevel < renderworldMaxLOD)) + { + ent.IsVisible = false; + ent.ChildrenVisible = false; + } + if (ent.CEntityDef.lodLevel == renderworldMaxLOD) + { + ent.ChildrenVisible = false; + } + } + + if (!ent.IsVisible) + { + ent.ChildrenRendered = false; + } + } + private void RenderWorldRecurseCalcEntityVisibility(Camera cam, YmapEntityDef ent) + { + RenderWorldCalcEntityVisibility(cam, ent); + if (ent.ChildrenVisible) + { + if (ent.Children != null) + { + for (int i = 0; i < ent.Children.Length; i++) + { + var child = ent.Children[i]; + if (child.Ymap == ent.Ymap) + { + RenderWorldRecurseCalcEntityVisibility(cam, child); + } + } + } + } + } + private void RenderWorldRecurseAddEntities(YmapEntityDef ent, List res) + { + //bool useclod = false; //(ent.CEntityDef.childLodDist == 0.0f); + //bool hide = useclod ? (ent.AnyChildVisible /*&& !ent.AnyChildInvisible*/) : ent.ChildrenVisible; + //bool force = !useclod && (ent.Parent != null) && ent.Parent.ChildrenVisible && !hide; + bool hide = ent.ChildrenVisible; + bool force = (ent.Parent != null) && ent.Parent.ChildrenVisible && !hide; + if (force || (ent.IsVisible && !hide)) + { + if (ent.Archetype != null) + { + if (!RenderIsEntityFinalRender(ent)) return; + + var bscent = ent.CamRel + ent.BSCenter; + float bsrad = ent.BSRadius; + if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref bscent, bsrad)) + { + return; //frustum cull + } + + + res.Add(ent); + } + else + { } + } + if (ent.IsVisible && ent.ChildrenVisible && (ent.Children != null)) + { + for (int i = 0; i < ent.Children.Length; i++) + { + var child = ent.Children[i]; + if (child.Ymap == ent.Ymap) + { + RenderWorldRecurseAddEntities(ent.Children[i], res); + } + } + } + } + + + private bool RenderIsEntityFinalRender(YmapEntityDef ent) + { + var arch = ent.Archetype; + bool isshadowproxy = false; + bool isreflproxy = false; + uint archflags = arch._BaseArchetypeDef.flags; + if (arch.Type == MetaName.CTimeArchetypeDef) + { + if (!(rendertimedents && (rendertimedentsalways || arch.IsActive(timeofday)))) return false; + //archflags = arch._BaseArchetypeDef.flags; + } + //else if (arch.Type == MetaName.CMloArchetypeDef) + //{ + // archflags = arch._BaseArchetypeDef.flags; + //} + ////switch (archflags) + ////{ + //// //case 8192: //8192: is YTYP no shadow rendering - CP + //// case 2048: //000000000000000000100000000000 shadow proxies... + //// case 536872960: //100000000000000000100000000000 tunnel refl/shadow prox? + //// isshadowproxy = true; break; + ////} + if ((archflags & 2048) > 0) + { + isshadowproxy = true; + } + + //if ((ent.CEntityDef.flags & 1572864) == 1572864) + //{ + // isreflproxy = true; + //} + + switch (ent._CEntityDef.flags) + { + case 135790592: //001000000110000000000000000000 prewater proxy (golf course) + case 135790593: //001000000110000000000000000001 water refl proxy? (mike house) + case 672661504: //101000000110000000000000000000 vb_ca_prop_tree_reflprox_2 + case 536870912: //100000000000000000000000000000 vb_05_emissive_mirroronly + case 35127296: //000010000110000000000000000000 tunnel refl proxy? + case 39321602: //000010010110000000000000000010 mlo reflection? + isreflproxy = true; break; + //nonproxy is: //000000000110000000000000001000 (1572872) + // //000000000110000000000000000000 + } + if (isshadowproxy || isreflproxy) + { + return renderproxies; //filter out proxy entities... + } + return true; + } + private bool RenderIsModelFinalRender(RenderableModel model) + { + + if ((model.Unk2Ch & 1) == 0) //smallest bit is proxy/"final render" bit? seems to work... + { + return renderproxies; + } + return true; + + //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; + } + + + + + + + + + public void RenderYmap(YmapFile ymap) + { + if (ymap == null) return; + if (!ymap.Loaded) return; + + if ((ymap.AllEntities != null) && (ymap.RootEntities != null)) + { + if (usedynamiclod) + { + for (int i = 0; i < ymap.RootEntities.Length; i++) + { + RenderYmapLOD(ymap.RootEntities[i].Ymap, ymap.RootEntities[i]); + } + } + else + { + var ents = renderchildents ? ymap.AllEntities : ymap.RootEntities; + for (int i = 0; i < ents.Length; i++) + { + var ent = ents[i]; + if (renderchildents && ent.Children != null) continue; + //if (rootent.CEntityDef.parentIndex == -1) continue; + Archetype arch = ent.Archetype; + if (arch != null) + { + bool timed = (arch.Type == MetaName.CTimeArchetypeDef); + if (!timed || (rendertimedents && (rendertimedentsalways || arch.IsActive(timeofday)))) + { + ent.CamRel = ent.Position - camera.Position; + RenderArchetype(arch, ent); + } + } + else + { + //couldn't find archetype... + } + } + } + } + + if (rendergrass && (ymap.GrassInstanceBatches != null)) + { + RenderYmapGrass(ymap); + } + if (renderdistlodlights && timecycle.IsNightTime && (ymap.DistantLODLights != null)) + { + RenderYmapDistantLODLights(ymap); + } + + } + private bool RenderYmapLOD(YmapFile ymap, YmapEntityDef entity) + { + if (!ymap.Loaded) return false; + + ymap.EnsureChildYmaps(gameFileCache); + + Archetype arch = entity.Archetype; + if (arch != null) + { + bool timed = (arch.Type == MetaName.CTimeArchetypeDef); + if (!timed || (rendertimedents && (rendertimedentsalways || arch.IsActive(timeofday)))) + { + bool usechild = false; + entity.CamRel = entity.Position - camera.Position; + float dist = (entity.CamRel + entity.BSCenter).Length(); + float rad = arch.BSRadius; + float loddist = entity.CEntityDef.lodDist; + if (loddist < 1.0f) + { + loddist = 200.0f; + } + float mindist = Math.Max(dist - rad, 1.0f) * lodthreshold; + if (mindist < loddist) + { + //recurse... + var children = entity.ChildrenMerged; + if ((children != null)) + { + usechild = true; + for (int i = 0; i < children.Length; i++) + { + var childe = children[i]; + if (!RenderYmapLOD(childe.Ymap, childe)) + { + if (waitforchildrentoload) + { + usechild = false; //might cause some overlapping, but should reduce things disappearing + } + } + } + } + if (!entity.ChildrenRendered) + { + entity.ChildrenRendered = usechild; + } + } + else + { + entity.ChildrenRendered = false; + } + if (!usechild && !entity.ChildrenRendered) + { + + + + if (renderinteriors && entity.IsMlo) //render Mlo child entities... + { + if ((entity.MloInstance != null) && (entity.MloInstance.Entities != null)) + { + for (int j = 0; j < entity.MloInstance.Entities.Length; j++) + { + var intent = entity.MloInstance.Entities[j]; + var intarch = intent.Archetype; + if (intarch == null) continue; //missing archetype... + + if (!RenderIsEntityFinalRender(intent)) continue; //proxy or something.. + + intent.CamRel = intent.Position - camera.Position; + intent.Distance = intent.CamRel.Length(); + intent.IsVisible = true; + + RenderArchetype(intarch, intent); + } + } + if (rendercollisionmeshes) + { + RenderInteriorCollisionMesh(entity); + } + } + + + + + return RenderArchetype(arch, entity); + } + return true; + } + + } + return false; + } + + + + private void RenderYmapGrass(YmapFile ymap) + { + //enqueue ymap grass instance batches for rendering + + if (ymap.GrassInstanceBatches == null) return; + + foreach (var batch in ymap.GrassInstanceBatches) + { + batch.CamRel = batch.Position - camera.Position; + //batch.Distance = batch.CamRel.Length(); + + float lodDist = batch.Batch.lodDist * renderworldDetailDistMult;//maybe add grass dist mult + //if (batch.Distance > lodDist) continue; //too far away.. + + lodDist *= 0.75f; //reduce it just a bit to improve performance... remove this later + + float cx = camera.Position.X; + float cy = camera.Position.Y; + float cz = camera.Position.Z; + if (cx < (batch.AABBMin.X - lodDist)) continue; + if (cx > (batch.AABBMax.X + lodDist)) continue; + if (cy < (batch.AABBMin.Y - lodDist)) continue; + if (cy > (batch.AABBMax.Y + lodDist)) continue; + if (cz < (batch.AABBMin.Z - lodDist)) continue; + if (cz > (batch.AABBMax.Z + lodDist)) continue; + + + var bscent = batch.CamRel; + float bsrad = batch.Radius; + if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref bscent, bsrad)) + { + continue; //frustum cull grass batches... + } + + var arch = batch.Archetype; + var drbl = gameFileCache.TryGetDrawable(arch); + var rndbl = TryGetRenderable(arch, drbl); + var instb = renderableCache.GetRenderableInstanceBatch(batch); + if (rndbl == null) continue; //no renderable + if (!(rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload))) continue; //not loaded yet + if ((instb == null) || !instb.IsLoaded) continue; + + RenderableInstanceBatchInst binst = new RenderableInstanceBatchInst(); + binst.Batch = instb; + binst.Renderable = rndbl; + + shaders.Enqueue(ref binst); + + } + + } + + private void RenderYmapDistantLODLights(YmapFile ymap) + { + //enqueue ymap DistantLODLights instance batch for rendering + + if (ymap.DistantLODLights == null) return; + + switch (ymap.DistantLODLights.CDistantLODLight.category) + { + case 0: //distlodlights_small009.ymap + case 1: //distlodlights_medium000.ymap + case 2: //distlodlights_large000.ymap + break; + default: + break; + } + + RenderableDistantLODLights lights = renderableCache.GetRenderableDistantLODLights(ymap.DistantLODLights); + if (!lights.IsLoaded) return; + + + uint ytdhash = 3154743001; //"graphics" + uint texhash = 2236244673; //"distant_light" + YtdFile graphicsytd = gameFileCache.GetYtd(ytdhash); + Texture lighttex = null; + if ((graphicsytd != null) && (graphicsytd.Loaded) && (graphicsytd.TextureDict != null) && (graphicsytd.TextureDict.Dict != null)) + { + graphicsytd.TextureDict.Dict.TryGetValue(texhash, out lighttex); //starfield hash + } + + if (lighttex == null) return; + RenderableTexture lightrtex = null; + if (lighttex != null) + { + lightrtex = renderableCache.GetRenderableTexture(lighttex); + } + if (lightrtex == null) return; + if (!lightrtex.IsLoaded) return; + + lights.Texture = lightrtex; + + shaders.Enqueue(lights); + } + + + + + + + public bool RenderFragment(Archetype arch, YmapEntityDef ent, FragType f, uint txdhash = 0) + { + + RenderDrawable(f.Drawable, arch, ent, txdhash); + + if (f.Unknown_F8h_Data != null) //cloth + { + RenderDrawable(f.Unknown_F8h_Data, arch, ent, txdhash); + } + + //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, arch, ent, -camera.Position, hash); + } + } + } + } + + return true; + } + + public bool RenderArchetype(Archetype arche, YmapEntityDef entity, Renderable rndbl = null, bool cull = true) + { + //enqueue a single archetype for rendering. + + if (arche == null) return false; + + Vector3 camrel = (entity != null) ? entity.CamRel : -camera.Position; + + Quaternion orientation = Quaternion.Identity; + Vector3 scale = Vector3.One; + Vector3 bscent = camrel; + if (entity != null) + { + orientation = entity.Orientation; + scale = entity.Scale; + bscent += entity.BSCenter; + } + else + { + bscent += arche.BSCenter; + } + + float bsrad = arche.BSRadius;// * scale; + if (cull) + { + if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref bscent, bsrad)) + { + return true; //culled - not visible; don't render, but pretend we did for LOD purposes.. + } + } + + float dist = bscent.Length(); + + if (boundsmode == BoundsShaderMode.Sphere) + { + if ((bsrad < renderboundsmaxrad) && (dist < renderboundsmaxdist)) + { + MapSphere ms = new MapSphere(); + ms.CamRelPos = bscent; + ms.Radius = bsrad; + BoundingSpheres.Add(ms); + } + } + if (boundsmode == BoundsShaderMode.Box) + { + if ((dist < renderboundsmaxdist)) + { + MapBox mb = new MapBox(); + mb.CamRelPos = camrel; + mb.BBMin = arche.BBMin; + mb.BBMax = arche.BBMax; + mb.Orientation = orientation; + mb.Scale = scale; + BoundingBoxes.Add(mb); + } + } + + + + bool res = false; + if (rndbl == null) + { + var drawable = gameFileCache.TryGetDrawable(arche); + rndbl = TryGetRenderable(arche, drawable); + } + + if (rndbl != null) + { + res = RenderRenderable(rndbl, arche, entity); + + + //fragments have extra drawables! need to render those too... TODO: handle fragments properly... + FragDrawable fd = rndbl.Key as FragDrawable; + if (fd != null) + { + var frag = fd.OwnerFragment; + if ((frag != null) && (frag.Unknown_F8h_Data != null)) //cloth... + { + rndbl = TryGetRenderable(arche, frag.Unknown_F8h_Data); + if (rndbl != null) + { + bool res2 = RenderRenderable(rndbl, arche, entity); + res = res || res2; + } + } + } + } + + + return res; + } + + public bool RenderDrawable(DrawableBase drawable, Archetype arche, YmapEntityDef entity, uint txdHash = 0) + { + //enqueue a single drawable for rendering. + + if (drawable == null) + return false; + + Renderable rndbl = TryGetRenderable(arche, drawable, txdHash); + if (rndbl == null) + return false; + + return RenderRenderable(rndbl, arche, entity); + } + + private bool RenderRenderable(Renderable rndbl, Archetype arche, YmapEntityDef entity) + { + //enqueue a single renderable for rendering. + + if (!rndbl.IsLoaded) return false; + + + if (RenderedDrawablesListEnable) //for later hit tests + { + var rd = new RenderedDrawable(); + rd.Drawable = rndbl.Key; + rd.Archetype = arche; + rd.Entity = entity; + RenderedDrawables.Add(rd); + } + + bool isselected = SelectionFlagsTestAll || (rndbl.Key == SelectedDrawable); + + Vector3 camrel = -camera.Position; + 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; + if (entity != null) + { + position = entity.Position; + scale = entity.Scale; + orientation = entity.Orientation; + tintPaletteIndex = entity.CEntityDef.tintValue; + bbmin = entity.BBMin; + bbmax = entity.BBMax; + bscen = entity.BSCenter; + camrel += position; + } + float distance = (camrel + bscen).Length(); + + + if (rendercollisionmeshes && rendercollisionmeshlayerdrawable) + { + Drawable sdrawable = rndbl.Key as Drawable; + if ((sdrawable != null) && (sdrawable.Bound != null)) + { + RenderCollisionMesh(sdrawable.Bound, entity); + } + } + if (renderskeletons && rndbl.HasSkeleton) + { + RenderSkeleton(rndbl, entity); + } + + bool retval = true;// false; + if (rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload)) + { + 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; + + + RenderableModel[] models = isselected ? rndbl.AllModels : rndbl.HDModels; + + for (int mi = 0; mi < models.Length; mi++) + { + var model = models[mi]; + + if (isselected) + { + if (SelectionModelDrawFlags.ContainsKey(model.DrawableModel)) + { continue; } //filter out models in selected item that aren't flagged for drawing. + } + + if (!RenderIsModelFinalRender(model) && !renderproxies) + { continue; } //filter out reflection proxy models... + + for (int gi = 0; gi < model.Geometries.Length; gi++) + { + var geom = model.Geometries[gi]; + + if (isselected) + { + if (SelectionGeometryDrawFlags.ContainsKey(geom.DrawableGeom)) + { continue; } //filter out geometries in selected item that aren't flagged for drawing. + } + + rginst.Geom = geom; + + shaders.Enqueue(ref rginst); + } + } + } + else + { + retval = false; + } + return retval; + } + + + + + public void RenderCar(Vector3 pos, Quaternion ori, MetaHash modelHash, MetaHash modelSetHash) + { + SelectedCarGenEntity.SetPosition(pos); + SelectedCarGenEntity.SetOrientation(ori); + + uint carhash = modelHash; + if ((carhash == 0) && (modelSetHash != 0)) + { + //find the pop group... and choose a vehicle.. + var stypes = Scenarios.ScenarioTypes; + if (stypes != null) + { + var modelset = stypes.GetVehicleModelSet(modelSetHash); + if ((modelset != null) && (modelset.Models != null) && (modelset.Models.Length > 0)) + { + carhash = JenkHash.GenHash(modelset.Models[0].NameLower); + } + } + } + if (carhash == 0) carhash = 418536135; //"infernus" + + YftFile caryft = gameFileCache.GetYft(carhash); + if ((caryft != null) && (caryft.Loaded) && (caryft.Fragment != null)) + { + RenderFragment(null, SelectedCarGenEntity, caryft.Fragment, carhash); + } + } + + + + + + private void RenderInteriorCollisionMesh(YmapEntityDef mlo) + { + //enqueue interior collison meshes for rendering. + + if (mlo.Archetype == null) return; + var hash = mlo.Archetype.Hash; + YbnFile ybn = gameFileCache.GetYbn(hash); + if ((ybn != null) && (ybn.Loaded)) + { + RenderCollisionMesh(ybn.Bounds, mlo); + } + if (ybn == null) + { } + } + + public void RenderCollisionMesh(Bounds bounds, YmapEntityDef entity) + { + //enqueue a single collision mesh for rendering. + + 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; + } + + switch (bounds.Type) + { + case 10: //BoundComposite + BoundComposite boundcomp = bounds as BoundComposite; + if (boundcomp != null) + { + 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(ref rbginst); + } + + if (RenderedBoundCompsListEnable) //for later hit tests + { + var rb = new RenderedBoundComposite(); + rb.BoundComp = rndbc; + rb.Entity = entity; + RenderedBoundComps.Add(rb); + } + } + } + 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; + } + } + + + + + + + + + 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; + + Renderable rndbl = renderableCache.GetRenderable(drawable); + if (rndbl == null) return null; + + if (clipDict != 0) + { + YcdFile ycd = gameFileCache.GetYcd(clipDict); + if ((ycd != null) && (ycd.Loaded)) + { + MetaHash ahash = arche.Hash; + MetaHash ahashuv1 = ahash + 1; + MetaHash ahashuv2 = ahash + 2; + ClipMapEntry cme, cmeuv1, cmeuv2; //this goes to at least uv5! (from uv0) - see hw1_09.ycd + bool found = false; + if (ycd.ClipMap.TryGetValue(ahash, out cme)) + { + found = true; + } + if (ycd.ClipMap.TryGetValue(ahashuv1, out cmeuv1)) + { + found = true; + } + if (ycd.ClipMap.TryGetValue(ahashuv2, out cmeuv2)) + { + found = true; + } + if (!found) + { + } + } + } + + + bool alltexsloaded = true; + int missingtexcount = 0; + for (int mi = 0; mi < rndbl.HDModels.Length; mi++) + { + var model = rndbl.HDModels[mi]; + + //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 (texDict != 0) + { + YtdFile ytd = gameFileCache.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... + var ytd2 = gameFileCache.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 = gameFileCache.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) + { + var ytd2 = gameFileCache.TryGetTextureDictForTexture(tex.NameHash); + if ((ytd2 != null) && (ytd2.Loaded) && (ytd2.TextureDict != null)) + { + dtex = ytd2.TextureDict.Lookup(tex.NameHash); + } + if (dtex == null) + { + dtex = gameFileCache.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.. + { + var ytd2 = gameFileCache.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; + } + + + + + } + + + public struct RenderedDrawable + { + public DrawableBase Drawable; + public Archetype Archetype; + public YmapEntityDef Entity; + } + public struct RenderedBoundComposite + { + public RenderableBoundComposite BoundComp; + public YmapEntityDef Entity; + } + + public struct RenderSkeletonItem + { + public Renderable Renderable; + public YmapEntityDef Entity; + } + + + + public enum WorldRenderMode + { + Default = 0, + SingleTexture = 1, + VertexNormals = 2, + VertexTangents = 3, + VertexColour = 4, + TextureCoord = 5, + } + + + + + +} diff --git a/Rendering/ShaderManager.cs b/Rendering/ShaderManager.cs index 450dfc7..bba3705 100644 --- a/Rendering/ShaderManager.cs +++ b/Rendering/ShaderManager.cs @@ -730,7 +730,7 @@ namespace CodeWalker.Rendering - public void Enqueue(RenderableGeometryInst geom) + public void Enqueue(ref RenderableGeometryInst geom) { var shader = geom.Geom.DrawableGeom.Shader; @@ -751,11 +751,11 @@ namespace CodeWalker.Rendering batch.Geometries.Add(geom); } - public void Enqueue(RenderableBoundGeometryInst geom) + public void Enqueue(ref RenderableBoundGeometryInst geom) { RenderBoundGeoms.Add(geom); } - public void Enqueue(RenderableInstanceBatchInst batch) + public void Enqueue(ref RenderableInstanceBatchInst batch) { RenderInstBatches.Add(batch); } diff --git a/Utils/InputUtils.cs b/Utils/InputUtils.cs new file mode 100644 index 0000000..118aa65 --- /dev/null +++ b/Utils/InputUtils.cs @@ -0,0 +1,336 @@ +using CodeWalker.Properties; +using SharpDX; +using SharpDX.XInput; +using System; +using System.Collections.Specialized; +using System.Windows.Forms; + +namespace CodeWalker +{ + + + + public class InputManager + { + public Controller xbcontroller = null; + public State xbcontrollerstate; + public State xbcontrollerstateprev; + public Vector4 xbmainaxes = Vector4.Zero; + public Vector4 xbmainaxesprev = Vector4.Zero; + public Vector2 xbtrigs = Vector2.Zero; + public Vector2 xbtrigsprev = Vector2.Zero; + public float xbcontrolvelocity = 0.0f; + + public bool xbenable = false; + public float xblx = 0; //left stick X axis + public float xbly = 0; //left stick Y axis + public float xbrx = 0; //right stick X axis + public float xbry = 0; //right stick Y axis + public float xblt = 0; //left trigger value + public float xbrt = 0; //right trigger value + + + + + + public volatile bool kbmovefwd = false; + public volatile bool kbmovebck = false; + public volatile bool kbmovelft = false; + public volatile bool kbmovergt = false; + public volatile bool kbmoveup = false; + public volatile bool kbmovedn = false; + public volatile bool kbjump = false; + public volatile bool kbmoving = false; + + public KeyBindings keyBindings = new KeyBindings(Settings.Default.KeyBindings); + + public bool CtrlPressed = false; + public bool ShiftPressed = false; + + + + + public void Init() + { + 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 Update(float elapsed) + { + if (elapsed > 0.1f) elapsed = 0.1f; + + var s = Settings.Default; + + xbenable = (xbcontroller != null) && (xbcontroller.IsConnected); + xblx = 0; xbly = 0; xbrx = 0; xbry = 0; xblt = 0; xbrt = 0; //input axes + + if (xbenable) + { + xbcontrollerstateprev = xbcontrollerstate; + xbcontrollerstate = xbcontroller.GetState(); + xbmainaxesprev = xbmainaxes; + xbtrigsprev = xbtrigs; + xbmainaxes = ControllerMainAxes(); + xbtrigs = ControllerTriggers(); + xblx = xbmainaxes.X; + xbly = xbmainaxes.Y; + xbrx = xbmainaxes.Z; + xbry = xbmainaxes.W; + xblt = xbtrigs.X; + xbrt = xbtrigs.Y; + float lamt = s.XInputLThumbSensitivity * elapsed; + float ramt = s.XInputRThumbSensitivity * elapsed; + xbly = s.XInputLThumbInvert ? xbly : -xbly; + xbry = s.XInputRThumbInvert ? xbry : -xbry; + xblx *= lamt; + xbly *= lamt; + xbrx *= ramt; + xbry *= ramt; + } + + } + + + + public void KeyDown(KeyEventArgs e, bool enablemove) + { + var k = e.KeyCode; + CtrlPressed = (e.Modifiers & Keys.Control) > 0; + ShiftPressed = (e.Modifiers & Keys.Shift) > 0; + + //enablemove = enablemove && (!ctrl); + + //WASD move... + 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; + } + + kbmoving = kbmovefwd || kbmovebck || kbmovelft || kbmovergt || kbmoveup || kbmovedn || kbjump; + + } + + public void KeyUp(KeyEventArgs e) + { + CtrlPressed = (e.Modifiers & Keys.Control) > 0; + ShiftPressed = (e.Modifiers & Keys.Shift) > 0; + + 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; + + kbmoving = kbmovefwd || kbmovebck || kbmovelft || kbmovergt || kbmoveup || kbmovedn || kbjump; + + } + + public void KeyboardStop() + { + kbmovefwd = false; + kbmovebck = false; + kbmovelft = false; + kbmovergt = false; + kbmoveup = false; + kbmovedn = false; + kbjump = false; + } + + + + public Vector3 KeyboardMoveVec(bool mapview = false) + { + Vector3 movevec = Vector3.Zero; + if (mapview) + { + 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; + } + else + { + 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; + } + return movevec; + } + + + + public Vector4 ControllerMainAxes() + { + 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); + + 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; + + return new Vector4(lx, ly, rx, ry); + } + public 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); + } + public bool ControllerButtonPressed(GamepadButtonFlags b) + { + return ((xbcontrollerstate.Gamepad.Buttons & b) != 0); + } + public bool ControllerButtonJustPressed(GamepadButtonFlags b) + { + return (((xbcontrollerstate.Gamepad.Buttons & b) != 0) && ((xbcontrollerstateprev.Gamepad.Buttons & b) == 0)); + } + + + } + + + + + public class KeyBindings + { + public Keys MoveForward = Keys.W; + public Keys MoveBackward = Keys.S; + public Keys MoveLeft = Keys.A; + public Keys MoveRight = Keys.D; + public Keys MoveUp = Keys.R; + public Keys MoveDown = Keys.F; + public Keys MoveSlowerZoomIn = Keys.Z; + public Keys MoveFasterZoomOut = Keys.X; + public Keys ToggleMouseSelect = Keys.C; + public Keys ToggleToolbar = Keys.T; + public Keys ExitEditMode = Keys.Q; + public Keys EditPosition = Keys.W; + public Keys EditRotation = Keys.E; + public Keys EditScale = Keys.R; + public Keys Jump = Keys.Space; //for control mode + public Keys FirstPerson = Keys.P; + + public KeyBindings(StringCollection sc) + { + foreach (string s in sc) + { + string[] parts = s.Split(':'); + if (parts.Length == 2) + { + string sval = parts[1].Trim(); + Keys k = (Keys)Enum.Parse(typeof(Keys), sval); + SetBinding(parts[0], k); + } + } + } + + public void SetBinding(string name, Keys k) + { + switch (name) + { + case "Move Forwards": MoveForward = k; break; + case "Move Backwards": MoveBackward = k; break; + case "Move Left": MoveLeft = k; break; + case "Move Right": MoveRight = k; break; + case "Move Up": MoveUp = k; break; + case "Move Down": MoveDown = k; break; + case "Move Slower / Zoom In": MoveSlowerZoomIn = k; break; + case "Move Faster / Zoom Out": MoveFasterZoomOut = k; break; + case "Toggle Mouse Select": ToggleMouseSelect = k; break; + case "Toggle Toolbar": ToggleToolbar = k; break; + case "Exit Edit Mode": ExitEditMode = k; break; + case "Edit Position": EditPosition = k; break; + case "Edit Rotation": EditRotation = k; break; + case "Edit Scale": EditScale = k; break; + case "First Person Mode": FirstPerson = k; break; + } + } + + public StringCollection GetSetting() + { + StringCollection sc = new StringCollection(); + sc.Add(GetSettingItem("Move Forwards", MoveForward)); + sc.Add(GetSettingItem("Move Backwards", MoveBackward)); + sc.Add(GetSettingItem("Move Left", MoveLeft)); + sc.Add(GetSettingItem("Move Right", MoveRight)); + sc.Add(GetSettingItem("Move Up", MoveUp)); + sc.Add(GetSettingItem("Move Down", MoveDown)); + sc.Add(GetSettingItem("Move Slower / Zoom In", MoveSlowerZoomIn)); + sc.Add(GetSettingItem("Move Faster / Zoom Out", MoveFasterZoomOut)); + sc.Add(GetSettingItem("Toggle Mouse Select", ToggleMouseSelect)); + sc.Add(GetSettingItem("Toggle Toolbar", ToggleToolbar)); + sc.Add(GetSettingItem("Exit Edit Mode", ExitEditMode)); + sc.Add(GetSettingItem("Edit Position", EditPosition)); + sc.Add(GetSettingItem("Edit Rotation", EditRotation)); + sc.Add(GetSettingItem("Edit Scale", EditScale)); + sc.Add(GetSettingItem("First Person Mode", FirstPerson)); + return sc; + } + + private string GetSettingItem(string name, Keys val) + { + return name + ": " + val.ToString(); + } + + public KeyBindings Copy() + { + return (KeyBindings)MemberwiseClone(); + } + + } + + + +} \ No newline at end of file diff --git a/Utils/MapUtils.cs b/Utils/MapUtils.cs new file mode 100644 index 0000000..a54ec36 --- /dev/null +++ b/Utils/MapUtils.cs @@ -0,0 +1,764 @@ +using System; +using System.IO; +using System.Globalization; +using System.ComponentModel; +using System.Collections.Generic; +using SharpDX; +using SharpDX.Direct3D11; +using CodeWalker.Utils; +using CodeWalker.World; +using CodeWalker.GameFiles; + +namespace CodeWalker +{ + + + public class MapIcon + { + public string Name { get; set; } + public string Filepath { get; set; } + public Texture2D Tex { get; set; } + public ShaderResourceView TexView { get; set; } + public Vector3 Center { get; set; } //in image pixels + public float Scale { get; set; } //screen pixels per icon pixel + public int TexWidth { get; set; } + public int TexHeight { get; set; } + + public MapIcon(string name, string filepath, int texw, int texh, float centerx, float centery, float scale) + { + Name = name; + Filepath = filepath; + TexWidth = texw; + TexHeight = texh; + Center = new Vector3(centerx, centery, 0.0f); + Scale = scale; + + if (!File.Exists(filepath)) + { + throw new Exception("File not found."); + } + } + + public void LoadTexture(Device device, Action errorAction) + { + try + { + if (device != null) + { + Tex = TextureLoader.CreateTexture2DFromBitmap(device, TextureLoader.LoadBitmap(new SharpDX.WIC.ImagingFactory2(), Filepath)); + TexView = new ShaderResourceView(device, Tex); + } + } + catch (Exception ex) + { + errorAction("Could not load map icon " + Filepath + " for " + Name + "!\n\n" + ex.ToString()); + } + } + + public void UnloadTexture() + { + if (TexView != null) + { + TexView.Dispose(); + TexView = null; + } + if (Tex != null) + { + Tex.Dispose(); + Tex = null; + } + } + + public override string ToString() + { + return Name; + } + } + + public class MapMarker + { + public MapIcon Icon { get; set; } + public Vector3 WorldPos { get; set; } //actual world pos + public Vector3 CamRelPos { get; set; } //updated per frame + public Vector3 ScreenPos { get; set; } //position on screen (updated per frame) + public string Name { get; set; } + public List Properties { get; set; } //additional data + public bool IsMovable { get; set; } + public float Distance { get; set; } //length of CamRelPos, updated per frame + + public void Parse(string s) + { + Vector3 p = new Vector3(0.0f); + string[] ss = s.Split(','); + if (ss.Length > 1) + { + FloatUtil.TryParse(ss[0].Trim(), out p.X); + FloatUtil.TryParse(ss[1].Trim(), out p.Y); + } + if (ss.Length > 2) + { + FloatUtil.TryParse(ss[2].Trim(), out p.Z); + } + if (ss.Length > 3) + { + Name = ss[3].Trim(); + } + else + { + Name = string.Empty; + } + for (int i = 4; i < ss.Length; i++) + { + if (Properties == null) Properties = new List(); + Properties.Add(ss[i].Trim()); + } + WorldPos = p; + } + + public override string ToString() + { + string cstr = Get3DWorldPosString(); + if (!string.IsNullOrEmpty(Name)) + { + cstr += ", " + Name; + if (Properties != null) + { + foreach (string prop in Properties) + { + cstr += ", " + prop; + } + } + } + return cstr; + } + + public string Get2DWorldPosString() + { + return string.Format(CultureInfo.InvariantCulture, "{0}, {1}", WorldPos.X, WorldPos.Y); + } + public string Get3DWorldPosString() + { + return string.Format(CultureInfo.InvariantCulture, "{0}, {1}, {2}", WorldPos.X, WorldPos.Y, WorldPos.Z); + } + + + } + + + + public struct MapSphere + { + public Vector3 CamRelPos { get; set; } + public float Radius { get; set; } + } + + public struct MapBox + { + public Vector3 CamRelPos { get; set; } + public Vector3 BBMin { get; set; } + public Vector3 BBMax { get; set; } + public Quaternion Orientation { get; set; } + public Vector3 Scale { get; set; } + } + + + + + + + + + [TypeConverter(typeof(ExpandableObjectConverter))] + public struct MapSelection + { + public YmapEntityDef EntityDef { get; set; } + public Archetype Archetype { get; set; } + public DrawableBase Drawable { get; set; } + public DrawableGeometry Geometry { get; set; } + public MetaWrapper EntityExtension { get; set; } + public MetaWrapper ArchetypeExtension { get; set; } + public YmapTimeCycleModifier TimeCycleModifier { get; set; } + public YmapCarGen CarGenerator { get; set; } + public YmapGrassInstanceBatch GrassBatch { get; set; } + public YmapDistantLODLights DistantLodLights { get; set; } + public YmapEntityDef MloEntityDef { get; set; } + public WaterQuad WaterQuad { get; set; } + public Bounds CollisionBounds { get; set; } + public YnvPoly NavPoly { get; set; } + public YndNode PathNode { get; set; } + public YndLink PathLink { get; set; } + public TrainTrackNode TrainTrackNode { get; set; } + public ScenarioNode ScenarioNode { get; set; } + public MCScenarioChainingEdge ScenarioEdge { get; set; } + public AudioPlacement Audio { get; set; } + + public bool MultipleSelection { get; set; } + public Vector3 MultipleSelectionCenter { get; set; } + + public BoundingBox AABB { get; set; } + public BoundingSphere BSphere { get; set; } + public int GeometryIndex { get; set; } + public Vector3 CamRel { get; set; } + public float HitDist { get; set; } + + + public bool HasValue + { + get + { + return (EntityDef != null) || + (Archetype != null) || + (Drawable != null) || + (Geometry != null) || + (EntityExtension != null) || + (ArchetypeExtension != null) || + (TimeCycleModifier != null) || + (CarGenerator != null) || + (GrassBatch != null) || + (WaterQuad != null) || + (CollisionBounds != null) || + (NavPoly != null) || + (PathNode != null) || + (TrainTrackNode != null) || + (DistantLodLights != null) || + (MloEntityDef != null) || + (ScenarioNode != null) || + (Audio != null); + } + } + + public bool HasHit + { + get { return (HitDist != float.MaxValue); } + } + + + public bool CheckForChanges(MapSelection mhit) + { + return (EntityDef != mhit.EntityDef) + || (Archetype != mhit.Archetype) + || (Drawable != mhit.Drawable) + || (TimeCycleModifier != mhit.TimeCycleModifier) + || (ArchetypeExtension != mhit.ArchetypeExtension) + || (EntityExtension != mhit.EntityExtension) + || (CarGenerator != mhit.CarGenerator) + || (MloEntityDef != mhit.MloEntityDef) + || (DistantLodLights != mhit.DistantLodLights) + || (GrassBatch != mhit.GrassBatch) + || (WaterQuad != mhit.WaterQuad) + || (CollisionBounds != mhit.CollisionBounds) + || (NavPoly != mhit.NavPoly) + || (PathNode != mhit.PathNode) + || (TrainTrackNode != mhit.TrainTrackNode) + || (ScenarioNode != mhit.ScenarioNode) + || (Audio != mhit.Audio); + } + public bool CheckForChanges() + { + return (EntityDef != null) + || (Archetype != null) + || (Drawable != null) + || (TimeCycleModifier != null) + || (ArchetypeExtension != null) + || (EntityExtension != null) + || (CarGenerator != null) + || (MloEntityDef != null) + || (DistantLodLights != null) + || (GrassBatch != null) + || (WaterQuad != null) + || (CollisionBounds != null) + || (NavPoly != null) + || (PathNode != null) + || (PathLink != null) + || (TrainTrackNode != null) + || (ScenarioNode != null) + || (Audio != null); + } + + + public void Clear() + { + EntityDef = null; + Archetype = null; + Drawable = null; + Geometry = null; + EntityExtension = null; + ArchetypeExtension = null; + TimeCycleModifier = null; + CarGenerator = null; + GrassBatch = null; + WaterQuad = null; + CollisionBounds = null; + NavPoly = null; + PathNode = null; + PathLink = null; + TrainTrackNode = null; + DistantLodLights = null; + MloEntityDef = null; + ScenarioNode = null; + ScenarioEdge = null; + Audio = null; + MultipleSelection = false; + AABB = new BoundingBox(); + GeometryIndex = 0; + CamRel = new Vector3(); + HitDist = float.MaxValue; + } + + public string GetNameString(string defval) + { + string name = defval; + if (MultipleSelection) + { + name = "Multiple items"; + } + else if (EntityDef != null) + { + name = EntityDef.CEntityDef.archetypeName.ToString(); + } + else if (Archetype != null) + { + name = Archetype.Hash.ToString(); + } + else if (TimeCycleModifier != null) + { + name = TimeCycleModifier.CTimeCycleModifier.name.ToString(); + } + else if (CarGenerator != null) + { + name = CarGenerator.CCarGen.carModel.ToString(); + } + else if (DistantLodLights != null) + { + name = DistantLodLights.Ymap?.Name ?? ""; + } + else if (CollisionBounds != null) + { + name = CollisionBounds.GetName(); + } + if (EntityExtension != null) + { + name = EntityExtension.Name; + } + if (ArchetypeExtension != null) + { + name = ArchetypeExtension.Name; + } + if (WaterQuad != null) + { + name = "WaterQuad " + WaterQuad.ToString(); + } + if (NavPoly != null) + { + name = "NavPoly " + NavPoly.ToString(); + } + if (PathNode != null) + { + name = "PathNode " + PathNode.AreaID.ToString() + "." + PathNode.NodeID.ToString(); //+ FloatUtil.GetVector3String(PathNode.Position); + } + if (TrainTrackNode != null) + { + name = "TrainTrackNode " + FloatUtil.GetVector3String(TrainTrackNode.Position); + } + if (ScenarioNode != null) + { + name = ScenarioNode.ToString(); + } + if (Audio != null) + { + name = Audio.ShortTypeName + " " + Audio.GetNameString();// FloatUtil.GetVector3String(Audio.InnerPos); + } + return name; + } + + public string GetFullNameString(string defval) + { + string name = defval; + if (MultipleSelection) + { + name = "Multiple items"; + } + else if (EntityDef != null) + { + name = EntityDef.CEntityDef.archetypeName.ToString(); + } + else if (Archetype != null) + { + name = Archetype.Hash.ToString(); + } + else if (CollisionBounds != null) + { + name = CollisionBounds.GetName(); + } + if (Geometry != null) + { + name += " (" + GeometryIndex.ToString() + ")"; + } + if (TimeCycleModifier != null) + { + name = TimeCycleModifier.CTimeCycleModifier.name.ToString(); + } + if (CarGenerator != null) + { + name = CarGenerator.NameString(); + } + if (EntityExtension != null) + { + name += ": " + EntityExtension.Name; + } + if (ArchetypeExtension != null) + { + name += ": " + ArchetypeExtension.Name; + } + if (WaterQuad != null) + { + name = "WaterQuad " + WaterQuad.ToString(); + } + if (NavPoly != null) + { + name = "NavPoly " + NavPoly.ToString(); + } + if (PathNode != null) + { + name = "PathNode " + PathNode.AreaID.ToString() + "." + PathNode.NodeID.ToString();// + FloatUtil.GetVector3String(PathNode.Position); + } + if (TrainTrackNode != null) + { + name = "TrainTrackNode " + FloatUtil.GetVector3String(TrainTrackNode.Position); + } + if (ScenarioNode != null) + { + name = ScenarioNode.ToString(); + } + if (Audio != null) + { + name = Audio.ShortTypeName + " " + Audio.GetNameString();// + FloatUtil.GetVector3String(Audio.InnerPos); + } + return name; + } + + + + public bool CanShowWidget + { + get + { + bool res = false; + + if (MultipleSelection) + { + res = true; + } + else if (EntityDef != null) + { + res = true; + } + else if (CarGenerator != null) + { + res = true; + } + else if (NavPoly != null) + { + res = true; + } + else if (PathNode != null) + { + res = true; + } + else if (TrainTrackNode != null) + { + res = true; + } + else if (ScenarioNode != null) + { + res = true; + } + else if (Audio != null) + { + res = true; + } + return res; + } + } + public Vector3 WidgetPosition + { + get + { + if (MultipleSelection) + { + return MultipleSelectionCenter; + } + else if (EntityDef != null) + { + return EntityDef.WidgetPosition; + } + else if (CarGenerator != null) + { + return CarGenerator.Position; + } + else if (NavPoly != null) + { + return NavPoly.Position; + } + else if (PathNode != null) + { + return PathNode.Position; + } + else if (TrainTrackNode != null) + { + return TrainTrackNode.Position; + } + else if (ScenarioNode != null) + { + return ScenarioNode.Position; + } + else if (Audio != null) + { + return Audio.InnerPos; + } + return Vector3.Zero; + } + } + public Quaternion WidgetRotation + { + get + { + if (MultipleSelection) + { + return Quaternion.Identity; + } + else if (EntityDef != null) + { + return EntityDef.WidgetOrientation; + } + else if (CarGenerator != null) + { + return CarGenerator.Orientation; + } + else if (NavPoly != null) + { + return Quaternion.Identity; + } + else if (PathNode != null) + { + return Quaternion.Identity; + } + else if (TrainTrackNode != null) + { + return Quaternion.Identity; + } + else if (ScenarioNode != null) + { + return ScenarioNode.Orientation; + } + else if (Audio != null) + { + return Audio.Orientation; + } + return Quaternion.Identity; + } + } + public WidgetAxis WidgetRotationAxes + { + get + { + if (MultipleSelection) + { + return WidgetAxis.XYZ; + } + else if (EntityDef != null) + { + return WidgetAxis.XYZ; + } + else if (CarGenerator != null) + { + return WidgetAxis.Z; + } + else if (NavPoly != null) + { + return WidgetAxis.XYZ; + } + else if (PathNode != null) + { + return WidgetAxis.None; + } + else if (TrainTrackNode != null) + { + return WidgetAxis.None; + } + else if (ScenarioNode != null) + { + return WidgetAxis.Z; + } + else if (Audio != null) + { + return WidgetAxis.XYZ; + } + return WidgetAxis.None; + } + } + public Vector3 WidgetScale + { + get + { + if (MultipleSelection) + { + return Vector3.One; + } + else if (EntityDef != null) + { + return EntityDef.Scale; + } + else if (CarGenerator != null) + { + return new Vector3(CarGenerator.CCarGen.perpendicularLength); + } + else if (NavPoly != null) + { + return Vector3.One; + } + else if (PathNode != null) + { + return Vector3.One; + } + else if (TrainTrackNode != null) + { + return Vector3.One; + } + else if (ScenarioNode != null) + { + return Vector3.One; + } + else if (Audio != null) + { + return Vector3.One; + } + return Vector3.One; + } + } + + + + + public void SetPosition(Vector3 newpos, Vector3 oldpos, bool editPivot) + { + if (MultipleSelection) + { + //don't do anything here for multiselection + } + else if (EntityDef != null) + { + if (editPivot) + { + EntityDef.SetPivotPositionFromWidget(newpos); + } + else + { + EntityDef.SetPositionFromWidget(newpos); + } + } + else if (CarGenerator != null) + { + CarGenerator.SetPosition(newpos); + } + else if (PathNode != null) + { + PathNode.SetPosition(newpos); + } + else if (NavPoly != null) + { + //NavPoly.SetPosition(newpos); + + //if (projectForm != null) + //{ + // projectForm.OnWorldNavPolyModified(NavPoly); + //} + } + else if (TrainTrackNode != null) + { + TrainTrackNode.SetPosition(newpos); + } + else if (ScenarioNode != null) + { + ScenarioNode.SetPosition(newpos); + } + else if (Audio != null) + { + Audio.SetPosition(newpos); + } + + } + public void SetRotation(Quaternion newrot, Quaternion oldrot, bool editPivot) + { + if (EntityDef != null) + { + if (editPivot) + { + EntityDef.SetPivotOrientationFromWidget(newrot); + } + else + { + EntityDef.SetOrientationFromWidget(newrot); + } + } + else if (CarGenerator != null) + { + CarGenerator.SetOrientation(newrot); + } + else if (ScenarioNode != null) + { + ScenarioNode.SetOrientation(newrot); + } + else if (Audio != null) + { + Audio.SetOrientation(newrot); + } + } + public void SetScale(Vector3 newscale, Vector3 oldscale, bool editPivot) + { + if (EntityDef != null) + { + EntityDef.SetScale(newscale); + } + else if (CarGenerator != null) + { + CarGenerator.SetScale(newscale); + AABB = new BoundingBox(CarGenerator.BBMin, CarGenerator.BBMax); + } + } + + + public override string ToString() + { + return GetFullNameString("[Empty]"); + } + } + + public enum MapSelectionMode + { + None = 0, + Entity = 1, + EntityExtension = 2, + ArchetypeExtension = 3, + TimeCycleModifier = 4, + CarGenerator = 5, + Grass = 6, + WaterQuad = 7, + Collision = 8, + NavMesh = 9, + Path = 10, + TrainTrack = 11, + DistantLodLights = 12, + MloInstance = 13, + Scenario = 14, + PopZone = 15, + Audio = 16, + } + + + + + + + +} \ No newline at end of file diff --git a/World/Space.cs b/World/Space.cs index 9a5ac89..96408d6 100644 --- a/World/Space.cs +++ b/World/Space.cs @@ -761,6 +761,8 @@ namespace CodeWalker.World if (!Inited) return; if (Grid == null) return; + if (elapsed > 0.1f) elapsed = 0.1f; + Collisions.Clear(); diff --git a/WorldForm.Designer.cs b/WorldForm.Designer.cs index ebf3030..c824bda 100644 --- a/WorldForm.Designer.cs +++ b/WorldForm.Designer.cs @@ -145,6 +145,7 @@ namespace CodeWalker this.WaitForChildrenCheckBox = new System.Windows.Forms.CheckBox(); this.label14 = new System.Windows.Forms.Label(); this.tabPage9 = new System.Windows.Forms.TabPage(); + this.SkeletonsCheckBox = new System.Windows.Forms.CheckBox(); this.AudioOuterBoundsCheckBox = new System.Windows.Forms.CheckBox(); this.PopZonesCheckBox = new System.Windows.Forms.CheckBox(); this.NavMeshesCheckBox = new System.Windows.Forms.CheckBox(); @@ -1746,6 +1747,7 @@ namespace CodeWalker // // tabPage9 // + this.tabPage9.Controls.Add(this.SkeletonsCheckBox); this.tabPage9.Controls.Add(this.AudioOuterBoundsCheckBox); this.tabPage9.Controls.Add(this.PopZonesCheckBox); this.tabPage9.Controls.Add(this.NavMeshesCheckBox); @@ -1774,15 +1776,26 @@ namespace CodeWalker this.tabPage9.Text = "Helpers"; this.tabPage9.UseVisualStyleBackColor = true; // + // SkeletonsCheckBox + // + this.SkeletonsCheckBox.AutoSize = true; + this.SkeletonsCheckBox.Location = new System.Drawing.Point(10, 411); + this.SkeletonsCheckBox.Name = "SkeletonsCheckBox"; + this.SkeletonsCheckBox.Size = new System.Drawing.Size(101, 17); + this.SkeletonsCheckBox.TabIndex = 53; + this.SkeletonsCheckBox.Text = "Show skeletons"; + this.SkeletonsCheckBox.UseVisualStyleBackColor = true; + this.SkeletonsCheckBox.CheckedChanged += new System.EventHandler(this.SkeletonsCheckBox_CheckedChanged); + // // AudioOuterBoundsCheckBox // this.AudioOuterBoundsCheckBox.AutoSize = true; this.AudioOuterBoundsCheckBox.Checked = true; this.AudioOuterBoundsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.AudioOuterBoundsCheckBox.Location = new System.Drawing.Point(10, 434); + this.AudioOuterBoundsCheckBox.Location = new System.Drawing.Point(10, 457); this.AudioOuterBoundsCheckBox.Name = "AudioOuterBoundsCheckBox"; this.AudioOuterBoundsCheckBox.Size = new System.Drawing.Size(147, 17); - this.AudioOuterBoundsCheckBox.TabIndex = 54; + this.AudioOuterBoundsCheckBox.TabIndex = 55; this.AudioOuterBoundsCheckBox.Text = "Show audio outer bounds"; this.AudioOuterBoundsCheckBox.UseVisualStyleBackColor = true; this.AudioOuterBoundsCheckBox.CheckedChanged += new System.EventHandler(this.AudioOuterBoundsCheckBox_CheckedChanged); @@ -1823,10 +1836,10 @@ namespace CodeWalker // PathsDepthClipCheckBox // this.PathsDepthClipCheckBox.AutoSize = true; - this.PathsDepthClipCheckBox.Location = new System.Drawing.Point(10, 411); + this.PathsDepthClipCheckBox.Location = new System.Drawing.Point(10, 434); this.PathsDepthClipCheckBox.Name = "PathsDepthClipCheckBox"; this.PathsDepthClipCheckBox.Size = new System.Drawing.Size(102, 17); - this.PathsDepthClipCheckBox.TabIndex = 53; + this.PathsDepthClipCheckBox.TabIndex = 54; this.PathsDepthClipCheckBox.Text = "Paths depth clip"; this.PathsDepthClipCheckBox.UseVisualStyleBackColor = true; this.PathsDepthClipCheckBox.CheckedChanged += new System.EventHandler(this.PathsDepthClipCheckBox_CheckedChanged); @@ -2489,7 +2502,7 @@ namespace CodeWalker this.ToolsMenuExtractShaders, this.ToolsMenuOptions}); this.ToolsMenu.Name = "ToolsMenu"; - this.ToolsMenu.Size = new System.Drawing.Size(166, 312); + this.ToolsMenu.Size = new System.Drawing.Size(166, 290); // // ToolsMenuRPFBrowser // @@ -3475,5 +3488,6 @@ namespace CodeWalker private System.Windows.Forms.CheckBox PopZonesCheckBox; private System.Windows.Forms.ToolStripMenuItem ToolbarSelectAudioButton; private System.Windows.Forms.CheckBox AudioOuterBoundsCheckBox; + private System.Windows.Forms.CheckBox SkeletonsCheckBox; } } \ No newline at end of file diff --git a/WorldForm.cs b/WorldForm.cs index 85b76c8..8cfa760 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -1,46 +1,29 @@ -using CodeWalker.GameFiles; -using CodeWalker.Properties; -using SharpDX.Direct3D11; -using SharpDX.DXGI; -using System; +using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; -using CodeWalker.Rendering; -using Device = SharpDX.Direct3D11.Device; -using Buffer = SharpDX.Direct3D11.Buffer; -using DriverType = SharpDX.Direct3D.DriverType; -using System.Runtime.InteropServices; -using System.Collections.Concurrent; -using CodeWalker.World; using System.Diagnostics; using SharpDX; -using CodeWalker.Utils; -using System.Globalization; -using CodeWalker.Project; -using System.Collections.Specialized; using SharpDX.XInput; +using Device = SharpDX.Direct3D11.Device; +using DeviceContext = SharpDX.Direct3D11.DeviceContext; +using CodeWalker.World; +using CodeWalker.Project; +using CodeWalker.Rendering; +using CodeWalker.GameFiles; +using CodeWalker.Properties; namespace CodeWalker { public partial class WorldForm : 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; + private Renderer Renderer = null; + public object RenderSyncRoot { get { return Renderer.RenderSyncRoot; } } volatile bool formopen = false; volatile bool running = false; @@ -48,11 +31,11 @@ namespace CodeWalker volatile bool initialised = false; Stopwatch frametimer = new Stopwatch(); - Camera camera = new Camera(); Space space = new Space(); - Timecycle timecycle = new Timecycle(); - Weather weather = new Weather(); - Clouds clouds = new Clouds(); + Camera camera; + Timecycle timecycle; + Weather weather; + Clouds clouds; Water water = new Water(); Trains trains = new Trains(); Scenarios scenarios = new Scenarios(); @@ -72,20 +55,12 @@ namespace CodeWalker int startupviewmode = 0; //0=world, 1=ymap, 2=model string modelname = "dt1_tc_dufo_core";//"dt1_11_fount_decal";// string[] ymaplist; - bool rendertimedents = Settings.Default.ShowTimedEntities; - bool rendertimedentsalways = false; - bool renderinteriors = true; - bool renderproxies = false; - bool renderchildents = false; + Vector3 prevworldpos = new Vector3(0, 0, 100); //also the start pos - bool usedynamiclod = Settings.Default.DynamicLOD; - float lodthreshold = 50.0f / (0.1f + (float)Settings.Default.DetailDist); //to match formula for the DetailTrackBar value - bool waitforchildrentoload = true; public GameFileCache GameFileCache { get { return gameFileCache; } } GameFileCache gameFileCache = new GameFileCache(); - RenderableCache renderableCache = new RenderableCache(); WorldControlMode ControlMode = WorldControlMode.Free; @@ -101,15 +76,8 @@ namespace CodeWalker Entity camEntity = new Entity(); PedEntity pedEntity = new PedEntity(); - 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; @@ -124,53 +92,25 @@ namespace CodeWalker List SortedMarkers = new List(); List MarkerBatch = new List(); bool RenderLocator = false; - bool markerdepthclip = Settings.Default.MarkerDepthClip; object markersyncroot = new object(); object markersortedsyncroot = new object(); - UnitQuad markerquad = null; - - BoundsShaderMode boundsmode = BoundsShaderMode.None; - bool renderboundsclip = Settings.Default.BoundsDepthClip; - float renderboundsmaxrad = 20000.0f; - float renderboundsmaxdist = 10000.0f; - List BoundingBoxes = new List(); - List BoundingSpheres = new List(); - List HilightSpheres = new List(); - List HilightBoxes = new List(); - List SelectionBoxes = new List(); - List WhiteBoxes = new List(); - List SelectionSpheres = new List(); - List WhiteSpheres = new List(); - bool controllightdir = false; //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 rendercollisionmeshes = Settings.Default.ShowCollisionMeshes; List collisionitems = new List(); int collisionmeshrange = Settings.Default.CollisionMeshRange; bool[] collisionmeshlayers = { true, true, true }; - bool collisionmeshlayerdrawable = true; - List renderworldentities = new List(); - List renderworldrenderables = new List(); Dictionary renderworldVisibleYmapDict = new Dictionary(); - Dictionary renderworldHideFlags = new Dictionary(); - Unk_1264241711 renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD; - float renderworldLodDistMult = 1.0f; - float renderworldDetailDistMult = 1.0f; bool worldymaptimefilter = true; bool worldymapweatherfilter = true; - bool rendergrass = true; - bool renderdistlodlights = true; - bool rendernaturalambientlight = true; - bool renderartificialambientlight = true; - ShaderGlobalLights globalLights = new ShaderGlobalLights(); - bool renderpathbounds = true; bool renderpaths = false; List renderpathynds = new List(); @@ -194,22 +134,10 @@ namespace CodeWalker bool renderaudioouterbounds = true; - 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 MapViewEnabled = false; - float MapViewDetail = 1.0f; int MapViewDragX = 0; int MapViewDragY = 0; - bool ShowScriptedYmaps = true; bool MouseSelectEnabled = false; bool ShowSelectionBounds = true; @@ -227,20 +155,12 @@ namespace CodeWalker MapSelection SelectedItem; List SelectedItems = new List(); WorldInfoForm InfoForm = null; - Dictionary SelectionModelDrawFlags = new Dictionary(); - Dictionary SelectionGeometryDrawFlags = new Dictionary(); - List SelectionLineVerts = new List(); - List SelectionTriVerts = new List(); - - YmapEntityDef SelectedCarGenEntity = new YmapEntityDef(); TransformWidget Widget = new TransformWidget(); TransformWidget GrabbedWidget = null; bool ShowWidget = true; - bool CtrlPressed = false; - bool ShiftPressed = false; ProjectForm ProjectForm = null; @@ -263,14 +183,8 @@ namespace CodeWalker WorldSearchForm SearchForm = null; - 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; + + InputManager Input = new InputManager(); @@ -281,11 +195,6 @@ namespace CodeWalker int toolsPanelResizeStartLeft = 0; int toolsPanelResizeStartRight = 0; - double currentRealTime = 0; - int framecount = 0; - float fcelapsed = 0.0f; - int fps = 0; - bool initedOk = false; @@ -293,7 +202,13 @@ namespace CodeWalker { InitializeComponent(); - initedOk = dxman.Init(this, false); + Renderer = new Renderer(this, gameFileCache); + camera = Renderer.camera; + timecycle = Renderer.timecycle; + weather = Renderer.weather; + clouds = Renderer.clouds; + + initedOk = Renderer.Init(); } @@ -397,36 +312,13 @@ namespace CodeWalker UpdateToolbarShortcutsText(); - InitController(); + + Input.Init(); - dxman.Start(); + Renderer.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; - } - - } private MapIcon AddIcon(string name, string filename, int texw, int texh, float centerx, float centery, float scale) @@ -450,15 +342,12 @@ namespace CodeWalker 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 + Renderer.DeviceCreated(device, width, height); } catch (Exception ex) { @@ -466,7 +355,6 @@ namespace CodeWalker return; } - if (Icons != null) { foreach (MapIcon icon in Icons) @@ -475,14 +363,9 @@ namespace CodeWalker } } - markerquad = new UnitQuad(device); - - renderableCache.OnDeviceCreated(device); - - camera.OnWindowResize(width, height); //init the projection stuff camera.FollowEntity = camEntity; - camera.FollowEntity.Position = (startupviewmode!=2) ? prevworldpos : Vector3.Zero;// new Vector3(0.0f, 0.0f, 100.0f); - camera.FollowEntity.Orientation = Quaternion.LookAtLH(Vector3.Zero, Vector3.Up, Vector3.ForwardLH); + camEntity.Position = (startupviewmode!=2) ? prevworldpos : Vector3.Zero; + camEntity.Orientation = Quaternion.LookAtLH(Vector3.Zero, Vector3.Up, Vector3.ForwardLH); space.AddPersistentEntity(pedEntity); @@ -499,10 +382,7 @@ namespace CodeWalker { formopen = false; - renderableCache.OnDeviceDestroyed(); - - shaders.Dispose(); - + Renderer.DeviceDestroyed(); if (Icons != null) { @@ -512,123 +392,84 @@ namespace CodeWalker } } - markerquad.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); - } + Renderer.BuffersResized(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)) + if (!Monitor.TryEnter(Renderer.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(); - space.Update(elapsed); - camera.SetMousePosition(MouseLastPoint.X, MouseLastPoint.Y); - camera.Update(elapsed); + + Renderer.Update(elapsed, MouseLastPoint.X, MouseLastPoint.Y); + + UpdateWidgets(); - WhiteBoxes.Clear(); - WhiteSpheres.Clear(); - SelectionBoxes.Clear(); - SelectionSpheres.Clear(); - HilightBoxes.Clear(); - HilightSpheres.Clear(); - BoundingBoxes.Clear(); - BoundingSpheres.Clear(); BeginMouseHitTest(); - dxman.ClearRenderTarget(context); - shaders.BeginFrame(context, currentRealTime, elapsed); - shaders.EnsureShaderTextures(gameFileCache, renderableCache); + Renderer.BeginRender(context); - RenderSky(context); + Renderer.RenderSkyAndClouds(); - RenderClouds(context); + Renderer.SelectedDrawable = SelectedItem.Drawable; - shaders.ClearDepth(context); - - if (renderworld || rendermaps) + if (renderworld) { RenderWorld(); - - if (rendermaps) - { - RenderYmaps(); - } + } + else if (rendermaps) + { + RenderYmaps(); } else { RenderSingleItem(); } + UpdateMouseHitsFromRenderer(); + RenderSelection(); - shaders.RenderQueued(context, camera, currentWindVec); + Renderer.RenderQueued(); - RenderBounds(context); + Renderer.RenderBounds(SelectionMode); - RenderSelectionGeometry(context); + Renderer.RenderSelectionGeometry(SelectionMode); - RenderMoused(context); + RenderMoused(); - shaders.RenderFinalPass(context); + Renderer.RenderFinalPass(); - RenderMarkers(context); + RenderMarkers(); - RenderWidgets(context); + RenderWidgets(); - renderableCache.RenderThreadSync(); + Renderer.EndRender(); - Monitor.Exit(rendersyncroot); + Monitor.Exit(Renderer.RenderSyncRoot); UpdateMarkerSelectionPanelInvoke(); } @@ -644,218 +485,20 @@ namespace CodeWalker TimeOfDayLabel.Text = string.Format("{0:00}:{1:00}", ih, im); } - private void UpdateTimeOfDay(float elapsed) - { - if (timerunning) - { - 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); - } - - } - - 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; - - if (controllightdir) - { - 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 != null) && (weather.Inited)) - { - lightdircolour *= weather.CurrentValues.skyHdr; - lightdircolour.Alpha = 1.0f; - lightdirambcolour *= weather.CurrentValues.skyHdr; - lightdirambcolour.Alpha = 1.0f; - hdrint = weather.CurrentValues.skyHdr; - } - sundir = lightdir; - moondir = -lightdir; - } - 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; - - lightdir = sundir; - - //if (lightdir.Z < -0.5f) lightdir.Z = -lightdir.Z; //make sure the lightsource is always above the horizon... - - if ((timeofday < 5.0f) || (timeofday > 21.0f)) - { - lightdir = moondir; - //usemoon = true; - } - - if (lightdir.Z < 0) - { - lightdir.Z = 0; //don't let the light source go below the horizon... - } - - //lightdir = Vector3.Normalize(weather.CurrentValues.sunDirection); - - if (weather != null && weather.Inited) - { - 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) - { - 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); - } - else - { - hdrint = weather.CurrentValues.skyHdr;//.lightDirCol.W; - } - } - - - } - - globalLights.Weather = weather; - globalLights.HdrEnabled = hdr; - globalLights.SpecularEnabled = !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; - - - if (shaders != null) - { - shaders.SetGlobalLightParams(globalLights); - } - - } - - private void UpdateWindVector(float elapsed) - { - //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; - - 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; - - currentWindVec.Z = (float)Math.Sin(dirval) * dirval1 + (float)Math.Cos(dirval2) * dirval4; - currentWindVec.W = (float)Math.Cos(dirval) * dirval5 + (float)Math.Sin(dirval3) * dirval4; - - 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)); - - 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); - } - private void UpdateControlInputs(float elapsed) { + if (elapsed > 0.1f) elapsed = 0.1f; + var s = Settings.Default; float moveSpeed = 50.0f; - bool xbenable = (xbcontroller != null) && (xbcontroller.IsConnected); - float lx = 0, ly = 0, rx = 0, ry = 0, lt = 0, rt = 0; //input axes - if (xbenable) - { - 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; - if (ControllerButtonJustPressed(GamepadButtonFlags.Start)) + Input.Update(elapsed); + + if (Input.xbenable) + { + if (Input.ControllerButtonJustPressed(GamepadButtonFlags.Start)) { SetControlMode(ControlMode == WorldControlMode.Free ? WorldControlMode.Ped : WorldControlMode.Free); } @@ -864,28 +507,21 @@ namespace CodeWalker if (ControlMode == WorldControlMode.Free) { - - Vector3 movevec = Vector3.Zero; - if (ShiftPressed) + if (Input.ShiftPressed) { moveSpeed *= 5.0f; } - if (CtrlPressed) + if (Input.CtrlPressed) { moveSpeed *= 0.2f; } + Vector3 movevec = Input.KeyboardMoveVec(MapViewEnabled); + if (MapViewEnabled) { - 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 * moveSpeed * Math.Min(camera.OrthographicTargetSize * 0.01f, 50.0f); - float mapviewscale = 1.0f / camera.Height; float fdx = MapViewDragX * mapviewscale; float fdy = MapViewDragY * mapviewscale; @@ -896,12 +532,6 @@ namespace CodeWalker else { //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, 20.0f); } @@ -915,39 +545,39 @@ namespace CodeWalker - if (xbenable) + if (Input.xbenable) { - camera.ControllerRotate(lx + rx, ly + ry); + camera.ControllerRotate(Input.xblx + Input.xbrx, Input.xbly + Input.xbry); float zoom = 0.0f; float zoomspd = s.XInputZoomSpeed; float zoomamt = zoomspd * elapsed; - if (ControllerButtonPressed(GamepadButtonFlags.DPadUp)) zoom += zoomamt; - if (ControllerButtonPressed(GamepadButtonFlags.DPadDown)) zoom -= zoomamt; + if (Input.ControllerButtonPressed(GamepadButtonFlags.DPadUp)) zoom += zoomamt; + if (Input.ControllerButtonPressed(GamepadButtonFlags.DPadDown)) zoom -= zoomamt; camera.ControllerZoom(zoom); float acc = 0.0f; float accspd = s.XInputMoveSpeed;//actually accel speed... - acc += rt * accspd; - acc -= lt * accspd; + acc += Input.xbrt * accspd; + acc -= Input.xblt * accspd; Vector3 newdir = camera.ViewDirection; //maybe use the "vehicle" direction...? - xbcontrolvelocity += (acc * elapsed); + Input.xbcontrolvelocity += (acc * elapsed); - if (ControllerButtonPressed(GamepadButtonFlags.A | GamepadButtonFlags.RightShoulder)) //handbrake... + if (Input.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; + Input.xbcontrolvelocity *= Math.Max(0.75f - elapsed, 0);//not ideal for low fps... + //Input.xbcontrolvelocity = 0.0f; + if (Math.Abs(Input.xbcontrolvelocity) < 0.001f) Input.xbcontrolvelocity = 0.0f; } - camEntity.Velocity = newdir * xbcontrolvelocity; + camEntity.Velocity = newdir * Input.xbcontrolvelocity; camEntity.Position += camEntity.Velocity * elapsed; //fire! - if (ControllerButtonJustPressed(GamepadButtonFlags.LeftShoulder)) + if (Input.ControllerButtonJustPressed(GamepadButtonFlags.LeftShoulder)) { SpawnTestEntity(true); } @@ -984,18 +614,18 @@ namespace CodeWalker camera.MouseRotate(mcx, mcy); - if (xbenable) + if (Input.xbenable) { - camera.ControllerRotate(rx, ry); + camera.ControllerRotate(Input.xbrx, Input.xbry); } - Vector2 movecontrol = new Vector2(xbmainaxes.X, xbmainaxes.Y); //(L stick) - if (kbmovelft) movecontrol.X -= 1.0f; - if (kbmovergt) movecontrol.X += 1.0f; - if (kbmovefwd) movecontrol.Y += 1.0f; - if (kbmovebck) movecontrol.Y -= 1.0f; + Vector2 movecontrol = new Vector2(Input.xbmainaxes.X, Input.xbmainaxes.Y); //(L stick) + if (Input.kbmovelft) movecontrol.X -= 1.0f; + if (Input.kbmovergt) movecontrol.X += 1.0f; + if (Input.kbmovefwd) movecontrol.Y += 1.0f; + if (Input.kbmovebck) movecontrol.Y -= 1.0f; movecontrol.X = Math.Min(movecontrol.X, 1.0f); movecontrol.X = Math.Max(movecontrol.X, -1.0f); movecontrol.Y = Math.Min(movecontrol.Y, 1.0f); @@ -1009,8 +639,8 @@ namespace CodeWalker pedEntity.ControlMovement = movexy; - pedEntity.ControlJump = kbjump || ControllerButtonPressed(GamepadButtonFlags.X); - pedEntity.ControlBoost = ShiftPressed || ControllerButtonPressed(GamepadButtonFlags.A | GamepadButtonFlags.RightShoulder | GamepadButtonFlags.LeftShoulder); + pedEntity.ControlJump = Input.kbjump || Input.ControllerButtonPressed(GamepadButtonFlags.X); + pedEntity.ControlBoost = Input.ShiftPressed || Input.ControllerButtonPressed(GamepadButtonFlags.A | GamepadButtonFlags.RightShoulder | GamepadButtonFlags.LeftShoulder); //Vector3 pedfwd = pedEntity.Orientation.Multiply(Vector3.UnitZ); @@ -1020,7 +650,7 @@ namespace CodeWalker - bool fire = mlb || (xbtrigs.Y > 0); + bool fire = mlb || (Input.xbtrigs.Y > 0); if (fire && !ControlFireToggle) { SpawnTestEntity(true); @@ -1033,496 +663,7 @@ namespace CodeWalker } - private Vector4 ControllerMainAxes() - { - 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); - 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; - - 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)); - } - - - - private DrawableBase TryGetDrawable(Archetype arche) - { - if (arche == null) return null; - uint drawhash = arche.Hash; - DrawableBase drawable = null; - if ((arche.DrawableDict != 0))// && (arche.DrawableDict != arche.Hash)) - { - //try get drawable from ydd... - YddFile ydd = gameFileCache.GetYdd(arche.DrawableDict); - if (ydd != null) - { - 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? - } - } - if (drawable == null) - { - //try get drawable from ydr. - YdrFile ydr = gameFileCache.GetYdr(drawhash); - if (ydr != null) - { - if (ydr.Loaded) - { - drawable = ydr.Drawable; - } - } - else - { - YftFile yft = gameFileCache.GetYft(drawhash); - if (yft != null) - { - if (yft.Loaded) - { - if (yft.Fragment != null) - { - drawable = yft.Fragment.Drawable; - } - } - } - } - } - - return drawable; - } - - 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; - - Renderable rndbl = renderableCache.GetRenderable(drawable); - if (rndbl == null) return null; - - if (clipDict != 0) - { - YcdFile ycd = gameFileCache.GetYcd(clipDict); - if ((ycd != null) && (ycd.Loaded)) - { - MetaHash ahash = arche.Hash; - MetaHash ahashuv1 = ahash + 1; - MetaHash ahashuv2 = ahash + 2; - ClipMapEntry cme, cmeuv1, cmeuv2; //this goes to at least uv5! (from uv0) - see hw1_09.ycd - bool found = false; - if (ycd.ClipMap.TryGetValue(ahash, out cme)) - { - found = true; - } - if (ycd.ClipMap.TryGetValue(ahashuv1, out cmeuv1)) - { - found = true; - } - if (ycd.ClipMap.TryGetValue(ahashuv2, out cmeuv2)) - { - found = true; - } - if (!found) - { - } - } - } - - - bool alltexsloaded = true; - int missingtexcount = 0; - for (int mi = 0; mi < rndbl.HDModels.Length; mi++) - { - var model = rndbl.HDModels[mi]; - - //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 (texDict != 0) - { - YtdFile ytd = gameFileCache.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... - var ytd2 = gameFileCache.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 = gameFileCache.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) - { - var ytd2 = gameFileCache.TryGetTextureDictForTexture(tex.NameHash); - if ((ytd2 != null) && (ytd2.Loaded) && (ytd2.TextureDict != null)) - { - dtex = ytd2.TextureDict.Lookup(tex.NameHash); - } - if (dtex == null) - { - dtex = gameFileCache.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.. - { - var ytd2 = gameFileCache.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 bool LodDistTest(ref Vector3 p, ref Vector3 min, ref Vector3 max, float lodDist) - { - //for AABB only! for oriented BBs p must be transformed first... - if (p.X < (min.X - lodDist)) return false; - if (p.X > (max.X + lodDist)) return false; - if (p.Y < (min.Y - lodDist)) return false; - if (p.Y > (max.Y + lodDist)) return false; - if (p.Z < (min.Z - lodDist)) return false; - if (p.Z > (max.Z + lodDist)) return false; - return true; - } - private bool LodDistTest(Vector3 p, Vector3 min, Vector3 max, float lodDist) - { - //for AABB only! for oriented BBs p must be transformed first... - if (p.X < (min.X - lodDist)) return false; - if (p.X > (max.X + lodDist)) return false; - if (p.Y < (min.Y - lodDist)) return false; - if (p.Y > (max.Y + lodDist)) return false; - if (p.Z < (min.Z - lodDist)) return false; - if (p.Z > (max.Z + lodDist)) return false; - return true; - } - - - - private void RenderSky(DeviceContext context) - { - if (MapViewEnabled) return; - 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 (MapViewEnabled) return; - 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.ToLowerInvariant()); - 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 RenderWorld() @@ -1530,25 +671,19 @@ namespace CodeWalker //start point for world view mode rendering. //also used for the water, paths, collisions, nav mesh, and the project window items. - renderworldentities.Clear(); - renderworldrenderables.Clear(); renderworldVisibleYmapDict.Clear(); - renderworldHideFlags.Clear(); - int hour = worldymaptimefilter ? (int)timeofday : -1; + int hour = worldymaptimefilter ? (int)Renderer.timeofday : -1; MetaHash weathertype = worldymapweatherfilter ? ((weather.CurrentWeatherType != null) ? weather.CurrentWeatherType.NameHash : new MetaHash(0)) : new MetaHash(0); + IEnumerable spaceEnts = null; + if (renderworld) { space.GetVisibleYmaps(camera, hour, weathertype, renderworldVisibleYmapDict); - foreach (var ae in space.TemporaryEntities) - { - if (ae.EntityDef == null) continue; //nothing to render... - RenderWorldCalcEntityVisibility(camera, ae.EntityDef); - renderworldentities.Add(ae.EntityDef); - } + spaceEnts = space.TemporaryEntities; } if (ProjectForm != null) @@ -1556,211 +691,16 @@ namespace CodeWalker ProjectForm.GetVisibleYmaps(camera, renderworldVisibleYmapDict); } - //float minZ = float.MaxValue; - float maxZ = float.MinValue; - float cvwidth = camera.OrthographicSize * camera.AspectRatio*0.5f; - float cvheight = camera.OrthographicSize*0.5f; - float cvwmin = camera.Position.X - cvwidth; - float cvwmax = camera.Position.X + cvwidth; - float cvhmin = camera.Position.Y - cvheight; - float cvhmax = camera.Position.Y + cvheight; - foreach (var ymap in renderworldVisibleYmapDict.Values) + Renderer.RenderWorld(renderworldVisibleYmapDict, spaceEnts); + + + foreach (var ymap in Renderer.VisibleYmaps) { - if (!RenderWorldYmapIsVisible(ymap)) continue; - if (ymap.AllEntities != null) - { - for (int i = 0; i < ymap.AllEntities.Length; i++) - { - var ent = ymap.AllEntities[i]; - ent.LargestChildLodDist = 0; - ent.ChildrenLoading = false; - ent.Rendered = false; - ent.ChildRendered = false; - if (MapViewEnabled) - { - //find the max Z value for positioning camera in map view, to help shadows - if ((ent.Position.Z<1000.0f)&&(ent.BSRadius < 500.0f)) - { - float r = ent.BSRadius; - if (((ent.Position.X + r) > cvwmin) && ((ent.Position.X - r) < cvwmax) && ((ent.Position.Y + r) > cvhmin) && ((ent.Position.Y - r) < cvhmax)) - { - //minZ = Math.Min(minZ, ent.BBMin.Z); - maxZ = Math.Max(maxZ, ent.BBMax.Z+50.0f);//add some bias to avoid clipping things... - } - } - } - } - } - } - - if (MapViewEnabled) - { - //move the camera closer to the geometry, to help shadows in map view. - if (maxZ == float.MinValue) maxZ = 1000.0f; - camera.Position.Z = Math.Min(maxZ, 1000.0f); - } - - - foreach (var ymap in renderworldVisibleYmapDict.Values) - { - if (!RenderWorldYmapIsVisible(ymap)) continue; - if (ymap.RootEntities != null) - { - YmapFile pymap; - renderworldVisibleYmapDict.TryGetValue(ymap.CMapData.parent, out pymap); - for (int i = 0; i < ymap.RootEntities.Length; i++) - { - var ent = ymap.RootEntities[i]; - int pind = ent.CEntityDef.parentIndex; - if (pind >= 0) //connect root entities to parents if they have them.. - { - YmapEntityDef p = null; - if ((pymap != null) && (pymap.AllEntities != null)) - { - if ((pind < pymap.AllEntities.Length)) - { - p = pymap.AllEntities[pind]; - ent.Parent = p; - ent.ParentGuid = p.CEntityDef.guid; - ent.ParentName = p.CEntityDef.archetypeName; - } - } - else - { }//should only happen if parent ymap not loaded yet... - } - RenderWorldRecurseCalcEntityVisibility(camera, ent); - } - } - } - - foreach (var ymap in renderworldVisibleYmapDict.Values) - { - if (!RenderWorldYmapIsVisible(ymap)) continue; - if (ymap.RootEntities != null) - { - for (int i = 0; i < ymap.RootEntities.Length; i++) - { - var ent = ymap.RootEntities[i]; - RenderWorldRecurseAddEntities(ent, renderworldentities); - } - } - UpdateMouseHits(ymap); } - //go through the render list, and try ensure renderables and textures for all. - //if an entity is not fully loaded, set a flag for its parent, then traverse to root - //until found an entity that is fully loaded. - //on a second loop, build a final render list based on the flags. - - for (int i = 0; i < renderworldentities.Count; i++) - { - var ent = renderworldentities[i]; - var arch = ent.Archetype; - var pent = ent.Parent; - - if (renderinteriors && ent.IsMlo) //render Mlo child entities... - { - if ((ent.MloInstance != null) && (ent.MloInstance.Entities != null)) - { - for (int j = 0; j < ent.MloInstance.Entities.Length; j++) - { - var intent = ent.MloInstance.Entities[j]; - var intarch = intent.Archetype; - if (intarch == null) continue; //missing archetype... - - if (!RenderIsEntityFinalRender(intent)) continue; //proxy or something.. - - intent.CamRel = intent.Position - camera.Position; - intent.Distance = intent.CamRel.Length(); - intent.IsVisible = true; - - var bscent = intent.CamRel + intent.BSCenter; - float bsrad = intent.BSRadius; - if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref bscent, bsrad)) - { - continue; //frustum cull interior ents - } - var intdrbl = TryGetDrawable(intarch); - var intrndbl = TryGetRenderable(intarch, intdrbl); - if (intrndbl == null) continue; //no renderable - if (!(intrndbl.IsLoaded && (intrndbl.AllTexturesLoaded || !waitforchildrentoload))) continue; //not loaded yet - - RenderableEntity intrent = new RenderableEntity(); - intrent.Entity = intent; - intrent.Renderable = intrndbl; - renderworldrenderables.Add(intrent); - } - } - if (rendercollisionmeshes) - { - RenderInteriorCollisionMesh(ent); - } - } - - ent.Rendered = true; - var drawable = TryGetDrawable(arch); - Renderable rndbl = TryGetRenderable(arch, drawable); - if ((rndbl != null) && rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload)) - { - RenderableEntity rent = new RenderableEntity(); - rent.Entity = ent; - rent.Renderable = rndbl; - renderworldrenderables.Add(rent); - - if (pent != null) - { - pent.ChildRendered = true; - } - } - else if (waitforchildrentoload) - { - //todo: render parent if children loading....... - } - } - - for (int i = 0; i < renderworldrenderables.Count; i++) - { - var ent = renderworldrenderables[i].Entity; - if (ent.ChildRendered && !ent.ChildrenLoading) - { - ent.ChildrenRendered = true; - } - } - - for (int i = 0; i < renderworldrenderables.Count; i++) - { - var rent = renderworldrenderables[i]; - var ent = rent.Entity; - var arch = ent.Archetype; - - RenderArchetype(arch, ent, rent.Renderable, false); - } - - - - if (rendergrass) - { - foreach (var ymap in renderworldVisibleYmapDict.Values) - { - if (ymap.GrassInstanceBatches != null) - { - RenderYmapGrass(ymap); - } - } - } - if (renderdistlodlights && timecycle.IsNightTime) - { - foreach (var ymap in renderworldVisibleYmapDict.Values) - { - if (ymap.DistantLODLights != null) - { - RenderYmapDistantLODLights(ymap); - } - } - } if (renderwaterquads || (SelectionMode == MapSelectionMode.WaterQuad)) { @@ -1794,157 +734,25 @@ namespace CodeWalker { RenderWorldAudioZones(); } + } - private bool RenderWorldYmapIsVisible(YmapFile ymap) + + private void RenderWorldCollisionMeshes() { - if (!ShowScriptedYmaps) + //enqueue collision meshes for rendering - from the world grid + + collisionitems.Clear(); + space.GetVisibleBounds(camera, collisionmeshrange, collisionmeshlayers, collisionitems); + + foreach (var item in collisionitems) { - if ((ymap._CMapData.flags & 1) > 0) - return false; - } - - return true; - } - private void RenderWorldCalcEntityVisibility(Camera cam, YmapEntityDef ent) - { - ent.CamRel = ent.Position - cam.Position; - ent.Distance = ent.CamRel.Length(); - float distval = ent.Distance; - - if (MapViewEnabled) - { - distval = cam.OrthographicSize / MapViewDetail; - } - - - var loddist = ent.CEntityDef.lodDist; - var cloddist = ent.CEntityDef.childLodDist; - - var loddistmultdef = renderworldLodDistMult * 1.0f; - var loddistmultorph = renderworldDetailDistMult * 1.5f; - var loddistmultarch = renderworldLodDistMult * 1.0f; - - if (loddist <= 0.0f)//usually -1 or -2 - { - if (ent.Archetype != null) + YbnFile ybn = gameFileCache.GetYbn(item.Name); + if ((ybn != null) && (ybn.Loaded)) { - loddist = ent.Archetype.LodDist * loddistmultarch; - } - } - else if (ent.CEntityDef.lodLevel == Unk_1264241711.LODTYPES_DEPTH_ORPHANHD) - { - loddist *= loddistmultorph; //orphan view dist adjustment... - } - else - { - loddist *= loddistmultdef; - } - - - if (cloddist <= 0) - { - if (ent.Archetype != null) - { - cloddist = ent.Archetype.LodDist * loddistmultarch; - //cloddist = ent.Archetype.BSRadius * 50.0f; - } - } - else - { - cloddist *= loddistmultdef; - } - if (cloddist == 0) - { - //cloddist = loddist;//always try to show children, based on their loddist - } - - - ent.IsVisible = (distval <= loddist); - ent.ChildrenVisible = (distval <= cloddist) && (ent.CEntityDef.numChildren > 0); - ent.ChildrenLoading = false; - - if ((ent.Parent != null) && (ent.CEntityDef.lodLevel != Unk_1264241711.LODTYPES_DEPTH_ORPHANHD)) - { - if (ent.Parent.CEntityDef.childLodDist == 0.0f) - { - ent.Parent.LargestChildLodDist = Math.Max(ent.Parent.LargestChildLodDist, loddist); + Renderer.RenderCollisionMesh(ybn.Bounds, null); } } - if (renderworldMaxLOD != Unk_1264241711.LODTYPES_DEPTH_ORPHANHD) - { - if ((ent.CEntityDef.lodLevel == Unk_1264241711.LODTYPES_DEPTH_ORPHANHD) || - (ent.CEntityDef.lodLevel < renderworldMaxLOD)) - { - ent.IsVisible = false; - ent.ChildrenVisible = false; - } - if (ent.CEntityDef.lodLevel == renderworldMaxLOD) - { - ent.ChildrenVisible = false; - } - } - - if (!ent.IsVisible) - { - ent.ChildrenRendered = false; - } - } - private void RenderWorldRecurseCalcEntityVisibility(Camera cam, YmapEntityDef ent) - { - RenderWorldCalcEntityVisibility(cam, ent); - if (ent.ChildrenVisible) - { - if (ent.Children != null) - { - for (int i = 0; i < ent.Children.Length; i++) - { - var child = ent.Children[i]; - if (child.Ymap == ent.Ymap) - { - RenderWorldRecurseCalcEntityVisibility(cam, child); - } - } - } - } - } - private void RenderWorldRecurseAddEntities(YmapEntityDef ent, List res) - { - //bool useclod = false; //(ent.CEntityDef.childLodDist == 0.0f); - //bool hide = useclod ? (ent.AnyChildVisible /*&& !ent.AnyChildInvisible*/) : ent.ChildrenVisible; - //bool force = !useclod && (ent.Parent != null) && ent.Parent.ChildrenVisible && !hide; - bool hide = ent.ChildrenVisible; - bool force = (ent.Parent != null) && ent.Parent.ChildrenVisible && !hide; - if (force || (ent.IsVisible && !hide)) - { - if (ent.Archetype != null) - { - if (!RenderIsEntityFinalRender(ent)) return; - - var bscent = ent.CamRel + ent.BSCenter; - float bsrad = ent.BSRadius; - if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref bscent, bsrad)) - { - return; //frustum cull - } - - - res.Add(ent); - } - else - { } - } - if (ent.IsVisible && ent.ChildrenVisible && (ent.Children != null)) - { - for (int i = 0; i < ent.Children.Length; i++) - { - var child = ent.Children[i]; - if (child.Ymap == ent.Ymap) - { - RenderWorldRecurseAddEntities(ent.Children[i], res); - } - } - } } private void RenderWorldWaterQuads() @@ -1958,15 +766,7 @@ namespace CodeWalker ProjectForm.GetVisibleWaterQuads(camera, renderwaterquadlist); } - foreach (var quad in renderwaterquadlist) - { - RenderableWaterQuad rquad = renderableCache.GetRenderableWaterQuad(quad); - if ((rquad != null) && (rquad.IsLoaded)) - { - rquad.CamRel = -camera.Position; - shaders.Enqueue(rquad); - } - } + Renderer.RenderWaterQuads(renderwaterquadlist); UpdateMouseHits(renderwaterquadlist); @@ -1974,8 +774,8 @@ namespace CodeWalker private void RenderWorldPaths() { - renderpathynds.Clear(); + space.GetVisibleYnds(camera, renderpathynds); if (ProjectForm != null) @@ -1983,14 +783,7 @@ namespace CodeWalker ProjectForm.GetVisibleYnds(camera, renderpathynds); } - foreach (var ynd in renderpathynds) - { - RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(ynd); - if ((rnd != null) && (rnd.IsLoaded)) - { - shaders.Enqueue(rnd); - } - } + Renderer.RenderPaths(renderpathynds); UpdateMouseHits(renderpathynds); } @@ -2007,14 +800,7 @@ namespace CodeWalker ProjectForm.GetVisibleTrainTracks(camera, rendertraintracklist); } - foreach (var track in rendertraintracklist) - { - RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(track); - if ((rnd != null) && (rnd.IsLoaded)) - { - shaders.Enqueue(rnd); - } - } + Renderer.RenderTrainTracks(rendertraintracklist); UpdateMouseHits(rendertraintracklist); } @@ -2030,15 +816,7 @@ namespace CodeWalker //ProjectForm.GetVisibleYnvs(camera, rendernavmeshynvs); } - - foreach (var ynv in rendernavmeshynvs) - { - RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(ynv); - if ((rnd != null) && (rnd.IsLoaded)) - { - shaders.Enqueue(rnd); - } - } + Renderer.RenderNavMeshes(rendernavmeshynvs); UpdateMouseHits(rendernavmeshynvs); @@ -2057,14 +835,7 @@ namespace CodeWalker ProjectForm.GetVisibleScenarios(camera, renderscenariolist); } - foreach (var scenario in renderscenariolist) - { - RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(scenario.ScenarioRegion); - if ((rnd != null) && (rnd.IsLoaded)) - { - shaders.Enqueue(rnd); - } - } + Renderer.RenderScenarios(renderscenariolist); UpdateMouseHits(renderscenariolist); } @@ -2081,12 +852,7 @@ namespace CodeWalker //ProjectForm.GetVisiblePopZones(camera, renderpopzonelist); } - - RenderablePathBatch rnd = renderableCache.GetRenderablePathBatch(popzones); - if ((rnd != null) && (rnd.IsLoaded)) - { - shaders.Enqueue(rnd); - } + Renderer.RenderPopZones(popzones); } private void RenderWorldAudioZones() @@ -2134,7 +900,7 @@ namespace CodeWalker mb.BBMax = placement.InnerMax; mb.Orientation = placement.InnerOri; mb.Scale = Vector3.One; - HilightBoxes.Add(mb); + Renderer.HilightBoxes.Add(mb); if (renderaudioouterbounds) { @@ -2143,7 +909,7 @@ namespace CodeWalker mb.BBMax = placement.OuterMax; mb.Orientation = placement.OuterOri; mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); } Vector3 hbcamrel = (placement.Position - camera.Position); @@ -2167,13 +933,13 @@ namespace CodeWalker { ms.CamRelPos = placement.InnerPos - camera.Position; ms.Radius = placement.InnerRad; - HilightSpheres.Add(ms); + Renderer.HilightSpheres.Add(ms); if (renderaudioouterbounds) { ms.CamRelPos = placement.OuterPos - camera.Position; ms.Radius = placement.OuterRad; - BoundingSpheres.Add(ms); + Renderer.BoundingSpheres.Add(ms); } bsph.Center = placement.Position; @@ -2205,10 +971,10 @@ namespace CodeWalker { case Dat151ZoneShape.Box: case Dat151ZoneShape.Line: - HilightBoxes.Add(lastHitOuterBox); + Renderer.HilightBoxes.Add(lastHitOuterBox); break; case Dat151ZoneShape.Sphere: - HilightSpheres.Add(lastHitOuterSphere); + Renderer.HilightSpheres.Add(lastHitOuterSphere); break; } } @@ -2235,7 +1001,7 @@ namespace CodeWalker if (arche != null) { - RenderArchetype(arche, null); + Renderer.RenderArchetype(arche, null); selarch = arche; } @@ -2244,7 +1010,7 @@ namespace CodeWalker YmapFile ymap = gameFileCache.GetYmap(hash); if (ymap != null) { - RenderYmap(ymap); + Renderer.RenderYmap(ymap); } else { @@ -2254,7 +1020,7 @@ namespace CodeWalker { if (ydr.Loaded) { - RenderDrawable(ydr.Drawable, null, null, -camera.Position, hash); + Renderer.RenderDrawable(ydr.Drawable, null, null, hash); seldrwbl = ydr.Drawable; } @@ -2270,7 +1036,7 @@ namespace CodeWalker { var f = yft.Fragment; - RenderFragment(null, null, f, hash); + Renderer.RenderFragment(null, null, f, hash); seldrwbl = f.Drawable; } @@ -2288,7 +1054,7 @@ namespace CodeWalker if ((selarch != null) && (seldrwbl == null)) { - seldrwbl = TryGetDrawable(selarch); + seldrwbl = gameFileCache.TryGetDrawable(selarch); } //select this item for viewing by the UI... @@ -2312,600 +1078,9 @@ namespace CodeWalker { uint hash = JenkHash.GenHash(lod); YmapFile ymap = gameFileCache.GetYmap(hash); - RenderYmap(ymap); - } - } - private void RenderYmap(YmapFile ymap) - { - if (ymap == null) return; - if (!ymap.Loaded) return; + Renderer.RenderYmap(ymap); - UpdateMouseHits(ymap); - - if ((ymap.AllEntities != null) && (ymap.RootEntities != null)) - { - if (usedynamiclod) - { - for (int i = 0; i < ymap.RootEntities.Length; i++) - { - RenderYmapLOD(ymap.RootEntities[i].Ymap, ymap.RootEntities[i]); - } - } - else - { - var ents = renderchildents ? ymap.AllEntities : ymap.RootEntities; - for (int i = 0; i < ents.Length; i++) - { - var ent = ents[i]; - if (renderchildents && ent.Children != null) continue; - //if (rootent.CEntityDef.parentIndex == -1) continue; - Archetype arch = ent.Archetype; - if (arch != null) - { - bool timed = (arch.Type == MetaName.CTimeArchetypeDef); - if (!timed || (rendertimedents && (rendertimedentsalways || arch.IsActive(timeofday)))) - { - ent.CamRel = ent.Position - camera.Position; - RenderArchetype(arch, ent); - } - } - else - { - //couldn't find archetype... - } - } - } - } - - if (rendergrass && (ymap.GrassInstanceBatches != null)) - { - RenderYmapGrass(ymap); - } - if (renderdistlodlights && timecycle.IsNightTime && (ymap.DistantLODLights != null)) - { - RenderYmapDistantLODLights(ymap); - } - - } - private bool RenderYmapLOD(YmapFile ymap, YmapEntityDef entity) - { - if (!ymap.Loaded) return false; - - ymap.EnsureChildYmaps(gameFileCache); - - Archetype arch = entity.Archetype; - if (arch != null) - { - bool timed = (arch.Type == MetaName.CTimeArchetypeDef); - if (!timed || (rendertimedents && (rendertimedentsalways || arch.IsActive(timeofday)))) - { - bool usechild = false; - entity.CamRel = entity.Position - camera.Position; - float dist = (entity.CamRel + entity.BSCenter).Length(); - float rad = arch.BSRadius; - float loddist = entity.CEntityDef.lodDist; - if (loddist < 1.0f) - { - loddist = 200.0f; - } - float mindist = Math.Max(dist - rad, 1.0f) * lodthreshold; - if (mindist < loddist) - { - //recurse... - var children = entity.ChildrenMerged; - if ((children != null)) - { - usechild = true; - for (int i = 0; i < children.Length; i++) - { - var childe = children[i]; - if (!RenderYmapLOD(childe.Ymap, childe)) - { - if (waitforchildrentoload) - { - usechild = false; //might cause some overlapping, but should reduce things disappearing - } - } - } - } - if (!entity.ChildrenRendered) - { - entity.ChildrenRendered = usechild; - } - } - else - { - entity.ChildrenRendered = false; - } - if (!usechild && !entity.ChildrenRendered) - { - - - - if (renderinteriors && entity.IsMlo) //render Mlo child entities... - { - if ((entity.MloInstance != null) && (entity.MloInstance.Entities != null)) - { - for (int j = 0; j < entity.MloInstance.Entities.Length; j++) - { - var intent = entity.MloInstance.Entities[j]; - var intarch = intent.Archetype; - if (intarch == null) continue; //missing archetype... - - if (!RenderIsEntityFinalRender(intent)) continue; //proxy or something.. - - intent.CamRel = intent.Position - camera.Position; - intent.Distance = intent.CamRel.Length(); - intent.IsVisible = true; - - RenderArchetype(intarch, intent); - } - } - if (rendercollisionmeshes) - { - RenderInteriorCollisionMesh(entity); - } - } - - - - - return RenderArchetype(arch, entity); - } - return true; - } - - } - return false; - } - - - private void RenderYmapGrass(YmapFile ymap) - { - //enqueue ymap grass instance batches for rendering - - if (ymap.GrassInstanceBatches == null) return; - - foreach (var batch in ymap.GrassInstanceBatches) - { - batch.CamRel = batch.Position - camera.Position; - //batch.Distance = batch.CamRel.Length(); - - float lodDist = batch.Batch.lodDist * renderworldDetailDistMult;//maybe add grass dist mult - //if (batch.Distance > lodDist) continue; //too far away.. - - lodDist *= 0.75f; //reduce it just a bit to improve performance... remove this later - - float cx = camera.Position.X; - float cy = camera.Position.Y; - float cz = camera.Position.Z; - if (cx < (batch.AABBMin.X - lodDist)) continue; - if (cx > (batch.AABBMax.X + lodDist)) continue; - if (cy < (batch.AABBMin.Y - lodDist)) continue; - if (cy > (batch.AABBMax.Y + lodDist)) continue; - if (cz < (batch.AABBMin.Z - lodDist)) continue; - if (cz > (batch.AABBMax.Z + lodDist)) continue; - - - var bscent = batch.CamRel; - float bsrad = batch.Radius; - if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref bscent, bsrad)) - { - continue; //frustum cull grass batches... - } - - var arch = batch.Archetype; - var drbl = TryGetDrawable(arch); - var rndbl = TryGetRenderable(arch, drbl); - var instb = renderableCache.GetRenderableInstanceBatch(batch); - if (rndbl == null) continue; //no renderable - if (!(rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload))) continue; //not loaded yet - if ((instb == null) || !instb.IsLoaded) continue; - - RenderableInstanceBatchInst binst = new RenderableInstanceBatchInst(); - binst.Batch = instb; - binst.Renderable = rndbl; - - shaders.Enqueue(binst); - - } - - } - - private void RenderYmapDistantLODLights(YmapFile ymap) - { - //enqueue ymap DistantLODLights instance batch for rendering - - if (ymap.DistantLODLights == null) return; - - switch (ymap.DistantLODLights.CDistantLODLight.category) - { - case 0: //distlodlights_small009.ymap - case 1: //distlodlights_medium000.ymap - case 2: //distlodlights_large000.ymap - break; - default: - break; - } - - RenderableDistantLODLights lights = renderableCache.GetRenderableDistantLODLights(ymap.DistantLODLights); - if (!lights.IsLoaded) return; - - - uint ytdhash = 3154743001; //"graphics" - uint texhash = 2236244673; //"distant_light" - YtdFile graphicsytd = gameFileCache.GetYtd(ytdhash); - Texture lighttex = null; - if ((graphicsytd != null) && (graphicsytd.Loaded) && (graphicsytd.TextureDict != null) && (graphicsytd.TextureDict.Dict != null)) - { - graphicsytd.TextureDict.Dict.TryGetValue(texhash, out lighttex); //starfield hash - } - - if (lighttex == null) return; - RenderableTexture lightrtex = null; - if (lighttex != null) - { - lightrtex = renderableCache.GetRenderableTexture(lighttex); - } - if (lightrtex == null) return; - if (!lightrtex.IsLoaded) return; - - lights.Texture = lightrtex; - - shaders.Enqueue(lights); - } - - - - - private bool RenderIsEntityFinalRender(YmapEntityDef ent) - { - var arch = ent.Archetype; - bool isshadowproxy = false; - bool isreflproxy = false; - uint archflags = arch._BaseArchetypeDef.flags; - if (arch.Type == MetaName.CTimeArchetypeDef) - { - if (!(rendertimedents && (rendertimedentsalways || arch.IsActive(timeofday)))) return false; - //archflags = arch._BaseArchetypeDef.flags; - } - //else if (arch.Type == MetaName.CMloArchetypeDef) - //{ - // archflags = arch._BaseArchetypeDef.flags; - //} - ////switch (archflags) - ////{ - //// //case 8192: //8192: is YTYP no shadow rendering - CP - //// case 2048: //000000000000000000100000000000 shadow proxies... - //// case 536872960: //100000000000000000100000000000 tunnel refl/shadow prox? - //// isshadowproxy = true; break; - ////} - if ((archflags & 2048) > 0) - { - isshadowproxy = true; - } - - //if ((ent.CEntityDef.flags & 1572864) == 1572864) - //{ - // isreflproxy = true; - //} - - switch (ent._CEntityDef.flags) - { - case 135790592: //001000000110000000000000000000 prewater proxy (golf course) - case 135790593: //001000000110000000000000000001 water refl proxy? (mike house) - case 672661504: //101000000110000000000000000000 vb_ca_prop_tree_reflprox_2 - case 536870912: //100000000000000000000000000000 vb_05_emissive_mirroronly - case 35127296: //000010000110000000000000000000 tunnel refl proxy? - case 39321602: //000010010110000000000000000010 mlo reflection? - isreflproxy = true; break; - //nonproxy is: //000000000110000000000000001000 (1572872) - // //000000000110000000000000000000 - } - if (isshadowproxy || isreflproxy) - { - return renderproxies; //filter out proxy entities... - } - return true; - } - private bool RenderIsModelFinalRender(RenderableModel model) - { - - if ((model.Unk2Ch & 1) == 0) //smallest bit is proxy/"final render" bit? seems to work... - { - return renderproxies; - } - return true; - - //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; - } - - - - - private bool RenderFragment(Archetype arch, YmapEntityDef ent, FragType f, uint txdhash=0) - { - var pos = ent?.Position ?? Vector3.Zero; - - RenderDrawable(f.Drawable, arch, ent, pos-camera.Position, txdhash); - - if (f.Unknown_F8h_Data != null) //cloth - { - RenderDrawable(f.Unknown_F8h_Data, arch, ent, pos-camera.Position, txdhash); - } - - //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, arch, ent, -camera.Position, hash); - } - } - } - } - - return true; - } - - private bool RenderArchetype(Archetype arche, YmapEntityDef entity, Renderable rndbl = null, bool cull = true) - { - //enqueue a single archetype for rendering. - - if (arche == null) return false; - - Vector3 camrel = (entity != null) ? entity.CamRel : -camera.Position; - - Quaternion orientation = Quaternion.Identity; - Vector3 scale = Vector3.One; - Vector3 bscent = camrel; - if (entity != null) - { - orientation = entity.Orientation; - scale = entity.Scale; - bscent += entity.BSCenter; - } - else - { - bscent += arche.BSCenter; - } - - float bsrad = arche.BSRadius;// * scale; - if (cull) - { - if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref bscent, bsrad)) - { - return true; //culled - not visible; don't render, but pretend we did for LOD purposes.. - } - } - - float dist = bscent.Length(); - - if (boundsmode == BoundsShaderMode.Sphere) - { - if ((bsrad < renderboundsmaxrad) && (dist < renderboundsmaxdist)) - { - MapSphere ms = new MapSphere(); - ms.CamRelPos = bscent; - ms.Radius = bsrad; - BoundingSpheres.Add(ms); - } - } - if (boundsmode == BoundsShaderMode.Box) - { - if ((dist < renderboundsmaxdist)) - { - MapBox mb = new MapBox(); - mb.CamRelPos = camrel; - mb.BBMin = arche.BBMin; - mb.BBMax = arche.BBMax; - mb.Orientation = orientation; - mb.Scale = scale; - BoundingBoxes.Add(mb); - } - } - - - - bool res = false; - if (rndbl == null) - { - var drawable = TryGetDrawable(arche); - rndbl = TryGetRenderable(arche, drawable); - } - - if (rndbl != null) - { - res = RenderRenderable(rndbl, arche, entity, camrel); - - - //fragments have extra drawables! need to render those too... TODO: handle fragments properly... - FragDrawable fd = rndbl.Key as FragDrawable; - if (fd != null) - { - var frag = fd.OwnerFragment; - if ((frag != null) && (frag.Unknown_F8h_Data != null)) //cloth... - { - rndbl = TryGetRenderable(arche, frag.Unknown_F8h_Data); - if (rndbl != null) - { - bool res2 = RenderRenderable(rndbl, arche, entity, camrel); - res = res || res2; - } - } - } - } - - - return res; - } - - private bool RenderDrawable(DrawableBase drawable, Archetype arche, YmapEntityDef entity, Vector3 camrel, uint txdHash = 0) - { - //enqueue a single drawable for rendering. - - if (drawable == null) - return false; - - Renderable rndbl = TryGetRenderable(arche, drawable, txdHash); - if (rndbl == null) - return false; - - return RenderRenderable(rndbl, arche, entity, camrel); - } - - private bool RenderRenderable(Renderable rndbl, Archetype arche, YmapEntityDef entity, Vector3 camrel) - { - //enqueue a single renderable for rendering. - - if (!rndbl.IsLoaded) return false; - - - if (((SelectionMode == MapSelectionMode.Entity) || (SelectionMode == MapSelectionMode.EntityExtension) || (SelectionMode == MapSelectionMode.ArchetypeExtension))) - { - UpdateMouseHit(rndbl, arche, entity, camrel); - } - - bool isselected = (rndbl.Key == SelectedItem.Drawable); - - 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) - { - position = entity.Position; - scale = entity.Scale; - orientation = entity.Orientation; - tintPaletteIndex = entity.CEntityDef.tintValue; - bbmin = entity.BBMin; - bbmax = entity.BBMax; - bscen = entity.BSCenter; - } - - - if (rendercollisionmeshes && collisionmeshlayerdrawable) - { - Drawable sdrawable = rndbl.Key as Drawable; - if ((sdrawable != null) && (sdrawable.Bound != null)) - { - RenderCollisionMesh(sdrawable.Bound, entity); - } - } - - - bool retval = true;// false; - if (rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload)) - { - 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; - - - RenderableModel[] models = isselected ? rndbl.AllModels : rndbl.HDModels; - - for (int mi = 0; mi < models.Length; mi++) - { - var model = models[mi]; - - if (isselected) - { - if (SelectionModelDrawFlags.ContainsKey(model.DrawableModel)) - { continue; } //filter out models in selected item that aren't flagged for drawing. - } - - if (!RenderIsModelFinalRender(model) && !renderproxies) - { continue; } //filter out reflection proxy models... - - for (int gi = 0; gi < model.Geometries.Length; gi++) - { - var geom = model.Geometries[gi]; - - if (isselected) - { - if (SelectionGeometryDrawFlags.ContainsKey(geom.DrawableGeom)) - { continue; } //filter out geometries in selected item that aren't flagged for drawing. - } - - rginst.Geom = geom; - - shaders.Enqueue(rginst); - } - } - } - else - { - retval = false; - } - return retval; - } - - - - - private void RenderCar(Vector3 pos, Quaternion ori, MetaHash modelHash, MetaHash modelSetHash) - { - SelectedCarGenEntity.SetPosition(pos); - SelectedCarGenEntity.SetOrientation(ori); - - uint carhash = modelHash; - if ((carhash == 0) && (modelSetHash != 0)) - { - //find the pop group... and choose a vehicle.. - var stypes = Scenarios.ScenarioTypes; - if (stypes != null) - { - var modelset = stypes.GetVehicleModelSet(modelSetHash); - if ((modelset != null) && (modelset.Models != null) && (modelset.Models.Length > 0)) - { - carhash = JenkHash.GenHash(modelset.Models[0].NameLower); - } - } - } - if (carhash == 0) carhash = 418536135; //"infernus" - - YftFile caryft = gameFileCache.GetYft(carhash); - if ((caryft != null) && (caryft.Loaded) && (caryft.Fragment != null)) - { - RenderFragment(null, SelectedCarGenEntity, caryft.Fragment, carhash); + UpdateMouseHits(ymap); } } @@ -2913,178 +1088,8 @@ namespace CodeWalker - private void RenderWorldCollisionMeshes() - { - //enqueue collision meshes for rendering - from the world grid - collisionitems.Clear(); - space.GetVisibleBounds(camera, collisionmeshrange, collisionmeshlayers, collisionitems); - - foreach (var item in collisionitems) - { - YbnFile ybn = gameFileCache.GetYbn(item.Name); - if ((ybn != null) && (ybn.Loaded)) - { - RenderCollisionMesh(ybn.Bounds, null); - } - } - - } - - private void RenderInteriorCollisionMesh(YmapEntityDef mlo) - { - //enqueue interior collison meshes for rendering. - - if (mlo.Archetype == null) return; - var hash = mlo.Archetype.Hash; - YbnFile ybn = gameFileCache.GetYbn(hash); - if ((ybn != null) && (ybn.Loaded)) - { - RenderCollisionMesh(ybn.Bounds, mlo); - } - if (ybn == null) - { } - } - - private void RenderCollisionMesh(Bounds bounds, YmapEntityDef entity) - { - //enqueue a single collision mesh for rendering. - - 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; - } - - switch (bounds.Type) - { - case 10: //BoundComposite - BoundComposite boundcomp = bounds as BoundComposite; - if (boundcomp != null) - { - 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); - } - } - 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; - } - } - - - - private void RenderBounds(DeviceContext context) - { - //immediately render the entity bounding boxes/spheres - depending on boundsmode - - - bool clip = renderboundsclip; - - switch (SelectionMode) - { - case MapSelectionMode.WaterQuad: - case MapSelectionMode.MloInstance: - clip = false; - break; - } - - - Vector3 colour = new Vector3(0, 0, 1) * globalLights.HdrIntensity; - Vector3 colourhi = new Vector3(0, 1, 1) * globalLights.HdrIntensity; - - shaders.SetDepthStencilMode(context, clip ? DepthStencilMode.Enabled : DepthStencilMode.DisableAll); - var shader = shaders.Bounds; - - if ((BoundingBoxes.Count > 0) || (HilightBoxes.Count > 0)) - { - shader.SetMode(BoundsShaderMode.Box); - shader.SetShader(context); - shader.SetInputLayout(context, VertexType.Default); - shader.SetSceneVars(context, camera, null, globalLights); - shader.SetColourVars(context, new Vector4(colour, 1)); - - for (int i = 0; i < BoundingBoxes.Count; i++) - { - MapBox mb = BoundingBoxes[i]; - shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale); - shader.DrawBox(context); - } - shader.SetColourVars(context, new Vector4(colourhi, 1)); - for (int i = 0; i < HilightBoxes.Count; i++) - { - MapBox mb = HilightBoxes[i]; - shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale); - shader.DrawBox(context); - } - } - - if ((BoundingSpheres.Count > 0) || (HilightSpheres.Count > 0)) - { - shader.SetMode(BoundsShaderMode.Sphere); - shader.SetShader(context); - shader.SetInputLayout(context, VertexType.Default); - shader.SetSceneVars(context, camera, null, globalLights); - shader.SetColourVars(context, new Vector4(colour, 1)); - - for (int i = 0; i < BoundingSpheres.Count; i++) - { - MapSphere ms = BoundingSpheres[i]; - shader.SetSphereVars(context, ms.CamRelPos, ms.Radius); - shader.DrawSphere(context); - } - shader.SetColourVars(context, new Vector4(colourhi, 1)); - for (int i = 0; i < HilightSpheres.Count; i++) - { - MapSphere ms = HilightSpheres[i]; - shader.SetSphereVars(context, ms.CamRelPos, ms.Radius); - shader.DrawSphere(context); - } - } - - - - shader.UnbindResources(context); - } - - private void RenderMoused(DeviceContext context) + private void RenderMoused() { //immediately render the bounding box of the currently moused entity. @@ -3162,10 +1167,7 @@ namespace CodeWalker } - Vector3 colour = new Vector3(1, 1, 1); - colour *= globalLights.HdrIntensity * 5.0f; - - bool clip = renderboundsclip; + bool clip = Renderer.renderboundsclip; BoundsShaderMode mode = BoundsShaderMode.Box; float bsphrad = CurMouseHit.BSphere.Radius; @@ -3222,29 +1224,7 @@ namespace CodeWalker } - shaders.SetDepthStencilMode(context, clip ? DepthStencilMode.Enabled : DepthStencilMode.DisableAll); - - //render moused object box. - var shader = shaders.Bounds; - shader.SetMode(mode); - shader.SetShader(context); - shader.SetInputLayout(context, VertexType.Default); - shader.SetSceneVars(context, camera, null, globalLights); - shader.SetColourVars(context, new Vector4(colour, 1)); //white box - - if (mode == BoundsShaderMode.Box) - { - shader.SetBoxVars(context, camrel, bbmin, bbmax, ori, scale); - shader.DrawBox(context); - } - else if (mode == BoundsShaderMode.Sphere) - { - shader.SetSphereVars(context, camrel, bsphrad); - shader.DrawSphere(context); - } - - shader.UnbindResources(context); - + Renderer.RenderMouseHit(mode, clip, ref camrel, ref bbmin, ref bbmax, ref scale, ref ori, bsphrad); } private void RenderSelection() @@ -3274,7 +1254,7 @@ namespace CodeWalker if (MouseRayCollision.Hit) { var arup = GetPerpVec(MouseRayCollision.Normal); - RenderSelectionArrowOutline(MouseRayCollision.Position, MouseRayCollision.Normal, arup, Quaternion.Identity, 2.0f, 0.15f, cgrn); + Renderer.RenderSelectionArrowOutline(MouseRayCollision.Position, MouseRayCollision.Normal, arup, Quaternion.Identity, 2.0f, 0.15f, cgrn); } } @@ -3285,12 +1265,6 @@ namespace CodeWalker { return; } - Vector3 colour = new Vector3(0, 1, 0); - colour *= globalLights.HdrIntensity * 5.0f; - - - bool clip = renderboundsclip; - BoundsShaderMode mode = BoundsShaderMode.Box; float bsphrad = selectionItem.BSphere.Radius; @@ -3316,7 +1290,7 @@ namespace CodeWalker if (EditEntityPivot) { - RenderSelectionEntityPivot(ent); + Renderer.RenderSelectionEntityPivot(ent); } } if (selectionItem.CarGenerator != null) @@ -3328,12 +1302,12 @@ namespace CodeWalker bbmax = cg.BBMax; float arrowlen = cg._CCarGen.perpendicularLength; float arrowrad = arrowlen * 0.066f; - RenderSelectionArrowOutline(cg.Position, Vector3.UnitX, Vector3.UnitY, ori, arrowlen, arrowrad, cgrn); + Renderer.RenderSelectionArrowOutline(cg.Position, Vector3.UnitX, Vector3.UnitY, ori, arrowlen, arrowrad, cgrn); Quaternion cgtrn = Quaternion.RotationAxis(Vector3.UnitZ, (float)Math.PI * -0.5f); //car fragments currently need to be rotated 90 deg right... Quaternion cgori = Quaternion.Multiply(ori, cgtrn); - RenderCar(cg.Position, cgori, cg._CCarGen.carModel, cg._CCarGen.popGroup); + Renderer.RenderCar(cg.Position, cgori, cg._CCarGen.carModel, cg._CCarGen.popGroup); } if (selectionItem.PathNode != null) { @@ -3353,7 +1327,7 @@ namespace CodeWalker ori = sn.Orientation; float arrowlen = 2.0f; float arrowrad = 0.25f; - RenderSelectionArrowOutline(sn.Position, Vector3.UnitY, Vector3.UnitZ, ori, arrowlen, arrowrad, cgrn); + Renderer.RenderSelectionArrowOutline(sn.Position, Vector3.UnitY, Vector3.UnitZ, ori, arrowlen, arrowrad, cgrn); MCScenarioPoint vpoint = sn.MyPoint ?? sn.ClusterMyPoint; if ((vpoint != null) && (vpoint?.Type?.IsVehicle ?? false)) @@ -3370,7 +1344,7 @@ namespace CodeWalker } } - RenderCar(sn.Position, sn.Orientation, 0, vhash); + Renderer.RenderCar(sn.Position, sn.Orientation, 0, vhash); } } @@ -3389,14 +1363,13 @@ namespace CodeWalker var aori = Quaternion.Invert(Quaternion.RotationLookAtRH(dir, dup)); float arrowrad = 0.25f; float arrowlen = Math.Max(dl - arrowrad*5.0f, 0); - RenderSelectionArrowOutline(sn1.Position, -Vector3.UnitZ, Vector3.UnitY, aori, arrowlen, arrowrad, cblu); + Renderer.RenderSelectionArrowOutline(sn1.Position, -Vector3.UnitZ, Vector3.UnitY, aori, arrowlen, arrowrad, cblu); } } if (selectionItem.MloEntityDef != null) { bbmin = selectionItem.AABB.Minimum; bbmax = selectionItem.AABB.Maximum; - clip = false; } if ((selectionItem.GrassBatch != null) || (selectionItem.ArchetypeExtension != null) || (selectionItem.EntityExtension != null) || (selectionItem.CollisionBounds != null)) { @@ -3404,16 +1377,10 @@ namespace CodeWalker bbmax = selectionItem.AABB.Maximum; scale = Vector3.One; } - if (selectionItem.WaterQuad != null) - { - clip = false; - } if (selectionItem.NavPoly != null) { - RenderSelectionNavPoly(selectionItem.NavPoly); - - //return;//don't render a selection box for nav mesh - //clip = false; + Renderer.RenderSelectionNavPoly(selectionItem.NavPoly); + //return;//don't render a selection box for nav mesh? } if (selectionItem.Audio != null) @@ -3430,7 +1397,7 @@ namespace CodeWalker MapSphere wsph = new MapSphere(); wsph.CamRelPos = au.OuterPos - camera.Position; wsph.Radius = au.OuterRad; - WhiteSpheres.Add(wsph); + Renderer.WhiteSpheres.Add(wsph); } else { @@ -3440,7 +1407,7 @@ namespace CodeWalker wbox.BBMax = au.OuterMax; wbox.Orientation = au.OuterOri; wbox.Scale = scale; - WhiteBoxes.Add(wbox); + Renderer.WhiteBoxes.Add(wbox); } } @@ -3453,240 +1420,21 @@ namespace CodeWalker box.BBMax = bbmax; box.Orientation = ori; box.Scale = scale; - SelectionBoxes.Add(box); + Renderer.SelectionBoxes.Add(box); } else if (mode == BoundsShaderMode.Sphere) { MapSphere sph = new MapSphere(); sph.CamRelPos = camrel; sph.Radius = bsphrad; - SelectionSpheres.Add(sph); + Renderer.SelectionSpheres.Add(sph); } } - private void RenderSelectionEntityPivot(YmapEntityDef ent) - { - uint cred = (uint)new Color4(1.0f, 0.0f, 0.0f, 1.0f).ToRgba(); - uint cgrn = (uint)new Color4(0.0f, 1.0f, 0.0f, 1.0f).ToRgba(); - uint cblu = (uint)new Color4(0.0f, 0.0f, 1.0f, 1.0f).ToRgba(); - - var pos = ent.WidgetPosition; - var ori = ent.WidgetOrientation; - - float pxsize = 120.0f; - float sssize = pxsize / camera.Height; - float dist = (pos - camera.Position).Length(); - float size = sssize * dist; - if (camera.IsMapView || camera.IsOrthographic) - { - size = sssize * camera.OrthographicSize; - } - float rad = size * 0.066f; - - RenderSelectionArrowOutline(pos, Vector3.UnitX, Vector3.UnitY, ori, size, rad, cred); - RenderSelectionArrowOutline(pos, Vector3.UnitY, Vector3.UnitX, ori, size, rad, cgrn); - RenderSelectionArrowOutline(pos, Vector3.UnitZ, Vector3.UnitY, ori, size, rad, cblu); - - } - - private void RenderSelectionArrowOutline(Vector3 pos, Vector3 dir, Vector3 up, Quaternion ori, float len, float rad, uint colour) - { - Vector3 ax = Vector3.Cross(dir, up); - Vector3 sx = ax * rad; - Vector3 sy = up * rad; - Vector3 sz = dir * len; - VertexTypePC[] c = new VertexTypePC[8]; - Vector3 d0 = - sx - sy; - Vector3 d1 = - sx + sy; - Vector3 d2 = + sx - sy; - Vector3 d3 = + sx + sy; - c[0].Position = d0; - c[1].Position = d1; - c[2].Position = d2; - c[3].Position = d3; - c[4].Position = d0 + sz; - c[5].Position = d1 + sz; - c[6].Position = d2 + sz; - c[7].Position = d3 + sz; - for (int i = 0; i < 8; i++) - { - c[i].Colour = colour; - c[i].Position = pos + ori.Multiply(c[i].Position); - } - - SelectionLineVerts.Add(c[0]); - SelectionLineVerts.Add(c[1]); - SelectionLineVerts.Add(c[1]); - SelectionLineVerts.Add(c[3]); - SelectionLineVerts.Add(c[3]); - SelectionLineVerts.Add(c[2]); - SelectionLineVerts.Add(c[2]); - SelectionLineVerts.Add(c[0]); - SelectionLineVerts.Add(c[4]); - SelectionLineVerts.Add(c[5]); - SelectionLineVerts.Add(c[5]); - SelectionLineVerts.Add(c[7]); - SelectionLineVerts.Add(c[7]); - SelectionLineVerts.Add(c[6]); - SelectionLineVerts.Add(c[6]); - SelectionLineVerts.Add(c[4]); - SelectionLineVerts.Add(c[0]); - SelectionLineVerts.Add(c[4]); - SelectionLineVerts.Add(c[1]); - SelectionLineVerts.Add(c[5]); - SelectionLineVerts.Add(c[2]); - SelectionLineVerts.Add(c[6]); - SelectionLineVerts.Add(c[3]); - SelectionLineVerts.Add(c[7]); - - c[0].Position = pos + ori.Multiply(dir * (len + rad * 5.0f)); - c[4].Position += ori.Multiply(d0); - c[5].Position += ori.Multiply(d1); - c[6].Position += ori.Multiply(d2); - c[7].Position += ori.Multiply(d3); - SelectionLineVerts.Add(c[4]); - SelectionLineVerts.Add(c[5]); - SelectionLineVerts.Add(c[5]); - SelectionLineVerts.Add(c[7]); - SelectionLineVerts.Add(c[7]); - SelectionLineVerts.Add(c[6]); - SelectionLineVerts.Add(c[6]); - SelectionLineVerts.Add(c[4]); - SelectionLineVerts.Add(c[0]); - SelectionLineVerts.Add(c[4]); - SelectionLineVerts.Add(c[0]); - SelectionLineVerts.Add(c[5]); - SelectionLineVerts.Add(c[0]); - SelectionLineVerts.Add(c[6]); - SelectionLineVerts.Add(c[0]); - SelectionLineVerts.Add(c[7]); - } - - private void RenderSelectionNavPoly(YnvPoly poly) - { - ////draw poly triangles - var pcolour = new Color4(0.6f, 0.95f, 0.6f, 1.0f); - var colourval = (uint)pcolour.ToRgba(); - var ynv = poly.Ynv; - var ic = poly._RawData.IndexCount; - var startid = poly._RawData.IndexID; - var endid = startid + ic; - var lastid = endid - 1; - var vc = ynv.Vertices.Count; - var startind = ynv.Indices[startid]; - VertexTypePC v0 = new VertexTypePC(); - VertexTypePC v1 = new VertexTypePC(); - VertexTypePC v2 = new VertexTypePC(); - v0.Position = ynv.Vertices[startind]; - v0.Colour = colourval; - v1.Colour = colourval; - v2.Colour = colourval; - int tricount = ic - 2; - for (int t = 0; t < tricount; t++) - { - int tid = startid + t; - int ind1 = ynv.Indices[tid + 1]; - int ind2 = ynv.Indices[tid + 2]; - if ((ind1 >= vc) || (ind2 >= vc)) - { continue; } - v1.Position = ynv.Vertices[ind1]; - v2.Position = ynv.Vertices[ind2]; - SelectionTriVerts.Add(v0); - SelectionTriVerts.Add(v1); - SelectionTriVerts.Add(v2); - SelectionTriVerts.Add(v0); - SelectionTriVerts.Add(v2); - SelectionTriVerts.Add(v1); - } - } - - private void RenderSelectionGeometry(DeviceContext context) - { - - bool clip = true; - switch (SelectionMode) - { - case MapSelectionMode.NavMesh: - case MapSelectionMode.WaterQuad: - case MapSelectionMode.MloInstance: - clip = false; - break; - } - - - shaders.SetDepthStencilMode(context, clip ? DepthStencilMode.Enabled : DepthStencilMode.DisableAll); - - var pshader = shaders.Paths; - if (SelectionTriVerts.Count > 0) - { - pshader.RenderTriangles(context, SelectionTriVerts, camera, shaders.GlobalLights); - } - if (SelectionLineVerts.Count > 0) - { - pshader.RenderLines(context, SelectionLineVerts, camera, shaders.GlobalLights); - } - - - - - Vector3 coloursel = new Vector3(0, 1, 0) * globalLights.HdrIntensity * 5.0f; - Vector3 colourwht = new Vector3(1, 1, 1) * globalLights.HdrIntensity * 10.0f; - var shader = shaders.Bounds; - - if ((WhiteBoxes.Count > 0) || (SelectionBoxes.Count > 0)) - { - shader.SetMode(BoundsShaderMode.Box); - shader.SetShader(context); - shader.SetInputLayout(context, VertexType.Default); - shader.SetSceneVars(context, camera, null, globalLights); - shader.SetColourVars(context, new Vector4(colourwht, 1)); - for (int i = 0; i < WhiteBoxes.Count; i++) - { - MapBox mb = WhiteBoxes[i]; - shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale); - shader.DrawBox(context); - } - shader.SetColourVars(context, new Vector4(coloursel, 1)); - for (int i = 0; i < SelectionBoxes.Count; i++) - { - MapBox mb = SelectionBoxes[i]; - shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale); - shader.DrawBox(context); - } - shader.UnbindResources(context); - } - - if ((WhiteSpheres.Count > 0) || (SelectionSpheres.Count > 0)) - { - shader.SetMode(BoundsShaderMode.Sphere); - shader.SetShader(context); - shader.SetInputLayout(context, VertexType.Default); - shader.SetSceneVars(context, camera, null, globalLights); - shader.SetColourVars(context, new Vector4(colourwht, 1)); - for (int i = 0; i < WhiteSpheres.Count; i++) - { - MapSphere ms = WhiteSpheres[i]; - shader.SetSphereVars(context, ms.CamRelPos, ms.Radius); - shader.DrawSphere(context); - } - shader.SetColourVars(context, new Vector4(coloursel, 1)); - for (int i = 0; i < SelectionSpheres.Count; i++) - { - MapSphere ms = SelectionSpheres[i]; - shader.SetSphereVars(context, ms.CamRelPos, ms.Radius); - shader.DrawSphere(context); - } - shader.UnbindResources(context); - } - - - } - - - private void RenderMarkers(DeviceContext context) + private void RenderMarkers() { //immediately render all the current markers. @@ -3717,51 +1465,15 @@ namespace CodeWalker MarkerBatch.AddRange(SortedMarkers); } - shaders.SetRasterizerMode(context, RasterizerMode.SolidDblSided); //hmm they are backwards - shaders.SetDepthStencilMode(context, markerdepthclip ? DepthStencilMode.Enabled : DepthStencilMode.DisableAll); - shaders.SetDefaultBlendState(context); - - var shader = shaders.Marker; - shader.SetShader(context); - shader.SetInputLayout(context, VertexType.Default); - shader.SetSceneVars(context, camera, null, globalLights); - - MapIcon icon = null; - foreach (var marker in MarkerBatch) - { - icon = marker.Icon; - Vector2 texs = new Vector2(icon.TexWidth, icon.TexHeight); - Vector2 size = texs * marker.Distance; - Vector2 offset = (new Vector2(texs.X, -texs.Y) - new Vector2(icon.Center.X, -icon.Center.Y) * 2.0f) * marker.Distance; - shader.SetMarkerVars(context, marker.CamRelPos, size, offset); - shader.SetTexture(context, icon.TexView); - markerquad.Draw(context); - } - - shader.UnbindResources(context); + Renderer.RenderMarkers(MarkerBatch); } - private void RenderWidgets(DeviceContext context) + private void RenderWidgets() { if (!ShowWidget) return; - - var dsmode = DepthStencilMode.Enabled; - if (Widget.Mode == WidgetMode.Rotation) - { - dsmode = DepthStencilMode.DisableAll; - } - - shaders.SetRasterizerMode(context, RasterizerMode.SolidDblSided); - shaders.SetDepthStencilMode(context, dsmode); - shaders.SetDefaultBlendState(context); - shaders.ClearDepth(context, false); - - var shader = shaders.Widgets; - - Widget.Render(context, camera, shader); - + Renderer.RenderTransformWidget(Widget); } private void UpdateWidgets() { @@ -3907,9 +1619,9 @@ namespace CodeWalker { space.BuildYndVerts(ynd); } - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - renderableCache.Invalidate(ynd); + Renderer.Invalidate(ynd); } } public void UpdatePathNodeGraphics(YndNode pathnode, bool fullupdate) @@ -3942,9 +1654,9 @@ namespace CodeWalker //{ // //space.BuildYndVerts(ynd); //} - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - renderableCache.Invalidate(tt); + Renderer.Invalidate(tt); } } public void UpdateTrainTrackNodeGraphics(TrainTrackNode node, bool fullupdate) @@ -3963,9 +1675,9 @@ namespace CodeWalker scenario.BuildVertices(); - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - renderableCache.Invalidate(scenario); + Renderer.Invalidate(scenario); } } @@ -3973,7 +1685,7 @@ namespace CodeWalker public Vector3 GetCameraPosition() { //currently used by ProjectForm when creating entities - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { return camera.Position; } @@ -3981,7 +1693,7 @@ namespace CodeWalker public Vector3 GetCameraViewDir() { //currently used by ProjectForm when creating entities - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { return camera.ViewDirection; } @@ -3995,16 +1707,17 @@ namespace CodeWalker public void SetKeyBindings(KeyBindings kb) { - keyBindings = kb.Copy(); + Input.keyBindings = kb.Copy(); UpdateToolbarShortcutsText(); } private void UpdateToolbarShortcutsText() { - ToolbarSelectButton.ToolTipText = string.Format("Select objects / Exit edit mode ({0}, {1})", keyBindings.ToggleMouseSelect, keyBindings.ExitEditMode); - ToolbarMoveButton.ToolTipText = string.Format("Move ({0})", keyBindings.EditPosition); - ToolbarRotateButton.ToolTipText = string.Format("Rotate ({0})", keyBindings.EditRotation); - ToolbarScaleButton.ToolTipText = string.Format("Scale ({0})", keyBindings.EditScale); - ShowToolbarCheckBox.Text = string.Format("Show Toolbar ({0})", keyBindings.ToggleToolbar); + var kb = Input.keyBindings; + ToolbarSelectButton.ToolTipText = string.Format("Select objects / Exit edit mode ({0}, {1})", kb.ToggleMouseSelect, kb.ExitEditMode); + ToolbarMoveButton.ToolTipText = string.Format("Move ({0})", kb.EditPosition); + ToolbarRotateButton.ToolTipText = string.Format("Rotate ({0})", kb.EditRotation); + ToolbarScaleButton.ToolTipText = string.Format("Scale ({0})", kb.EditScale); + ShowToolbarCheckBox.Text = string.Format("Show Toolbar ({0})", kb.ToggleToolbar); } @@ -4166,7 +1879,7 @@ namespace CodeWalker e.EnableCollisions = true; e.Enabled = true; - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { space.AddTemporaryEntity(e); } @@ -4198,7 +1911,7 @@ namespace CodeWalker pedEntity.Enabled = false; - timerunning = false; + Renderer.timerunning = false; camera.SetFollowEntity(camEntity); camera.TargetDistance = 1.0f; //default? @@ -4212,7 +1925,7 @@ namespace CodeWalker pedEntity.Velocity = Vector3.Zero; pedEntity.Enabled = true; - timerunning = true; + Renderer.timerunning = true; camera.SetFollowEntity(pedEntity.CameraEntity); camera.TargetDistance = 0.01f; //1cm @@ -4244,11 +1957,8 @@ namespace CodeWalker //reset variables for beginning the mouse hit test CurMouseHit.Clear(); - SelectionLineVerts.Clear(); - SelectionTriVerts.Clear(); - - MouseRayCollisionEnabled = CtrlPressed; //temporary...! + MouseRayCollisionEnabled = Input.CtrlPressed; //temporary...! if (MouseRayCollisionEnabled) { if (space.Inited && space.Grid != null) @@ -4260,10 +1970,30 @@ namespace CodeWalker } } + + Renderer.RenderedDrawablesListEnable = + ((SelectionMode == MapSelectionMode.Entity) && MouseSelectEnabled) || + (SelectionMode == MapSelectionMode.EntityExtension) || + (SelectionMode == MapSelectionMode.ArchetypeExtension); + + Renderer.RenderedBoundCompsListEnable = (SelectionMode == MapSelectionMode.Collision); + + } - private void UpdateMouseHit(Renderable rndbl, Archetype arche, YmapEntityDef entity, Vector3 camrel) + private void UpdateMouseHitsFromRenderer() { - if ((SelectionMode == MapSelectionMode.Entity) && !MouseSelectEnabled) return; //performance improvement when not selecting entities... + foreach (var rd in Renderer.RenderedDrawables) + { + UpdateMouseHits(rd.Drawable, rd.Archetype, rd.Entity); + } + foreach (var rb in Renderer.RenderedBoundComps) + { + UpdateMouseHits(rb.BoundComp, rb.Entity); + } + } + private void UpdateMouseHits(DrawableBase drawable, Archetype arche, YmapEntityDef entity) + { + //if ((SelectionMode == MapSelectionMode.Entity) && !MouseSelectEnabled) return; //performance improvement when not selecting entities... //test the selected entity/archetype for mouse hit. @@ -4271,7 +2001,6 @@ namespace CodeWalker Quaternion orinv; Ray mraytrn; float hitdist = 0.0f; - var drawable = rndbl.Key; int geometryIndex = 0; DrawableGeometry geometry = null; BoundingBox geometryAABB = new BoundingBox(); @@ -4280,10 +2009,12 @@ namespace CodeWalker BoundingBox gbbox = new BoundingBox(); Quaternion orientation = Quaternion.Identity; Vector3 scale = Vector3.One; + Vector3 camrel = -camera.Position; if (entity != null) { orientation = entity.Orientation; scale = entity.Scale; + camrel += entity.Position; } if (arche != null) { @@ -4323,7 +2054,7 @@ namespace CodeWalker mb.Scale = Vector3.One;// scale; mb.BBMin *= scale; mb.BBMax *= scale; - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); bbox.Minimum = mb.BBMin; //TODO: refactor this! bbox.Maximum = mb.BBMax; @@ -4352,7 +2083,7 @@ namespace CodeWalker mb.Scale = Vector3.One;// scale; mb.BBMin *= scale; mb.BBMax *= scale; - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); bbox.Minimum = mb.BBMin; //TODO: refactor this! bbox.Maximum = mb.BBMax; @@ -4564,191 +2295,6 @@ namespace CodeWalker //{ } - } - private void UpdateMouseHits(YmapFile ymap) - { - //find mouse hits for things like time cycle mods and car generators in ymaps. - - BoundingBox bbox = new BoundingBox(); - Ray mray = new Ray(); - mray.Position = camera.MouseRay.Position + camera.Position; - mray.Direction = camera.MouseRay.Direction; - float hitdist = float.MaxValue; - - if ((SelectionMode == MapSelectionMode.TimeCycleModifier) && (ymap.TimeCycleModifiers != null)) - { - for (int i = 0; i < ymap.TimeCycleModifiers.Length; i++) - { - var tcm = ymap.TimeCycleModifiers[i]; - if ((((tcm.BBMin + tcm.BBMax) * 0.5f) - camera.Position).Length() > renderboundsmaxdist) continue; - //if (!LodDistTest(camera.Position, tcm.BBMin, tcm.BBMax, renderboundsmaxdist)) continue; - - MapBox mb = new MapBox(); - mb.CamRelPos = -camera.Position; - mb.BBMin = tcm.BBMin; - mb.BBMax = tcm.BBMax; - mb.Orientation = Quaternion.Identity; - mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); - - bbox.Minimum = mb.BBMin; - bbox.Maximum = mb.BBMax; - if (mray.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) - { - CurMouseHit.TimeCycleModifier = tcm; - CurMouseHit.HitDist = hitdist; - CurMouseHit.CamRel = mb.CamRelPos; - CurMouseHit.AABB = bbox; - } - } - } - if ((SelectionMode == MapSelectionMode.CarGenerator) && (ymap.CarGenerators != null)) - { - for (int i = 0; i < ymap.CarGenerators.Length; i++) - { - var cg = ymap.CarGenerators[i]; - MapBox mb = new MapBox(); - mb.CamRelPos = cg.Position - camera.Position; - mb.BBMin = cg.BBMin; - mb.BBMax = cg.BBMax; - mb.Orientation = cg.Orientation; - mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); - - Quaternion orinv = Quaternion.Invert(cg.Orientation); - Ray mraytrn = new Ray(); - mraytrn.Position = orinv.Multiply(camera.MouseRay.Position - mb.CamRelPos); - mraytrn.Direction = orinv.Multiply(mray.Direction); - bbox.Minimum = mb.BBMin; - bbox.Maximum = mb.BBMax; - if (mraytrn.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) - { - CurMouseHit.CarGenerator = cg; - CurMouseHit.HitDist = hitdist; - CurMouseHit.CamRel = mb.CamRelPos; - CurMouseHit.AABB = bbox; - } - } - if (SelectedItem.CarGenerator != null) - { - } - - } - if ((SelectionMode == MapSelectionMode.MloInstance) && (ymap.MloEntities != null)) - { - for (int i = 0; i < ymap.MloEntities.Length; i++) - { - var ent = ymap.MloEntities[i]; - MapBox mb = new MapBox(); - mb.CamRelPos = ent.Position - camera.Position; - mb.BBMin = /*ent?.BBMin ??*/ new Vector3(-1.5f); - mb.BBMax = /*ent?.BBMax ??*/ new Vector3(1.5f); - mb.Orientation = ent?.Orientation ?? Quaternion.Identity; - mb.Scale = /*ent?.Scale ??*/ Vector3.One; - BoundingBoxes.Add(mb); - - Quaternion orinv = Quaternion.Invert(mb.Orientation); - Ray mraytrn = new Ray(); - mraytrn.Position = orinv.Multiply(camera.MouseRay.Position - mb.CamRelPos); - mraytrn.Direction = orinv.Multiply(mray.Direction); - bbox.Minimum = mb.BBMin; - bbox.Maximum = mb.BBMax; - if (mraytrn.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) - { - CurMouseHit.MloEntityDef = ent; - CurMouseHit.EntityDef = ent; - CurMouseHit.HitDist = hitdist; - CurMouseHit.CamRel = mb.CamRelPos; - CurMouseHit.AABB = new BoundingBox(mb.BBMin, mb.BBMax); - } - } - } - if ((SelectionMode == MapSelectionMode.Grass) && (ymap.GrassInstanceBatches != null)) - { - for (int i = 0; i < ymap.GrassInstanceBatches.Length; i++) - { - var gb = ymap.GrassInstanceBatches[i]; - if ((gb.Position - camera.Position).Length() > renderboundsmaxdist) continue; - //if (!LodDistTest(camera.Position, gb.AABBMin, gb.AABBMax, renderboundsmaxdist)) continue; - - MapBox mb = new MapBox(); - mb.CamRelPos = -camera.Position; - mb.BBMin = gb.AABBMin; - mb.BBMax = gb.AABBMax; - mb.Orientation = Quaternion.Identity; - mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); - - bbox.Minimum = mb.BBMin; - bbox.Maximum = mb.BBMax; - if (mray.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) - { - CurMouseHit.GrassBatch = gb; - CurMouseHit.HitDist = hitdist; - CurMouseHit.CamRel = mb.CamRelPos; - CurMouseHit.AABB = bbox; - } - } - } - if ((SelectionMode == MapSelectionMode.DistantLodLights) && (ymap.DistantLODLights != null)) - { - var dll = ymap.DistantLODLights; - if ((((dll.BBMin + dll.BBMax) * 0.5f) - camera.Position).Length() <= renderboundsmaxdist) - //if (LodDistTest(camera.Position, dll.BBMin, dll.BBMax, renderboundsmaxdist)) - { - MapBox mb = new MapBox(); - mb.CamRelPos = -camera.Position; - mb.BBMin = dll.BBMin; - mb.BBMax = dll.BBMax; - mb.Orientation = Quaternion.Identity; - mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); - - bbox.Minimum = mb.BBMin; - bbox.Maximum = mb.BBMax; - if (mray.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) - { - CurMouseHit.DistantLodLights = dll; - CurMouseHit.HitDist = hitdist; - CurMouseHit.CamRel = mb.CamRelPos; - CurMouseHit.AABB = bbox; - } - } - } - - - } - private void UpdateMouseHits(List waterquads) - { - if (SelectionMode != MapSelectionMode.WaterQuad) return; - - BoundingBox bbox = new BoundingBox(); - Ray mray = new Ray(); - mray.Position = camera.MouseRay.Position + camera.Position; - mray.Direction = camera.MouseRay.Direction; - float hitdist = float.MaxValue; - - - foreach (var quad in waterquads) - { - MapBox mb = new MapBox(); - mb.CamRelPos = -camera.Position; - mb.BBMin = new Vector3(quad.minX, quad.minY, quad.z); - mb.BBMax = new Vector3(quad.maxX, quad.maxY, quad.z); - mb.Orientation = Quaternion.Identity; - mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); - - bbox.Minimum = mb.BBMin; - bbox.Maximum = mb.BBMax; - if (mray.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) - { - CurMouseHit.WaterQuad = quad; - CurMouseHit.HitDist = hitdist; - CurMouseHit.CamRel = mb.CamRelPos; - CurMouseHit.AABB = bbox; - } - } } private void UpdateMouseHits(RenderableBoundComposite rndbc, YmapEntityDef entity) { @@ -4785,9 +2331,9 @@ namespace CodeWalker mb.BBMax = geom.BoundGeom.BoundingBoxMax; var cent = camrel + (mb.BBMin + mb.BBMax) * 0.5f; - if (cent.Length() > renderboundsmaxdist) continue; + if (cent.Length() > Renderer.renderboundsmaxdist) continue; - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); bbox.Minimum = mb.BBMin * scale; bbox.Maximum = mb.BBMax * scale; @@ -4803,6 +2349,190 @@ namespace CodeWalker } } + private void UpdateMouseHits(YmapFile ymap) + { + //find mouse hits for things like time cycle mods and car generators in ymaps. + + BoundingBox bbox = new BoundingBox(); + Ray mray = new Ray(); + mray.Position = camera.MouseRay.Position + camera.Position; + mray.Direction = camera.MouseRay.Direction; + float hitdist = float.MaxValue; + + float dmax = Renderer.renderboundsmaxdist; + + if ((SelectionMode == MapSelectionMode.TimeCycleModifier) && (ymap.TimeCycleModifiers != null)) + { + for (int i = 0; i < ymap.TimeCycleModifiers.Length; i++) + { + var tcm = ymap.TimeCycleModifiers[i]; + if ((((tcm.BBMin + tcm.BBMax) * 0.5f) - camera.Position).Length() > dmax) continue; + + MapBox mb = new MapBox(); + mb.CamRelPos = -camera.Position; + mb.BBMin = tcm.BBMin; + mb.BBMax = tcm.BBMax; + mb.Orientation = Quaternion.Identity; + mb.Scale = Vector3.One; + Renderer.BoundingBoxes.Add(mb); + + bbox.Minimum = mb.BBMin; + bbox.Maximum = mb.BBMax; + if (mray.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) + { + CurMouseHit.TimeCycleModifier = tcm; + CurMouseHit.HitDist = hitdist; + CurMouseHit.CamRel = mb.CamRelPos; + CurMouseHit.AABB = bbox; + } + } + } + if ((SelectionMode == MapSelectionMode.CarGenerator) && (ymap.CarGenerators != null)) + { + for (int i = 0; i < ymap.CarGenerators.Length; i++) + { + var cg = ymap.CarGenerators[i]; + MapBox mb = new MapBox(); + mb.CamRelPos = cg.Position - camera.Position; + mb.BBMin = cg.BBMin; + mb.BBMax = cg.BBMax; + mb.Orientation = cg.Orientation; + mb.Scale = Vector3.One; + Renderer.BoundingBoxes.Add(mb); + + Quaternion orinv = Quaternion.Invert(cg.Orientation); + Ray mraytrn = new Ray(); + mraytrn.Position = orinv.Multiply(camera.MouseRay.Position - mb.CamRelPos); + mraytrn.Direction = orinv.Multiply(mray.Direction); + bbox.Minimum = mb.BBMin; + bbox.Maximum = mb.BBMax; + if (mraytrn.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) + { + CurMouseHit.CarGenerator = cg; + CurMouseHit.HitDist = hitdist; + CurMouseHit.CamRel = mb.CamRelPos; + CurMouseHit.AABB = bbox; + } + } + if (SelectedItem.CarGenerator != null) + { + } + + } + if ((SelectionMode == MapSelectionMode.MloInstance) && (ymap.MloEntities != null)) + { + for (int i = 0; i < ymap.MloEntities.Length; i++) + { + var ent = ymap.MloEntities[i]; + MapBox mb = new MapBox(); + mb.CamRelPos = ent.Position - camera.Position; + mb.BBMin = /*ent?.BBMin ??*/ new Vector3(-1.5f); + mb.BBMax = /*ent?.BBMax ??*/ new Vector3(1.5f); + mb.Orientation = ent?.Orientation ?? Quaternion.Identity; + mb.Scale = /*ent?.Scale ??*/ Vector3.One; + Renderer.BoundingBoxes.Add(mb); + + Quaternion orinv = Quaternion.Invert(mb.Orientation); + Ray mraytrn = new Ray(); + mraytrn.Position = orinv.Multiply(camera.MouseRay.Position - mb.CamRelPos); + mraytrn.Direction = orinv.Multiply(mray.Direction); + bbox.Minimum = mb.BBMin; + bbox.Maximum = mb.BBMax; + if (mraytrn.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) + { + CurMouseHit.MloEntityDef = ent; + CurMouseHit.EntityDef = ent; + CurMouseHit.HitDist = hitdist; + CurMouseHit.CamRel = mb.CamRelPos; + CurMouseHit.AABB = new BoundingBox(mb.BBMin, mb.BBMax); + } + } + } + if ((SelectionMode == MapSelectionMode.Grass) && (ymap.GrassInstanceBatches != null)) + { + for (int i = 0; i < ymap.GrassInstanceBatches.Length; i++) + { + var gb = ymap.GrassInstanceBatches[i]; + if ((gb.Position - camera.Position).Length() > dmax) continue; + + MapBox mb = new MapBox(); + mb.CamRelPos = -camera.Position; + mb.BBMin = gb.AABBMin; + mb.BBMax = gb.AABBMax; + mb.Orientation = Quaternion.Identity; + mb.Scale = Vector3.One; + Renderer.BoundingBoxes.Add(mb); + + bbox.Minimum = mb.BBMin; + bbox.Maximum = mb.BBMax; + if (mray.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) + { + CurMouseHit.GrassBatch = gb; + CurMouseHit.HitDist = hitdist; + CurMouseHit.CamRel = mb.CamRelPos; + CurMouseHit.AABB = bbox; + } + } + } + if ((SelectionMode == MapSelectionMode.DistantLodLights) && (ymap.DistantLODLights != null)) + { + var dll = ymap.DistantLODLights; + if ((((dll.BBMin + dll.BBMax) * 0.5f) - camera.Position).Length() <= dmax) + { + MapBox mb = new MapBox(); + mb.CamRelPos = -camera.Position; + mb.BBMin = dll.BBMin; + mb.BBMax = dll.BBMax; + mb.Orientation = Quaternion.Identity; + mb.Scale = Vector3.One; + Renderer.BoundingBoxes.Add(mb); + + bbox.Minimum = mb.BBMin; + bbox.Maximum = mb.BBMax; + if (mray.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) + { + CurMouseHit.DistantLodLights = dll; + CurMouseHit.HitDist = hitdist; + CurMouseHit.CamRel = mb.CamRelPos; + CurMouseHit.AABB = bbox; + } + } + } + + + } + private void UpdateMouseHits(List waterquads) + { + if (SelectionMode != MapSelectionMode.WaterQuad) return; + + BoundingBox bbox = new BoundingBox(); + Ray mray = new Ray(); + mray.Position = camera.MouseRay.Position + camera.Position; + mray.Direction = camera.MouseRay.Direction; + float hitdist = float.MaxValue; + + + foreach (var quad in waterquads) + { + MapBox mb = new MapBox(); + mb.CamRelPos = -camera.Position; + mb.BBMin = new Vector3(quad.minX, quad.minY, quad.z); + mb.BBMax = new Vector3(quad.maxX, quad.maxY, quad.z); + mb.Orientation = Quaternion.Identity; + mb.Scale = Vector3.One; + Renderer.BoundingBoxes.Add(mb); + + bbox.Minimum = mb.BBMin; + bbox.Maximum = mb.BBMax; + if (mray.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0)) + { + CurMouseHit.WaterQuad = quad; + CurMouseHit.HitDist = hitdist; + CurMouseHit.CamRel = mb.CamRelPos; + CurMouseHit.AABB = bbox; + } + } + } private void UpdateMouseHits(List ynvs) { if (SelectionMode != MapSelectionMode.NavMesh) return; @@ -4824,7 +2554,7 @@ namespace CodeWalker mb.BBMax = ynv.Nav.SectorTree.AABBMax.XYZ(); mb.Orientation = Quaternion.Identity; mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); } if ((ynv.Nav != null) && (ynv.Vertices != null) && (ynv.Indices != null) && (ynv.Polys != null)) @@ -4857,18 +2587,18 @@ namespace CodeWalker { continue; } v.Position = ynv.Vertices[ind]; - SelectionLineVerts.Add(v); + Renderer.SelectionLineVerts.Add(v); if (id == startid) { v0 = v; } else { - SelectionLineVerts.Add(v); + Renderer.SelectionLineVerts.Add(v); } if (id == lastid) { - SelectionLineVerts.Add(v0); + Renderer.SelectionLineVerts.Add(v0); } } @@ -4891,12 +2621,12 @@ namespace CodeWalker // { continue; } // v1.Position = ynv.Vertices[ind1]; // v2.Position = ynv.Vertices[ind2]; - // SelectionTriVerts.Add(v0); - // SelectionTriVerts.Add(v1); - // SelectionTriVerts.Add(v2); - // SelectionTriVerts.Add(v0); - // SelectionTriVerts.Add(v2); - // SelectionTriVerts.Add(v1); + // Renderer.SelectionTriVerts.Add(v0); + // Renderer.SelectionTriVerts.Add(v1); + // Renderer.SelectionTriVerts.Add(v2); + // Renderer.SelectionTriVerts.Add(v0); + // Renderer.SelectionTriVerts.Add(v2); + // Renderer.SelectionTriVerts.Add(v1); //} } @@ -5023,7 +2753,7 @@ namespace CodeWalker mb.BBMax = new Vector3(ynd.BBMax.X, ynd.BBMax.Y, maxz); mb.Orientation = Quaternion.Identity; mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); } if (ynd.BVH != null) @@ -5074,11 +2804,11 @@ namespace CodeWalker mb.Scale = Vector3.One; if (ln == SelectedItem.PathLink) { - HilightBoxes.Add(mb); + Renderer.HilightBoxes.Add(mb); } else { - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); } } } @@ -5132,7 +2862,7 @@ namespace CodeWalker mb.BBMax = new Vector3(linkrad, linkrad, dl); mb.Orientation = Quaternion.Invert(Quaternion.RotationLookAtRH(dir, dup)); mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); } } } @@ -5159,7 +2889,7 @@ namespace CodeWalker mb.BBMax = sr?.BVH?.Box.Maximum ?? Vector3.Zero; mb.Orientation = Quaternion.Identity; mb.Scale = Vector3.One; - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); } if (sr.BVH != null) @@ -5207,11 +2937,11 @@ namespace CodeWalker mb.Scale = Vector3.One; if (renderscenariobounds) { - HilightBoxes.Add(mb); + Renderer.HilightBoxes.Add(mb); } else { - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); } } @@ -5226,7 +2956,7 @@ namespace CodeWalker mb.BBMax = new Vector3(0.5f); mb.CamRelPos = ncl.Position - camera.Position; mb.Orientation = Quaternion.Identity; - HilightBoxes.Add(mb); + Renderer.HilightBoxes.Add(mb); //show boxes for points in the cluster @@ -5241,7 +2971,7 @@ namespace CodeWalker mb.BBMax = new Vector3(0.5f); mb.CamRelPos = clpoint.Position - camera.Position; mb.Orientation = clpoint.Orientation; - BoundingBoxes.Add(mb); + Renderer.BoundingBoxes.Add(mb); } } } @@ -5313,7 +3043,7 @@ namespace CodeWalker } if ((mhitv.Archetype != null) && (mhitv.Drawable == null)) { - mhitv.Drawable = TryGetDrawable(mhitv.Archetype); //no drawable given.. try to get it from the cache.. if it's not there, drawable info won't display... + mhitv.Drawable = gameFileCache.TryGetDrawable(mhitv.Archetype); //no drawable given.. try to get it from the cache.. if it's not there, drawable info won't display... } @@ -5432,7 +3162,7 @@ namespace CodeWalker if (mhit.HasValue) { //make sure the path link gets changed (sub-selection!) - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { SelectedItem.PathLink = mhitv.PathLink; SelectedItem.ScenarioEdge = mhitv.ScenarioEdge; @@ -5441,7 +3171,7 @@ namespace CodeWalker return; } - lock (rendersyncroot) //drawflags is used when rendering.. need that lock + lock (Renderer.RenderSyncRoot) //drawflags is used when rendering.. need that lock { if (mhit.HasValue) { @@ -5638,7 +3368,7 @@ namespace CodeWalker if (!MouseSelectEnabled) { return; } - SelectItem(LastMouseHit, CtrlPressed); + SelectItem(LastMouseHit, Input.CtrlPressed); } private void UpdateSelectionUI(bool wait) { @@ -5674,8 +3404,8 @@ namespace CodeWalker SelArchetypePropertyGrid.SelectedObject = item.Archetype; SelDrawablePropertyGrid.SelectedObject = item.Drawable; - SelectionModelDrawFlags.Clear(); - SelectionGeometryDrawFlags.Clear(); + Renderer.SelectionModelDrawFlags.Clear(); + Renderer.SelectionGeometryDrawFlags.Clear(); SelDrawableModelsTreeView.Nodes.Clear(); SelDrawableTexturesTreeView.Nodes.Clear(); if (item.Drawable != null) @@ -5883,7 +3613,7 @@ namespace CodeWalker if (!check) { - SelectionModelDrawFlags[model] = false; + Renderer.SelectionModelDrawFlags[model] = false; } if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue; @@ -5935,37 +3665,8 @@ namespace CodeWalker var model = node.Tag as DrawableModel; var geom = node.Tag as DrawableGeometry; bool rem = node.Checked; - lock (rendersyncroot) - { - if (model != null) - { - if (rem) - { - if (SelectionModelDrawFlags.ContainsKey(model)) - { - SelectionModelDrawFlags.Remove(model); - } - } - else - { - SelectionModelDrawFlags[model] = false; - } - } - if (geom != null) - { - if (rem) - { - if (SelectionGeometryDrawFlags.ContainsKey(geom)) - { - SelectionGeometryDrawFlags.Remove(geom); - } - } - else - { - SelectionGeometryDrawFlags[geom] = false; - } - } - } + + Renderer.UpdateSelectionDrawFlags(model, geom, rem); } public void SyncSelDrawableModelsTreeNode(TreeNode node) { @@ -6091,7 +3792,7 @@ namespace CodeWalker UpdateStatus("Loading timecycles..."); timecycle.Init(gameFileCache, UpdateStatus); - timecycle.SetTime(timeofday); + timecycle.SetTime(Renderer.timeofday); UpdateStatus("Loading materials..."); BoundsMaterialTypes.Init(gameFileCache); @@ -6134,7 +3835,7 @@ namespace CodeWalker Cursor = Cursors.WaitCursor; Task.Run(() => { - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { if (gameFileCache.SetDlcLevel(dlc, enable)) { @@ -6153,7 +3854,7 @@ namespace CodeWalker Cursor = Cursors.WaitCursor; Task.Run(() => { - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { if (gameFileCache.SetModsEnabled(enable)) { @@ -6206,11 +3907,11 @@ namespace CodeWalker while (formopen && !IsDisposed) //main asset loop { - gameFileCache.ContentThreadProc(); + bool fcItemsPending = gameFileCache.ContentThreadProc(); - renderableCache.ContentThreadProc(); + bool rcItemsPending = Renderer.ContentThreadProc(); - if (!(gameFileCache.ItemsStillPending || renderableCache.ItemsStillPending)) + if (!(fcItemsPending || rcItemsPending)) { Thread.Sleep(1); //sleep if there's nothing to do } @@ -6294,7 +3995,7 @@ namespace CodeWalker { CloudsComboBox.Items.Add(frag.Name); } - CloudsComboBox.SelectedIndex = Math.Max(CloudsComboBox.FindString(individualcloudfrag), 0); + CloudsComboBox.SelectedIndex = Math.Max(CloudsComboBox.FindString(Renderer.individualcloudfrag), 0); CloudParamComboBox.Items.Clear(); @@ -7439,7 +5140,7 @@ namespace CodeWalker ToolbarRotateButton.Checked = false; ToolbarScaleButton.Checked = false; - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { switch (mode) { @@ -7477,7 +5178,7 @@ namespace CodeWalker } } - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { switch (space) { @@ -7528,7 +5229,7 @@ namespace CodeWalker mode = BoundsShaderMode.Sphere; break; } - boundsmode = mode; + Renderer.boundsmode = mode; } @@ -7638,32 +5339,28 @@ namespace CodeWalker } } - lock (rendersyncroot) + + Renderer.SetCameraMode(modestr); + + switch (modestr) { - switch (modestr) - { - case "Perspective": - camera.IsOrthographic = false; - MapViewEnabled = false; - camera.UpdateProj = true; - ToolbarCameraModeButton.Image = ToolbarCameraPerspectiveButton.Image; - ToolbarCameraPerspectiveButton.Checked = true; - break; - case "Orthographic": - camera.IsOrthographic = true; - MapViewEnabled = false; - ToolbarCameraModeButton.Image = ToolbarCameraOrthographicButton.Image; - ToolbarCameraOrthographicButton.Checked = true; - break; - case "2D Map": - camera.IsOrthographic = true; - MapViewEnabled = true; - ToolbarCameraModeButton.Image = ToolbarCameraMapViewButton.Image; - ToolbarCameraMapViewButton.Checked = true; - break; - } - camera.IsMapView = MapViewEnabled; + case "Perspective": + MapViewEnabled = false; + ToolbarCameraModeButton.Image = ToolbarCameraPerspectiveButton.Image; + ToolbarCameraPerspectiveButton.Checked = true; + break; + case "Orthographic": + MapViewEnabled = false; + ToolbarCameraModeButton.Image = ToolbarCameraOrthographicButton.Image; + ToolbarCameraOrthographicButton.Checked = true; + break; + case "2D Map": + MapViewEnabled = true; + ToolbarCameraModeButton.Image = ToolbarCameraMapViewButton.Image; + ToolbarCameraMapViewButton.Checked = true; + break; } + FieldOfViewTrackBar.Enabled = !MapViewEnabled; MapViewDetailTrackBar.Enabled = MapViewEnabled; @@ -7691,19 +5388,12 @@ namespace CodeWalker 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) + StatsLabel.Text = Renderer.GetStatusText(); + + if (Renderer.timerunning) { - float fv = timeofday * 60.0f; + float fv = Renderer.timeofday * 60.0f; TimeOfDayTrackBar.Value = (int)fv; UpdateTimeOfDayLabel(); } @@ -7765,7 +5455,7 @@ namespace CodeWalker { GrabbedWidget = Widget; GrabbedWidget.IsDragging = true; - if (ShiftPressed) + if (Input.ShiftPressed) { CloneItem(); } @@ -7779,7 +5469,7 @@ namespace CodeWalker GrabbedWidget = null; } - if (CtrlPressed) + if (Input.CtrlPressed) { SpawnTestEntity(); } @@ -7889,19 +5579,21 @@ namespace CodeWalker } if (MouseRButtonDown) { - if (controllightdir) + if (Renderer.controllightdir) { - lightdirx += (dx * camera.Sensitivity); - lightdiry += (dy * camera.Sensitivity); + Renderer.lightdirx += (dx * camera.Sensitivity); + Renderer.lightdiry += (dy * camera.Sensitivity); } - else if (controltimeofday) + else if (Renderer.controltimeofday) { - timeofday += (dx - dy) / 30.0f; - while (timeofday >= 24.0f) timeofday -= 24.0f; - while (timeofday < 0.0f) timeofday += 24.0f; - timecycle.SetTime(timeofday); + 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 = timeofday * 60.0f; + float fv = tod * 60.0f; TimeOfDayTrackBar.Value = (int)fv; UpdateTimeOfDayLabel(); } @@ -7984,84 +5676,70 @@ namespace CodeWalker 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 = (!iseditmode) || (MouseLButtonDown && (GrabbedMarker == null) && (GrabbedWidget == null)); - enablemove = enablemove && (!ctrl); + Input.KeyDown(e, enablemove); - //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; + var k = e.KeyCode; + var kb = Input.keyBindings; + bool ctrl = Input.CtrlPressed; + bool shift = Input.ShiftPressed; if (!ctrl) { - if (k == keyBindings.MoveSlowerZoomIn) + if (k == kb.MoveSlowerZoomIn) { camera.MouseZoom(1); } - if (k == keyBindings.MoveFasterZoomOut) + if (k == kb.MoveFasterZoomOut) { camera.MouseZoom(-1); } } - - if (!moving) //don't trigger further actions if moving. + if (!Input.kbmoving) //don't trigger further actions if moving. { - if (!ctrl) { //switch widget modes and spaces. - if ((k == keyBindings.ExitEditMode)) + if ((k == kb.ExitEditMode)) { if (Widget.Mode == WidgetMode.Default) ToggleWidgetSpace(); else SetWidgetMode("Default"); } - if ((k == keyBindings.EditPosition))// && !enablemove) + if ((k == kb.EditPosition))// && !enablemove) { if (Widget.Mode == WidgetMode.Position) ToggleWidgetSpace(); else SetWidgetMode("Position"); } - if ((k == keyBindings.EditRotation))// && !enablemove) + if ((k == kb.EditRotation))// && !enablemove) { if (Widget.Mode == WidgetMode.Rotation) ToggleWidgetSpace(); else SetWidgetMode("Rotation"); } - if ((k == keyBindings.EditScale))// && !enablemove) + if ((k == kb.EditScale))// && !enablemove) { if (Widget.Mode == WidgetMode.Scale) ToggleWidgetSpace(); else SetWidgetMode("Scale"); } - if (k == keyBindings.ToggleMouseSelect) + if (k == kb.ToggleMouseSelect) { SetMouseSelect(!MouseSelectEnabled); } - if (k == keyBindings.ToggleToolbar) + if (k == kb.ToggleToolbar) { ToggleToolbar(); } - if (k == keyBindings.FirstPerson) + if (k == kb.FirstPerson) { SetControlMode((ControlMode == WorldControlMode.Free) ? WorldControlMode.Ped : WorldControlMode.Free); } + if (k == Keys.Delete) + { + DeleteItem(); + } } else { @@ -8108,10 +5786,7 @@ namespace CodeWalker private void WorldForm_KeyUp(object sender, KeyEventArgs e) { - bool ctrl = (e.Modifiers & Keys.Control) > 0; - bool shift = (e.Modifiers & Keys.Shift) > 0; - CtrlPressed = ctrl; - ShiftPressed = shift; + Input.KeyUp(e); if (ActiveControl is TextBox) { @@ -8124,17 +5799,6 @@ namespace CodeWalker 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; @@ -8144,13 +5808,7 @@ namespace CodeWalker private void WorldForm_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; + Input.KeyboardStop(); } private void ViewModeComboBox_SelectedIndexChanged(object sender, EventArgs e) @@ -8220,30 +5878,27 @@ namespace CodeWalker private void WireframeCheckBox_CheckedChanged(object sender, EventArgs e) { - shaders.wireframe = WireframeCheckBox.Checked; + Renderer.shaders.wireframe = WireframeCheckBox.Checked; } private void GrassCheckBox_CheckedChanged(object sender, EventArgs e) { - rendergrass = GrassCheckBox.Checked; + Renderer.rendergrass = GrassCheckBox.Checked; } private void TimedEntitiesCheckBox_CheckedChanged(object sender, EventArgs e) { - lock (rendersyncroot) - { - rendertimedents = TimedEntitiesCheckBox.Checked; - } + Renderer.rendertimedents = TimedEntitiesCheckBox.Checked; } private void TimedEntitiesAlwaysOnCheckBox_CheckedChanged(object sender, EventArgs e) { - rendertimedentsalways = TimedEntitiesAlwaysOnCheckBox.Checked; + Renderer.rendertimedentsalways = TimedEntitiesAlwaysOnCheckBox.Checked; } private void InteriorsCheckBox_CheckedChanged(object sender, EventArgs e) { - renderinteriors = InteriorsCheckBox.Checked; + Renderer.renderinteriors = InteriorsCheckBox.Checked; } private void WaterQuadsCheckBox_CheckedChanged(object sender, EventArgs e) @@ -8253,10 +5908,7 @@ namespace CodeWalker private void ProxiesCheckBox_CheckedChanged(object sender, EventArgs e) { - lock (rendersyncroot) - { - renderproxies = ProxiesCheckBox.Checked; - } + Renderer.renderproxies = ProxiesCheckBox.Checked; } private void PathsCheckBox_CheckedChanged(object sender, EventArgs e) @@ -8281,7 +5933,7 @@ namespace CodeWalker private void PathsDepthClipCheckBox_CheckedChanged(object sender, EventArgs e) { - shaders.PathsDepthClip = PathsDepthClipCheckBox.Checked; + Renderer.shaders.PathsDepthClip = PathsDepthClipCheckBox.Checked; } private void ErrorConsoleCheckBox_CheckedChanged(object sender, EventArgs e) @@ -8291,36 +5943,32 @@ namespace CodeWalker private void DynamicLODCheckBox_CheckedChanged(object sender, EventArgs e) { - usedynamiclod = DynamicLODCheckBox.Checked; - ShowYmapChildrenCheckBox.Enabled = !usedynamiclod; + Renderer.usedynamiclod = DynamicLODCheckBox.Checked; + ShowYmapChildrenCheckBox.Enabled = !Renderer.usedynamiclod; } private void DetailTrackBar_Scroll(object sender, EventArgs e) { - lodthreshold = 50.0f / (0.1f + (float)DetailTrackBar.Value); + Renderer.lodthreshold = 50.0f / (0.1f + (float)DetailTrackBar.Value); } private void WaitForChildrenCheckBox_CheckedChanged(object sender, EventArgs e) { - waitforchildrentoload = WaitForChildrenCheckBox.Checked; + Renderer.waitforchildrentoload = WaitForChildrenCheckBox.Checked; } private void ReloadShadersButton_Click(object sender, EventArgs e) { - if (currentdevice == null) return; //can't do this with no device + if (Renderer.Device == null) return; //can't do this with no device Cursor = Cursors.WaitCursor; pauserendering = true; - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { try { - if (shaders != null) - { - shaders.Dispose(); - } - shaders = new ShaderManager(currentdevice, dxman); + Renderer.ReloadShaders(); } catch (Exception ex) { @@ -8416,20 +6064,20 @@ namespace CodeWalker private void MarkerDepthClipCheckBox_CheckedChanged(object sender, EventArgs e) { - markerdepthclip = MarkerDepthClipCheckBox.Checked; + Renderer.markerdepthclip = MarkerDepthClipCheckBox.Checked; } private void ShadowsCheckBox_CheckedChanged(object sender, EventArgs e) { - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - shaders.shadows = ShadowsCheckBox.Checked; + Renderer.shaders.shadows = ShadowsCheckBox.Checked; } } private void SkydomeCheckbox_CheckedChanged(object sender, EventArgs e) { - renderskydome = SkydomeCheckBox.Checked; + Renderer.renderskydome = SkydomeCheckBox.Checked; } private void BoundsStyleComboBox_SelectedIndexChanged(object sender, EventArgs e) @@ -8441,13 +6089,13 @@ namespace CodeWalker private void BoundsDepthClipCheckBox_CheckedChanged(object sender, EventArgs e) { - renderboundsclip = BoundsDepthClipCheckBox.Checked; + Renderer.renderboundsclip = BoundsDepthClipCheckBox.Checked; } private void BoundsRangeTrackBar_Scroll(object sender, EventArgs e) { float fv = BoundsRangeTrackBar.Value; - renderboundsmaxdist = fv * fv; + Renderer.renderboundsmaxdist = fv * fv; } private void MouseSelectCheckBox_CheckedChanged(object sender, EventArgs e) @@ -8465,6 +6113,11 @@ namespace CodeWalker renderpopzones = PopZonesCheckBox.Checked; } + private void SkeletonsCheckBox_CheckedChanged(object sender, EventArgs e) + { + Renderer.renderskeletons = SkeletonsCheckBox.Checked; + } + private void AudioOuterBoundsCheckBox_CheckedChanged(object sender, EventArgs e) { renderaudioouterbounds = AudioOuterBoundsCheckBox.Checked; @@ -8646,42 +6299,42 @@ namespace CodeWalker { default: case "Default": - shaders.RenderMode = WorldRenderMode.Default; + Renderer.shaders.RenderMode = WorldRenderMode.Default; break; case "Single texture": - shaders.RenderMode = WorldRenderMode.SingleTexture; + Renderer.shaders.RenderMode = WorldRenderMode.SingleTexture; TextureSamplerComboBox.Enabled = true; TextureCoordsComboBox.Enabled = true; break; case "Vertex normals": - shaders.RenderMode = WorldRenderMode.VertexNormals; + Renderer.shaders.RenderMode = WorldRenderMode.VertexNormals; break; case "Vertex tangents": - shaders.RenderMode = WorldRenderMode.VertexTangents; + Renderer.shaders.RenderMode = WorldRenderMode.VertexTangents; break; case "Vertex colour 1": - shaders.RenderMode = WorldRenderMode.VertexColour; - shaders.RenderVertexColourIndex = 1; + Renderer.shaders.RenderMode = WorldRenderMode.VertexColour; + Renderer.shaders.RenderVertexColourIndex = 1; break; case "Vertex colour 2": - shaders.RenderMode = WorldRenderMode.VertexColour; - shaders.RenderVertexColourIndex = 2; + Renderer.shaders.RenderMode = WorldRenderMode.VertexColour; + Renderer.shaders.RenderVertexColourIndex = 2; break; case "Vertex colour 3": - shaders.RenderMode = WorldRenderMode.VertexColour; - shaders.RenderVertexColourIndex = 3; + Renderer.shaders.RenderMode = WorldRenderMode.VertexColour; + Renderer.shaders.RenderVertexColourIndex = 3; break; case "Texture coord 1": - shaders.RenderMode = WorldRenderMode.TextureCoord; - shaders.RenderTextureCoordIndex = 1; + Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord; + Renderer.shaders.RenderTextureCoordIndex = 1; break; case "Texture coord 2": - shaders.RenderMode = WorldRenderMode.TextureCoord; - shaders.RenderTextureCoordIndex = 2; + Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord; + Renderer.shaders.RenderTextureCoordIndex = 2; break; case "Texture coord 3": - shaders.RenderMode = WorldRenderMode.TextureCoord; - shaders.RenderTextureCoordIndex = 3; + Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord; + Renderer.shaders.RenderTextureCoordIndex = 3; break; } } @@ -8690,7 +6343,7 @@ namespace CodeWalker { if (TextureSamplerComboBox.SelectedItem is MetaName) { - shaders.RenderTextureSampler = (MetaName)TextureSamplerComboBox.SelectedItem; + Renderer.shaders.RenderTextureSampler = (MetaName)TextureSamplerComboBox.SelectedItem; } } @@ -8700,13 +6353,13 @@ namespace CodeWalker { default: case "Texture coord 1": - shaders.RenderTextureSamplerCoord = 1; + Renderer.shaders.RenderTextureSamplerCoord = 1; break; case "Texture coord 2": - shaders.RenderTextureSamplerCoord = 2; + Renderer.shaders.RenderTextureSamplerCoord = 2; break; case "Texture coord 3": - shaders.RenderTextureSamplerCoord = 3; + Renderer.shaders.RenderTextureSamplerCoord = 3; break; } @@ -8715,6 +6368,7 @@ namespace CodeWalker private void CollisionMeshesCheckBox_CheckedChanged(object sender, EventArgs e) { rendercollisionmeshes = CollisionMeshesCheckBox.Checked; + Renderer.rendercollisionmeshes = rendercollisionmeshes; } private void CollisionMeshRangeTrackBar_Scroll(object sender, EventArgs e) @@ -8739,13 +6393,13 @@ namespace CodeWalker private void CollisionMeshLayerDrawableCheckBox_CheckedChanged(object sender, EventArgs e) { - collisionmeshlayerdrawable = CollisionMeshLayerDrawableCheckBox.Checked; + Renderer.rendercollisionmeshlayerdrawable = CollisionMeshLayerDrawableCheckBox.Checked; } private void ControlLightDirectionCheckBox_CheckedChanged(object sender, EventArgs e) { - controllightdir = ControlLightDirectionCheckBox.Checked; - if (controllightdir) + Renderer.controllightdir = ControlLightDirectionCheckBox.Checked; + if (Renderer.controllightdir) { ControlTimeOfDayCheckBox.Checked = false; } @@ -8753,8 +6407,8 @@ namespace CodeWalker private void ControlTimeOfDayCheckBox_CheckedChanged(object sender, EventArgs e) { - controltimeofday = ControlTimeOfDayCheckBox.Checked; - if (controltimeofday) + Renderer.controltimeofday = ControlTimeOfDayCheckBox.Checked; + if (Renderer.controltimeofday) { ControlLightDirectionCheckBox.Checked = false; } @@ -8762,20 +6416,20 @@ namespace CodeWalker private void ShowYmapChildrenCheckBox_CheckedChanged(object sender, EventArgs e) { - renderchildents = ShowYmapChildrenCheckBox.Checked; + Renderer.renderchildents = ShowYmapChildrenCheckBox.Checked; } private void HDRRenderingCheckBox_CheckedChanged(object sender, EventArgs e) { - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - shaders.hdr = HDRRenderingCheckBox.Checked; + Renderer.shaders.hdr = HDRRenderingCheckBox.Checked; } } private void AnisotropicFilteringCheckBox_CheckedChanged(object sender, EventArgs e) { - shaders.AnisotropicFiltering = AnisotropicFilteringCheckBox.Checked; + Renderer.shaders.AnisotropicFiltering = AnisotropicFilteringCheckBox.Checked; } private void WorldMaxLodComboBox_SelectedIndexChanged(object sender, EventArgs e) @@ -8784,25 +6438,25 @@ namespace CodeWalker { default: case "ORPHANHD": - renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD; + Renderer.renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD; break; case "HD": - renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_HD; + Renderer.renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_HD; break; case "LOD": - renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_LOD; + Renderer.renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_LOD; break; case "SLOD1": - renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_SLOD1; + Renderer.renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_SLOD1; break; case "SLOD2": - renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_SLOD2; + Renderer.renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_SLOD2; break; case "SLOD3": - renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_SLOD3; + Renderer.renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_SLOD3; break; case "SLOD4": - renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_SLOD4; + Renderer.renderworldMaxLOD = Unk_1264241711.LODTYPES_DEPTH_SLOD4; break; } } @@ -8810,20 +6464,20 @@ namespace CodeWalker private void WorldLodDistTrackBar_Scroll(object sender, EventArgs e) { float loddist = ((float)WorldLodDistTrackBar.Value) * 0.1f; - renderworldLodDistMult = loddist; + Renderer.renderworldLodDistMult = loddist; WorldLodDistLabel.Text = loddist.ToString("0.0"); } private void WorldDetailDistTrackBar_Scroll(object sender, EventArgs e) { float detdist = ((float)WorldDetailDistTrackBar.Value) * 0.1f; - renderworldDetailDistMult = detdist; + Renderer.renderworldDetailDistMult = detdist; WorldDetailDistLabel.Text = detdist.ToString("0.0"); } private void WorldScriptedYmapsCheckBox_CheckedChanged(object sender, EventArgs e) { - ShowScriptedYmaps = WorldScriptedYmapsCheckBox.Checked; + Renderer.ShowScriptedYmaps = WorldScriptedYmapsCheckBox.Checked; } private void WorldYmapTimeFilterCheckBox_CheckedChanged(object sender, EventArgs e) @@ -8875,22 +6529,17 @@ namespace CodeWalker private void TimeOfDayTrackBar_Scroll(object sender, EventArgs e) { int v = TimeOfDayTrackBar.Value; - float fh = v / 60.0f; + float hour = v / 60.0f; UpdateTimeOfDayLabel(); - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - timeofday = fh; - timecycle.SetTime(timeofday); + Renderer.SetTimeOfDay(hour); } } private void WeatherComboBox_SelectedIndexChanged(object sender, EventArgs e) { - if (!Monitor.TryEnter(rendersyncroot, 50)) - { return; } //couldn't get a lock... - weathertype = WeatherComboBox.Text; - weather.SetNextWeather(weathertype); - Monitor.Exit(rendersyncroot); + Renderer.SetWeatherType(WeatherComboBox.Text); } private void WeatherRegionComboBox_SelectedIndexChanged(object sender, EventArgs e) @@ -8902,29 +6551,29 @@ namespace CodeWalker { //if (!Monitor.TryEnter(rendersyncroot, 50)) //{ return; } //couldn't get a lock... - individualcloudfrag = CloudsComboBox.Text; + Renderer.individualcloudfrag = CloudsComboBox.Text; //Monitor.Exit(rendersyncroot); } private void DistantLODLightsCheckBox_CheckedChanged(object sender, EventArgs e) { - renderdistlodlights = DistantLODLightsCheckBox.Checked; + Renderer.renderdistlodlights = DistantLODLightsCheckBox.Checked; } private void NaturalAmbientLightCheckBox_CheckedChanged(object sender, EventArgs e) { - rendernaturalambientlight = NaturalAmbientLightCheckBox.Checked; + Renderer.rendernaturalambientlight = NaturalAmbientLightCheckBox.Checked; } private void ArtificialAmbientLightCheckBox_CheckedChanged(object sender, EventArgs e) { - renderartificialambientlight = ArtificialAmbientLightCheckBox.Checked; + Renderer.renderartificialambientlight = ArtificialAmbientLightCheckBox.Checked; } private void TimeStartStopButton_Click(object sender, EventArgs e) { - timerunning = !timerunning; - TimeStartStopButton.Text = timerunning ? "Stop" : "Start"; + Renderer.timerunning = !Renderer.timerunning; + TimeStartStopButton.Text = Renderer.timerunning ? "Stop" : "Start"; } private void TimeSpeedTrackBar_Scroll(object sender, EventArgs e) @@ -8934,9 +6583,9 @@ namespace CodeWalker //when tv=0.5, speed=0.5 min/sec //when tv=1, speed=128 min/sec - timespeed = 128.0f * tv * tv * tv * tv * tv * tv * tv * tv; + Renderer.timespeed = 128.0f * tv * tv * tv * tv * tv * tv * tv * tv; - TimeSpeedLabel.Text = timespeed.ToString("0.###") + " min/sec"; + TimeSpeedLabel.Text = Renderer.timespeed.ToString("0.###") + " min/sec"; } private void CameraModeComboBox_SelectedIndexChanged(object sender, EventArgs e) @@ -8948,9 +6597,9 @@ namespace CodeWalker { float det = ((float)MapViewDetailTrackBar.Value) * 0.1f; MapViewDetailLabel.Text = det.ToString("0.0#"); - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { - MapViewDetail = det; + Renderer.MapViewDetail = det; } } @@ -8958,7 +6607,7 @@ namespace CodeWalker { float fov = FieldOfViewTrackBar.Value * 0.01f; FieldOfViewLabel.Text = fov.ToString("0.0#"); - lock (rendersyncroot) + lock (Renderer.RenderSyncRoot) { camera.FieldOfView = fov; camera.UpdateProj = true; @@ -9399,16 +7048,6 @@ namespace CodeWalker } - public enum WorldRenderMode - { - Default = 0, - SingleTexture = 1, - VertexNormals = 2, - VertexTangents = 3, - VertexColour = 4, - TextureCoord = 5, - } - public enum WorldControlMode { Free = 0, @@ -9420,828 +7059,5 @@ namespace CodeWalker } - public class MapIcon - { - public string Name { get; set; } - public string Filepath { get; set; } - public Texture2D Tex { get; set; } - public ShaderResourceView TexView { get; set; } - public Vector3 Center { get; set; } //in image pixels - public float Scale { get; set; } //screen pixels per icon pixel - public int TexWidth { get; set; } - public int TexHeight { get; set; } - - public MapIcon(string name, string filepath, int texw, int texh, float centerx, float centery, float scale) - { - Name = name; - Filepath = filepath; - TexWidth = texw; - TexHeight = texh; - Center = new Vector3(centerx, centery, 0.0f); - Scale = scale; - - if (!File.Exists(filepath)) - { - throw new Exception("File not found."); - } - } - - public void LoadTexture(Device device, Action errorAction) - { - try - { - if (device != null) - { - Tex = TextureLoader.CreateTexture2DFromBitmap(device, TextureLoader.LoadBitmap(new SharpDX.WIC.ImagingFactory2(), Filepath)); - TexView = new ShaderResourceView(device, Tex); - } - } - catch (Exception ex) - { - errorAction("Could not load map icon " + Filepath + " for " + Name + "!\n\n" + ex.ToString()); - } - } - - public void UnloadTexture() - { - if (TexView != null) - { - TexView.Dispose(); - TexView = null; - } - if (Tex != null) - { - Tex.Dispose(); - Tex = null; - } - } - - public override string ToString() - { - return Name; - } - } - - public class MapMarker - { - public MapIcon Icon { get; set; } - public Vector3 WorldPos { get; set; } //actual world pos - public Vector3 CamRelPos { get; set; } //updated per frame - public Vector3 ScreenPos { get; set; } //position on screen (updated per frame) - public string Name { get; set; } - public List Properties { get; set; } //additional data - public bool IsMovable { get; set; } - public float Distance { get; set; } //length of CamRelPos, updated per frame - - public void Parse(string s) - { - Vector3 p = new Vector3(0.0f); - string[] ss = s.Split(','); - if (ss.Length > 1) - { - FloatUtil.TryParse(ss[0].Trim(), out p.X); - FloatUtil.TryParse(ss[1].Trim(), out p.Y); - } - if (ss.Length > 2) - { - FloatUtil.TryParse(ss[2].Trim(), out p.Z); - } - if (ss.Length > 3) - { - Name = ss[3].Trim(); - } - else - { - Name = string.Empty; - } - for (int i = 4; i < ss.Length; i++) - { - if (Properties == null) Properties = new List(); - Properties.Add(ss[i].Trim()); - } - WorldPos = p; - } - - public override string ToString() - { - string cstr = Get3DWorldPosString(); - if (!string.IsNullOrEmpty(Name)) - { - cstr += ", " + Name; - if (Properties != null) - { - foreach (string prop in Properties) - { - cstr += ", " + prop; - } - } - } - return cstr; - } - - public string Get2DWorldPosString() - { - return string.Format(CultureInfo.InvariantCulture, "{0}, {1}", WorldPos.X, WorldPos.Y); - } - public string Get3DWorldPosString() - { - return string.Format(CultureInfo.InvariantCulture, "{0}, {1}, {2}", WorldPos.X, WorldPos.Y, WorldPos.Z); - } - - - } - - public struct MapSphere - { - public Vector3 CamRelPos { get; set; } - public float Radius { get; set; } - } - public struct MapBox - { - public Vector3 CamRelPos { get; set; } - public Vector3 BBMin { get; set; } - public Vector3 BBMax { get; set; } - public Quaternion Orientation { get; set; } - public Vector3 Scale { get; set; } - } - - [TypeConverter(typeof(ExpandableObjectConverter))] - public struct MapSelection - { - public YmapEntityDef EntityDef { get; set; } - public Archetype Archetype { get; set; } - public DrawableBase Drawable { get; set; } - public DrawableGeometry Geometry { get; set; } - public MetaWrapper EntityExtension { get; set; } - public MetaWrapper ArchetypeExtension { get; set; } - public YmapTimeCycleModifier TimeCycleModifier { get; set; } - public YmapCarGen CarGenerator { get; set; } - public YmapGrassInstanceBatch GrassBatch { get; set; } - public YmapDistantLODLights DistantLodLights { get; set; } - public YmapEntityDef MloEntityDef { get; set; } - public WaterQuad WaterQuad { get; set; } - public Bounds CollisionBounds { get; set; } - public YnvPoly NavPoly { get; set; } - public YndNode PathNode { get; set; } - public YndLink PathLink { get; set; } - public TrainTrackNode TrainTrackNode { get; set; } - public ScenarioNode ScenarioNode { get; set; } - public MCScenarioChainingEdge ScenarioEdge { get; set; } - public AudioPlacement Audio { get; set; } - - public bool MultipleSelection { get; set; } - public Vector3 MultipleSelectionCenter { get; set; } - - public BoundingBox AABB { get; set; } - public BoundingSphere BSphere { get; set; } - public int GeometryIndex { get; set; } - public Vector3 CamRel { get; set; } - public float HitDist { get; set; } - - - public bool HasValue - { - get - { - return (EntityDef != null) || - (Archetype != null) || - (Drawable != null) || - (Geometry != null) || - (EntityExtension != null) || - (ArchetypeExtension != null) || - (TimeCycleModifier != null) || - (CarGenerator != null) || - (GrassBatch != null) || - (WaterQuad != null) || - (CollisionBounds != null) || - (NavPoly != null) || - (PathNode != null) || - (TrainTrackNode != null) || - (DistantLodLights != null) || - (MloEntityDef != null) || - (ScenarioNode != null) || - (Audio != null); - } - } - - public bool HasHit - { - get { return (HitDist != float.MaxValue); } - } - - - public bool CheckForChanges(MapSelection mhit) - { - return (EntityDef != mhit.EntityDef) - || (Archetype != mhit.Archetype) - || (Drawable != mhit.Drawable) - || (TimeCycleModifier != mhit.TimeCycleModifier) - || (ArchetypeExtension != mhit.ArchetypeExtension) - || (EntityExtension != mhit.EntityExtension) - || (CarGenerator != mhit.CarGenerator) - || (MloEntityDef != mhit.MloEntityDef) - || (DistantLodLights != mhit.DistantLodLights) - || (GrassBatch != mhit.GrassBatch) - || (WaterQuad != mhit.WaterQuad) - || (CollisionBounds != mhit.CollisionBounds) - || (NavPoly != mhit.NavPoly) - || (PathNode != mhit.PathNode) - || (TrainTrackNode != mhit.TrainTrackNode) - || (ScenarioNode != mhit.ScenarioNode) - || (Audio != mhit.Audio); - } - public bool CheckForChanges() - { - return (EntityDef != null) - || (Archetype != null) - || (Drawable != null) - || (TimeCycleModifier != null) - || (ArchetypeExtension != null) - || (EntityExtension != null) - || (CarGenerator != null) - || (MloEntityDef != null) - || (DistantLodLights != null) - || (GrassBatch != null) - || (WaterQuad != null) - || (CollisionBounds != null) - || (NavPoly != null) - || (PathNode != null) - || (PathLink != null) - || (TrainTrackNode != null) - || (ScenarioNode != null) - || (Audio != null); - } - - - public void Clear() - { - EntityDef = null; - Archetype = null; - Drawable = null; - Geometry = null; - EntityExtension = null; - ArchetypeExtension = null; - TimeCycleModifier = null; - CarGenerator = null; - GrassBatch = null; - WaterQuad = null; - CollisionBounds = null; - NavPoly = null; - PathNode = null; - PathLink = null; - TrainTrackNode = null; - DistantLodLights = null; - MloEntityDef = null; - ScenarioNode = null; - ScenarioEdge = null; - Audio = null; - MultipleSelection = false; - AABB = new BoundingBox(); - GeometryIndex = 0; - CamRel = new Vector3(); - HitDist = float.MaxValue; - } - - public string GetNameString(string defval) - { - string name = defval; - if (MultipleSelection) - { - name = "Multiple items"; - } - else if (EntityDef != null) - { - name = EntityDef.CEntityDef.archetypeName.ToString(); - } - else if (Archetype != null) - { - name = Archetype.Hash.ToString(); - } - else if (TimeCycleModifier != null) - { - name = TimeCycleModifier.CTimeCycleModifier.name.ToString(); - } - else if (CarGenerator != null) - { - name = CarGenerator.CCarGen.carModel.ToString(); - } - else if (DistantLodLights != null) - { - name = DistantLodLights.Ymap?.Name ?? ""; - } - else if (CollisionBounds != null) - { - name = CollisionBounds.GetName(); - } - if (EntityExtension != null) - { - name = EntityExtension.Name; - } - if (ArchetypeExtension != null) - { - name = ArchetypeExtension.Name; - } - if (WaterQuad != null) - { - name = "WaterQuad " + WaterQuad.ToString(); - } - if (NavPoly != null) - { - name = "NavPoly " + NavPoly.ToString(); - } - if (PathNode != null) - { - name = "PathNode " + PathNode.AreaID.ToString() + "." + PathNode.NodeID.ToString(); //+ FloatUtil.GetVector3String(PathNode.Position); - } - if (TrainTrackNode != null) - { - name = "TrainTrackNode " + FloatUtil.GetVector3String(TrainTrackNode.Position); - } - if (ScenarioNode != null) - { - name = ScenarioNode.ToString(); - } - if (Audio != null) - { - name = Audio.ShortTypeName + " " + Audio.GetNameString();// FloatUtil.GetVector3String(Audio.InnerPos); - } - return name; - } - - public string GetFullNameString(string defval) - { - string name = defval; - if (MultipleSelection) - { - name = "Multiple items"; - } - else if (EntityDef != null) - { - name = EntityDef.CEntityDef.archetypeName.ToString(); - } - else if (Archetype != null) - { - name = Archetype.Hash.ToString(); - } - else if (CollisionBounds != null) - { - name = CollisionBounds.GetName(); - } - if (Geometry != null) - { - name += " (" + GeometryIndex.ToString() + ")"; - } - if (TimeCycleModifier != null) - { - name = TimeCycleModifier.CTimeCycleModifier.name.ToString(); - } - if (CarGenerator != null) - { - name = CarGenerator.NameString(); - } - if (EntityExtension != null) - { - name += ": " + EntityExtension.Name; - } - if (ArchetypeExtension != null) - { - name += ": " + ArchetypeExtension.Name; - } - if (WaterQuad != null) - { - name = "WaterQuad " + WaterQuad.ToString(); - } - if (NavPoly != null) - { - name = "NavPoly " + NavPoly.ToString(); - } - if (PathNode != null) - { - name = "PathNode " + PathNode.AreaID.ToString() + "." + PathNode.NodeID.ToString();// + FloatUtil.GetVector3String(PathNode.Position); - } - if (TrainTrackNode != null) - { - name = "TrainTrackNode " + FloatUtil.GetVector3String(TrainTrackNode.Position); - } - if (ScenarioNode != null) - { - name = ScenarioNode.ToString(); - } - if (Audio != null) - { - name = Audio.ShortTypeName + " " + Audio.GetNameString();// + FloatUtil.GetVector3String(Audio.InnerPos); - } - return name; - } - - - - public bool CanShowWidget - { - get - { - bool res = false; - - if (MultipleSelection) - { - res = true; - } - else if (EntityDef != null) - { - res = true; - } - else if (CarGenerator != null) - { - res = true; - } - else if (NavPoly != null) - { - res = true; - } - else if (PathNode != null) - { - res = true; - } - else if (TrainTrackNode != null) - { - res = true; - } - else if (ScenarioNode != null) - { - res = true; - } - else if (Audio != null) - { - res = true; - } - return res; - } - } - public Vector3 WidgetPosition - { - get - { - if (MultipleSelection) - { - return MultipleSelectionCenter; - } - else if (EntityDef != null) - { - return EntityDef.WidgetPosition; - } - else if (CarGenerator != null) - { - return CarGenerator.Position; - } - else if (NavPoly != null) - { - return NavPoly.Position; - } - else if (PathNode != null) - { - return PathNode.Position; - } - else if (TrainTrackNode != null) - { - return TrainTrackNode.Position; - } - else if (ScenarioNode != null) - { - return ScenarioNode.Position; - } - else if (Audio != null) - { - return Audio.InnerPos; - } - return Vector3.Zero; - } - } - public Quaternion WidgetRotation - { - get - { - if (MultipleSelection) - { - return Quaternion.Identity; - } - else if (EntityDef != null) - { - return EntityDef.WidgetOrientation; - } - else if (CarGenerator != null) - { - return CarGenerator.Orientation; - } - else if (NavPoly != null) - { - return Quaternion.Identity; - } - else if (PathNode != null) - { - return Quaternion.Identity; - } - else if (TrainTrackNode != null) - { - return Quaternion.Identity; - } - else if (ScenarioNode != null) - { - return ScenarioNode.Orientation; - } - else if (Audio != null) - { - return Audio.Orientation; - } - return Quaternion.Identity; - } - } - public WidgetAxis WidgetRotationAxes - { - get - { - if (MultipleSelection) - { - return WidgetAxis.XYZ; - } - else if (EntityDef != null) - { - return WidgetAxis.XYZ; - } - else if (CarGenerator != null) - { - return WidgetAxis.Z; - } - else if (NavPoly != null) - { - return WidgetAxis.XYZ; - } - else if (PathNode != null) - { - return WidgetAxis.None; - } - else if (TrainTrackNode != null) - { - return WidgetAxis.None; - } - else if (ScenarioNode != null) - { - return WidgetAxis.Z; - } - else if (Audio != null) - { - return WidgetAxis.XYZ; - } - return WidgetAxis.None; - } - } - public Vector3 WidgetScale - { - get - { - if (MultipleSelection) - { - return Vector3.One; - } - else if (EntityDef != null) - { - return EntityDef.Scale; - } - else if (CarGenerator != null) - { - return new Vector3(CarGenerator.CCarGen.perpendicularLength); - } - else if (NavPoly != null) - { - return Vector3.One; - } - else if (PathNode != null) - { - return Vector3.One; - } - else if (TrainTrackNode != null) - { - return Vector3.One; - } - else if (ScenarioNode != null) - { - return Vector3.One; - } - else if (Audio != null) - { - return Vector3.One; - } - return Vector3.One; - } - } - - - - - public void SetPosition(Vector3 newpos, Vector3 oldpos, bool editPivot) - { - if (MultipleSelection) - { - //don't do anything here for multiselection - } - else if (EntityDef != null) - { - if (editPivot) - { - EntityDef.SetPivotPositionFromWidget(newpos); - } - else - { - EntityDef.SetPositionFromWidget(newpos); - } - } - else if (CarGenerator != null) - { - CarGenerator.SetPosition(newpos); - } - else if (PathNode != null) - { - PathNode.SetPosition(newpos); - } - else if (NavPoly != null) - { - //NavPoly.SetPosition(newpos); - - //if (projectForm != null) - //{ - // projectForm.OnWorldNavPolyModified(NavPoly); - //} - } - else if (TrainTrackNode != null) - { - TrainTrackNode.SetPosition(newpos); - } - else if (ScenarioNode != null) - { - ScenarioNode.SetPosition(newpos); - } - else if (Audio != null) - { - Audio.SetPosition(newpos); - } - - } - public void SetRotation(Quaternion newrot, Quaternion oldrot, bool editPivot) - { - if (EntityDef != null) - { - if (editPivot) - { - EntityDef.SetPivotOrientationFromWidget(newrot); - } - else - { - EntityDef.SetOrientationFromWidget(newrot); - } - } - else if (CarGenerator != null) - { - CarGenerator.SetOrientation(newrot); - } - else if (ScenarioNode != null) - { - ScenarioNode.SetOrientation(newrot); - } - else if (Audio != null) - { - Audio.SetOrientation(newrot); - } - } - public void SetScale(Vector3 newscale, Vector3 oldscale, bool editPivot) - { - if (EntityDef != null) - { - EntityDef.SetScale(newscale); - } - else if (CarGenerator != null) - { - CarGenerator.SetScale(newscale); - AABB = new BoundingBox(CarGenerator.BBMin, CarGenerator.BBMax); - } - } - - - public override string ToString() - { - return GetFullNameString("[Empty]"); - } - } - - public enum MapSelectionMode - { - None = 0, - Entity = 1, - EntityExtension = 2, - ArchetypeExtension = 3, - TimeCycleModifier = 4, - CarGenerator = 5, - Grass = 6, - WaterQuad = 7, - Collision = 8, - NavMesh = 9, - Path = 10, - TrainTrack = 11, - DistantLodLights = 12, - MloInstance = 13, - Scenario = 14, - PopZone = 15, - Audio = 16, - } - - - - public class KeyBindings - { - public Keys MoveForward = Keys.W; - public Keys MoveBackward = Keys.S; - public Keys MoveLeft = Keys.A; - public Keys MoveRight = Keys.D; - public Keys MoveUp = Keys.R; - public Keys MoveDown = Keys.F; - public Keys MoveSlowerZoomIn = Keys.Z; - public Keys MoveFasterZoomOut = Keys.X; - public Keys ToggleMouseSelect = Keys.C; - public Keys ToggleToolbar = Keys.T; - public Keys ExitEditMode = Keys.Q; - public Keys EditPosition = Keys.W; - public Keys EditRotation = Keys.E; - public Keys EditScale = Keys.R; - public Keys Jump = Keys.Space; //for control mode - public Keys FirstPerson = Keys.P; - - public KeyBindings(StringCollection sc) - { - foreach (string s in sc) - { - string[] parts = s.Split(':'); - if (parts.Length == 2) - { - string sval = parts[1].Trim(); - Keys k = (Keys)Enum.Parse(typeof(Keys), sval); - SetBinding(parts[0], k); - } - } - } - - public void SetBinding(string name, Keys k) - { - switch (name) - { - case "Move Forwards": MoveForward = k; break; - case "Move Backwards": MoveBackward = k; break; - case "Move Left": MoveLeft = k; break; - case "Move Right": MoveRight = k; break; - case "Move Up": MoveUp = k; break; - case "Move Down": MoveDown = k; break; - case "Move Slower / Zoom In": MoveSlowerZoomIn = k; break; - case "Move Faster / Zoom Out": MoveFasterZoomOut = k; break; - case "Toggle Mouse Select": ToggleMouseSelect = k; break; - case "Toggle Toolbar": ToggleToolbar = k; break; - case "Exit Edit Mode": ExitEditMode = k; break; - case "Edit Position": EditPosition = k; break; - case "Edit Rotation": EditRotation = k; break; - case "Edit Scale": EditScale = k; break; - case "First Person Mode": FirstPerson = k; break; - } - } - - public StringCollection GetSetting() - { - StringCollection sc = new StringCollection(); - sc.Add(GetSettingItem("Move Forwards", MoveForward)); - sc.Add(GetSettingItem("Move Backwards", MoveBackward)); - sc.Add(GetSettingItem("Move Left", MoveLeft)); - sc.Add(GetSettingItem("Move Right", MoveRight)); - sc.Add(GetSettingItem("Move Up", MoveUp)); - sc.Add(GetSettingItem("Move Down", MoveDown)); - sc.Add(GetSettingItem("Move Slower / Zoom In", MoveSlowerZoomIn)); - sc.Add(GetSettingItem("Move Faster / Zoom Out", MoveFasterZoomOut)); - sc.Add(GetSettingItem("Toggle Mouse Select", ToggleMouseSelect)); - sc.Add(GetSettingItem("Toggle Toolbar", ToggleToolbar)); - sc.Add(GetSettingItem("Exit Edit Mode", ExitEditMode)); - sc.Add(GetSettingItem("Edit Position", EditPosition)); - sc.Add(GetSettingItem("Edit Rotation", EditRotation)); - sc.Add(GetSettingItem("Edit Scale", EditScale)); - sc.Add(GetSettingItem("First Person Mode", FirstPerson)); - return sc; - } - - private string GetSettingItem(string name, Keys val) - { - return name + ": " + val.ToString(); - } - - public KeyBindings Copy() - { - return (KeyBindings)MemberwiseClone(); - } - - } - - } diff --git a/WorldForm.resx b/WorldForm.resx index aed5002..1687a09 100644 --- a/WorldForm.resx +++ b/WorldForm.resx @@ -240,6 +240,14 @@ ufo YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB4SURBVDhP3ZC7DcAgDEQZKTMwHOvSIFriS7BlEB+HMic9 QJbvFThLUkpXzjkSpaeuzMPlEELx3jdsBauyCHBY6UWYPQI93KEljQD3jL6EGzN6x0bASyNYwkKU8Udm gd6TMnIikDJyIqjVNz8T7FgKrAwFX6lVinM3aJ05lWDPRRcAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB0SURBVDhP7ZNBCoAgEEXnSJ3BqxmetNpaMLhVv5DNRJS2 + CxIeuvA9XSjtg5mHEILPxB6U7JyLxphmSkDK1o5x9dst87SUfTXwRsYsA+paT0BGDGsVOJ92hdz3Bz4f + wGPC48uu7w5IGd+gBlpRMgYCnRwyESUj3CsQkYNFDwAAAABJRU5ErkJggg== @@ -259,14 +267,6 @@ ufo 7bHCx/miCf7qYJ1jjjYYx3Fm0nfDXfJWzhjMzuBweJJvr++b5K1dOQN7hP9AH0H96EvM83zh7q+2zsH1 L1H0fS+TJHEX+ZsBXDRobS/oRorjWB5/aqSXVkZRJKuqQnxtJEJNXCvjTu9D9kGOmhEvW5kwJiVb43wI WBXYx9R1nV75RuyHKrrnzCcGjE1u9ZyD4BugoZigQ9xrngAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB0SURBVDhP7ZNBCoAgEEXnSJ3BqxmetNpaMLhVv5DNRJS2 - CxIeuvA9XSjtg5mHEILPxB6U7JyLxphmSkDK1o5x9dst87SUfTXwRsYsA+paT0BGDGsVOJ92hdz3Bz4f - wGPC48uu7w5IGd+gBlpRMgYCnRwyESUj3CsQkYNFDwAAAABJRU5ErkJggg== @@ -352,6 +352,17 @@ ufo 4BJN+IjGo5O8ZJndGVhKxpjWWts551aih0fre+0BLaVchRAezPB2NXSSV/gVwXGYPJiVUt6ns1ghCDjn UQG86w3FToVgDcWCWS9Fvi/Ao0RVAcwUjwpyhzmf4n8BFApS5HZRwRuONGMbrIJ1JIN8O2QAAAAASUVO RK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEvSURBVDhP3dK/K0dRGMfxKxRJopCSEkLya/guUhQRmQwG + WfwIkYySgYUSKUKJlOK/MBoMFMofYLUIsfJ+f3NuF3+A8tRree5zP/fcc070f6oHT/jAPTqQj6WvXvCM + TZQgG3H58gFGcYVLtGIN15jBNDbwiGNUIg4pQx8GsQuHhrCDW8yjHyns4Q0DcCXpykM5bFzgHGPYxw1G + UIVMtMHfWUUj4nIg/KurGIYrSAZYOXDGlbhXcZlegUO8Yxzb+BlQAwNW0G0jVAYK0AwHtnCEOyQDZvGC + ObTbKIIvLMA9WIYDizhFMsDjfsAZptCA9JcdfoVBvryOSbgCe4HPTuCz+BQMKEUvJmCy96ET1ehCuAf2 + 5ZF+uwdZKEYtmuBGFSIXhtejBe5PHX7dxL+qKPoEppRHcXOtiDsAAAAASUVORK5CYII= @@ -387,17 +398,6 @@ ufo rp3fhGJScIRLzKMLFTC9cMIu3nCDVUyjB6WkYA93mEWbAyH9cMImPuA+rWMA31YwBU82kF6BS32Er/aO M8zAh+OEghpcwQ2bg3uwBW8ewFd7xQkm0IA4oaAS7bh2KHjBIZbhV/D6GJkFphrdcIP8lFrAGPwPOjCO QdQiTqrAWNICd7gPnUj+xBKaU9dxfhTkjwV/FxU+AbsiGnc46OYIAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEvSURBVDhP3dK/K0dRGMfxKxRJopCSEkLya/guUhQRmQwG - WfwIkYySgYUSKUKJlOK/MBoMFMofYLUIsfJ+f3NuF3+A8tRree5zP/fcc070f6oHT/jAPTqQj6WvXvCM - TZQgG3H58gFGcYVLtGIN15jBNDbwiGNUIg4pQx8GsQuHhrCDW8yjHyns4Q0DcCXpykM5bFzgHGPYxw1G - UIVMtMHfWUUj4nIg/KurGIYrSAZYOXDGlbhXcZlegUO8Yxzb+BlQAwNW0G0jVAYK0AwHtnCEOyQDZvGC - ObTbKIIvLMA9WIYDizhFMsDjfsAZptCA9JcdfoVBvryOSbgCe4HPTuCz+BQMKEUvJmCy96ET1ehCuAf2 - 5ZF+uwdZKEYtmuBGFSIXhtejBe5PHX7dxL+qKPoEppRHcXOtiDsAAAAASUVORK5CYII=