From fe5d5a20017ad402a894d42e67ce0f9f367bef62 Mon Sep 17 00:00:00 2001 From: codeimp Date: Tue, 9 Dec 2008 15:45:24 +0000 Subject: [PATCH] working on visual mode --- Source/Builder.csproj | 1 + Source/BuilderModes/BuilderModes.csproj | 1 + .../VisualModes/BaseVisualMode.cs | 56 ++++--- .../VisualModes/BaseVisualThing.cs | 67 ++++++++ Source/VisualModes/IVisualPickable.cs | 48 ++++++ Source/VisualModes/VisualBlockEntry.cs | 9 +- Source/VisualModes/VisualBlockMap.cs | 14 ++ Source/VisualModes/VisualGeometry.cs | 2 +- Source/VisualModes/VisualMode.cs | 91 ++++++++--- Source/VisualModes/VisualPickResult.cs | 2 +- Source/VisualModes/VisualSector.cs | 1 + Source/VisualModes/VisualThing.cs | 153 ++++++++++++++++-- 12 files changed, 381 insertions(+), 64 deletions(-) create mode 100644 Source/BuilderModes/VisualModes/BaseVisualThing.cs create mode 100644 Source/VisualModes/IVisualPickable.cs diff --git a/Source/Builder.csproj b/Source/Builder.csproj index 0bbc9d8b..a2df45a3 100644 --- a/Source/Builder.csproj +++ b/Source/Builder.csproj @@ -652,6 +652,7 @@ + diff --git a/Source/BuilderModes/BuilderModes.csproj b/Source/BuilderModes/BuilderModes.csproj index 44b15008..1b7b8e70 100644 --- a/Source/BuilderModes/BuilderModes.csproj +++ b/Source/BuilderModes/BuilderModes.csproj @@ -109,6 +109,7 @@ + diff --git a/Source/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/BuilderModes/VisualModes/BaseVisualMode.cs index 26b2eed7..a92d3bb0 100644 --- a/Source/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/BuilderModes/VisualModes/BaseVisualMode.cs @@ -100,6 +100,12 @@ namespace CodeImp.DoomBuilder.BuilderModes return new BaseVisualSector(s); } + // This creates a visual thing + protected override VisualThing CreateVisualThing(Thing t) + { + return new BaseVisualThing(t); + } + // This locks the target so that it isn't changed until unlocked public void LockTarget() { @@ -122,24 +128,34 @@ namespace CodeImp.DoomBuilder.BuilderModes VisualPickResult newtarget = PickObject(start, start + delta); // Object changed? - if(newtarget.geometry != target.geometry) + if(newtarget.picked != target.picked) { // Any result? - if(newtarget.geometry != null) + if(newtarget.picked != null) { - if(newtarget.geometry.Sidedef != null) + VisualGeometry prevgeo = null; + if((target.picked != null) && (target.picked is VisualGeometry)) + prevgeo = (target.picked as VisualGeometry); + + // Geometry picked? + if(newtarget.picked is VisualGeometry) { - if((target.geometry != null) && (target.geometry.Sidedef == null)) General.Interface.HideInfo(); - General.Interface.ShowLinedefInfo(newtarget.geometry.Sidedef.Line); - } - else if(newtarget.geometry.Sidedef == null) - { - if((target.geometry == null) || (target.geometry.Sidedef != null)) General.Interface.HideInfo(); - General.Interface.ShowSectorInfo(newtarget.geometry.Sector.Sector); - } - else - { - General.Interface.HideInfo(); + VisualGeometry pickedgeo = (newtarget.picked as VisualGeometry); + + if(pickedgeo.Sidedef != null) + { + if((prevgeo != null) && (prevgeo.Sidedef == null)) General.Interface.HideInfo(); + General.Interface.ShowLinedefInfo(pickedgeo.Sidedef.Line); + } + else if(pickedgeo.Sidedef == null) + { + if((prevgeo == null) || (prevgeo.Sidedef != null)) General.Interface.HideInfo(); + General.Interface.ShowSectorInfo(pickedgeo.Sector.Sector); + } + else + { + General.Interface.HideInfo(); + } } } else @@ -155,9 +171,9 @@ namespace CodeImp.DoomBuilder.BuilderModes // This changes the target's height private void ChangeTargetHeight(int amount) { - if(target.geometry is BaseVisualGeometrySector) + if(target.picked is BaseVisualGeometrySector) { - BaseVisualGeometrySector vgs = (target.geometry as BaseVisualGeometrySector); + BaseVisualGeometrySector vgs = (target.picked as BaseVisualGeometrySector); vgs.ChangeHeight(amount); // Rebuild sector @@ -240,25 +256,25 @@ namespace CodeImp.DoomBuilder.BuilderModes [BeginAction("visualselect", BaseAction = true)] public void BeginSelect() { - if(target.geometry != null) (target.geometry as BaseVisualGeometry).OnSelectBegin(); + if(target.picked != null) (target.picked as BaseVisualGeometry).OnSelectBegin(); } [EndAction("visualselect", BaseAction = true)] public void EndSelect() { - if(target.geometry != null) (target.geometry as BaseVisualGeometry).OnSelectEnd(); + if(target.picked != null) (target.picked as BaseVisualGeometry).OnSelectEnd(); } [BeginAction("visualedit", BaseAction = true)] public void BeginEdit() { - if(target.geometry != null) (target.geometry as BaseVisualGeometry).OnEditBegin(); + if(target.picked != null) (target.picked as BaseVisualGeometry).OnEditBegin(); } [EndAction("visualedit", BaseAction = true)] public void EndEdit() { - if(target.geometry != null) (target.geometry as BaseVisualGeometry).OnEditEnd(); + if(target.picked != null) (target.picked as BaseVisualGeometry).OnEditEnd(); } [BeginAction("raisesector8")] diff --git a/Source/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/BuilderModes/VisualModes/BaseVisualThing.cs new file mode 100644 index 00000000..aceb2205 --- /dev/null +++ b/Source/BuilderModes/VisualModes/BaseVisualThing.cs @@ -0,0 +1,67 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Reflection; +using CodeImp.DoomBuilder.Windows; +using CodeImp.DoomBuilder.IO; +using CodeImp.DoomBuilder.Map; +using CodeImp.DoomBuilder.Rendering; +using CodeImp.DoomBuilder.Geometry; +using CodeImp.DoomBuilder.Editing; +using CodeImp.DoomBuilder.VisualModes; + +#endregion + +namespace CodeImp.DoomBuilder.BuilderModes +{ + internal class BaseVisualThing : VisualThing + { + #region ================== Constants + + #endregion + + #region ================== Variables + + #endregion + + #region ================== Properties + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + public BaseVisualThing(Thing t) : base(t) + { + + } + + #endregion + + #region ================== Methods + + #endregion + } +} diff --git a/Source/VisualModes/IVisualPickable.cs b/Source/VisualModes/IVisualPickable.cs new file mode 100644 index 00000000..56eeb562 --- /dev/null +++ b/Source/VisualModes/IVisualPickable.cs @@ -0,0 +1,48 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Reflection; +using System.Drawing; +using System.ComponentModel; +using CodeImp.DoomBuilder.Map; +using SlimDX.Direct3D9; +using SlimDX; +using CodeImp.DoomBuilder.Geometry; +using System.Drawing.Imaging; +using CodeImp.DoomBuilder.Data; +using CodeImp.DoomBuilder.Editing; +using CodeImp.DoomBuilder.IO; +using CodeImp.DoomBuilder.Rendering; + +#endregion + +namespace CodeImp.DoomBuilder.VisualModes +{ + public interface IVisualPickable + { + bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir); + bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray); + } +} diff --git a/Source/VisualModes/VisualBlockEntry.cs b/Source/VisualModes/VisualBlockEntry.cs index 306d1b6c..f12a6b54 100644 --- a/Source/VisualModes/VisualBlockEntry.cs +++ b/Source/VisualModes/VisualBlockEntry.cs @@ -44,21 +44,24 @@ namespace CodeImp.DoomBuilder.VisualModes // Members private List lines; + private List things; #endregion - + #region ================== Properties public List Lines { get { return lines; } } + public List Things { get { return things; } } #endregion #region ================== Constructor - + // Constructor for empty block internal VisualBlockEntry() { - lines = new List(); + lines = new List(2); + things = new List(2); } #endregion diff --git a/Source/VisualModes/VisualBlockMap.cs b/Source/VisualModes/VisualBlockMap.cs index 87deff1b..2196fa26 100644 --- a/Source/VisualModes/VisualBlockMap.cs +++ b/Source/VisualModes/VisualBlockMap.cs @@ -271,6 +271,20 @@ namespace CodeImp.DoomBuilder.VisualModes return entries; } + // This puts a thing in the blockmap + public void AddThingsSet(ICollection things) + { + foreach(Thing t in things) AddThing(t); + } + + // This puts a thing in the blockmap + public void AddThing(Thing t) + { + Point p = GetBlockCoordinates(t.Position); + VisualBlockEntry block = GetBlock(p); + block.Things.Add(t); + } + // This puts a whole set of linedefs in the blocks they cross public void AddLinedefsSet(ICollection lines) { diff --git a/Source/VisualModes/VisualGeometry.cs b/Source/VisualModes/VisualGeometry.cs index 2bf55d1c..6942f018 100644 --- a/Source/VisualModes/VisualGeometry.cs +++ b/Source/VisualModes/VisualGeometry.cs @@ -40,7 +40,7 @@ using CodeImp.DoomBuilder.Rendering; namespace CodeImp.DoomBuilder.VisualModes { - public abstract class VisualGeometry : IComparable + public abstract class VisualGeometry : IVisualPickable, IComparable { #region ================== Variables diff --git a/Source/VisualModes/VisualMode.cs b/Source/VisualModes/VisualMode.cs index 22989e7e..3f252ef5 100644 --- a/Source/VisualModes/VisualMode.cs +++ b/Source/VisualModes/VisualMode.cs @@ -76,8 +76,10 @@ namespace CodeImp.DoomBuilder.VisualModes // Map protected VisualBlockMap blockmap; + protected Dictionary allthings; protected Dictionary allsectors; protected List visibleblocks; + protected List visiblethings; protected Dictionary visiblesectors; protected List visiblegeometry; @@ -105,11 +107,13 @@ namespace CodeImp.DoomBuilder.VisualModes this.camanglez = Angle2D.PI; this.blockmap = new VisualBlockMap(); this.allsectors = new Dictionary(General.Map.Map.Sectors.Count); + this.allthings = new Dictionary(General.Map.Map.Things.Count); this.visibleblocks = new List(); this.visiblesectors = new Dictionary(50); this.visiblegeometry = new List(200); + this.visiblethings = new List(100); } - + // Disposer public override void Dispose() { @@ -122,7 +126,9 @@ namespace CodeImp.DoomBuilder.VisualModes visiblesectors = null; visiblegeometry = null; visibleblocks = null; + visiblethings = null; allsectors = null; + allthings = null; blockmap = null; // Done @@ -199,9 +205,11 @@ namespace CodeImp.DoomBuilder.VisualModes base.OnUndoEnd(); allsectors.Clear(); + allthings.Clear(); visiblesectors.Clear(); visibleblocks.Clear(); visiblegeometry.Clear(); + visiblethings.Clear(); // Make new blockmap if(blockmap != null) @@ -230,10 +238,12 @@ namespace CodeImp.DoomBuilder.VisualModes base.OnRedoEnd(); allsectors.Clear(); + allthings.Clear(); visiblesectors.Clear(); visibleblocks.Clear(); visiblegeometry.Clear(); - + visiblethings.Clear(); + // Make new blockmap if(blockmap != null) { @@ -335,7 +345,7 @@ namespace CodeImp.DoomBuilder.VisualModes #endregion #region ================== Visibility Culling - + // This preforms visibility culling private void DoCulling() { @@ -349,8 +359,10 @@ namespace CodeImp.DoomBuilder.VisualModes // Fill visiblity collections visiblesectors = new Dictionary(visiblesectors.Count); visiblegeometry = new List(visiblegeometry.Capacity); + visiblethings = new List(visiblethings.Capacity); foreach(VisualBlockEntry block in visibleblocks) { + // Lines foreach(Linedef ld in block.Lines) { // Line not already processed? @@ -358,7 +370,7 @@ namespace CodeImp.DoomBuilder.VisualModes { // Add line if not added yet visiblelines.Add(ld, ld); - + // Which side of the line is the camera on? if(ld.SideOfLine(campos2d) < 0) { @@ -372,8 +384,27 @@ namespace CodeImp.DoomBuilder.VisualModes } } } + + // Things + foreach(Thing t in block.Things) + { + VisualThing vt; + + if(allthings.ContainsKey(t)) + { + vt = allthings[t]; + } + else + { + // Create new visual thing + vt = CreateVisualThing(t); + allthings.Add(t, vt); + } + + visiblethings.Add(vt); + } } - + // Find camera sector Linedef nld = MapSet.NearestLinedef(visiblelines.Values, campos2d); if(nld != null) @@ -419,7 +450,7 @@ namespace CodeImp.DoomBuilder.VisualModes private void ProcessSidedefCulling(Sidedef sd) { VisualSector vs; - + // Find the visualsector and make it if needed if(allsectors.ContainsKey(sd.Sector)) { @@ -432,7 +463,7 @@ namespace CodeImp.DoomBuilder.VisualModes vs = CreateVisualSector(sd.Sector); allsectors.Add(sd.Sector, vs); } - + // Add to visible sectors if not added yet if(!visiblesectors.ContainsKey(sd.Sector)) { @@ -475,7 +506,7 @@ namespace CodeImp.DoomBuilder.VisualModes Vector3D delta = to - from; // Setup no result - result.geometry = null; + result.picked = null; result.hitpos = new Vector3D(); result.u_ray = 1.0f; @@ -485,14 +516,14 @@ namespace CodeImp.DoomBuilder.VisualModes // Make collections Dictionary lines = new Dictionary(blocks.Count * 10); Dictionary sectors = new Dictionary(blocks.Count * 10); - List potentialgeometry = new List(blocks.Count * 10); + List pickables = new List(blocks.Count * 10); // Add geometry from the camera sector if((camsector != null) && allsectors.ContainsKey(camsector)) { VisualSector vs = allsectors[camsector]; sectors.Add(camsector, vs); - potentialgeometry.AddRange(vs.FixedGeometry); + foreach(VisualGeometry g in vs.FixedGeometry) pickables.Add(g); } // Go for all lines to see which ones we intersect @@ -531,16 +562,18 @@ namespace CodeImp.DoomBuilder.VisualModes if(!sectors.ContainsKey(ld.Front.Sector)) { sectors.Add(ld.Front.Sector, vs); - potentialgeometry.AddRange(vs.FixedGeometry); + foreach(VisualGeometry g in vs.FixedGeometry) pickables.Add(g); } // Add sidedef if on the front side if(side < 0.0f) { - int previndex = potentialgeometry.Count; - potentialgeometry.AddRange(vs.GetSidedefGeometry(ld.Front)); - for(int i = previndex; i < potentialgeometry.Count; i++) - potentialgeometry[i].SetPickResults(intersect, u); + List sidedefgeo = vs.GetSidedefGeometry(ld.Front); + foreach(VisualGeometry g in sidedefgeo) + { + g.SetPickResults(intersect, u); + pickables.Add(g); + } } } } @@ -557,16 +590,18 @@ namespace CodeImp.DoomBuilder.VisualModes if(!sectors.ContainsKey(ld.Back.Sector)) { sectors.Add(ld.Back.Sector, vs); - potentialgeometry.AddRange(vs.FixedGeometry); + foreach(VisualGeometry g in vs.FixedGeometry) pickables.Add(g); } // Add sidedef if on the front side if(side > 0.0f) { - int previndex = potentialgeometry.Count; - potentialgeometry.AddRange(vs.GetSidedefGeometry(ld.Back)); - for(int i = previndex; i < potentialgeometry.Count; i++) - potentialgeometry[i].SetPickResults(intersect, u); + List sidedefgeo = vs.GetSidedefGeometry(ld.Back); + foreach(VisualGeometry g in sidedefgeo) + { + g.SetPickResults(intersect, u); + pickables.Add(g); + } } } } @@ -580,24 +615,24 @@ namespace CodeImp.DoomBuilder.VisualModes // This is still too much for accurate intersection testing, so we do a fast reject pass first. Vector3D direction = to - from; direction = direction.GetNormal(); - List likelygeometry = new List(potentialgeometry.Count); - foreach(VisualGeometry g in potentialgeometry) + List potentialpicks = new List(pickables.Count); + foreach(IVisualPickable p in pickables) { - if(g.PickFastReject(from, to, direction)) likelygeometry.Add(g); + if(p.PickFastReject(from, to, direction)) potentialpicks.Add(p); } // Now we do an accurate intersection test for all resulting geometry // We keep only the closest hit! - foreach(VisualGeometry g in likelygeometry) + foreach(IVisualPickable p in potentialpicks) { float u = result.u_ray; - if(g.PickAccurate(from, to, direction, ref u)) + if(p.PickAccurate(from, to, direction, ref u)) { // Closer than previous find? if((u > 0.0f) && (u < result.u_ray)) { result.u_ray = u; - result.geometry = g; + result.picked = p; } } } @@ -615,6 +650,9 @@ namespace CodeImp.DoomBuilder.VisualModes // This creates a visual sector protected abstract VisualSector CreateVisualSector(Sector s); + + // This creates a visual thing + protected abstract VisualThing CreateVisualThing(Thing t); // This returns a visual sector protected VisualSector GetVisualSector(Sector s) @@ -632,6 +670,7 @@ namespace CodeImp.DoomBuilder.VisualModes protected virtual void FillBlockMap() { blockmap.AddLinedefsSet(General.Map.Map.Linedefs); + blockmap.AddThingsSet(General.Map.Map.Things); } // Processing diff --git a/Source/VisualModes/VisualPickResult.cs b/Source/VisualModes/VisualPickResult.cs index 2062bf70..76bbde6f 100644 --- a/Source/VisualModes/VisualPickResult.cs +++ b/Source/VisualModes/VisualPickResult.cs @@ -41,7 +41,7 @@ namespace CodeImp.DoomBuilder.VisualModes public struct VisualPickResult { // Members - public VisualGeometry geometry; + public IVisualPickable picked; public float u_ray; public Vector3D hitpos; } diff --git a/Source/VisualModes/VisualSector.cs b/Source/VisualModes/VisualSector.cs index 424e8ce0..9cc152ec 100644 --- a/Source/VisualModes/VisualSector.cs +++ b/Source/VisualModes/VisualSector.cs @@ -69,6 +69,7 @@ namespace CodeImp.DoomBuilder.VisualModes internal List AllGeometry { get { return allgeometry; } } internal VertexBuffer GeometryBuffer { get { return geobuffer; } } internal bool NeedsUpdateGeo { get { return updategeo; } set { updategeo |= value; } } + public bool IsDisposed { get { return isdisposed; } } public Sector Sector { get { return sector; } } diff --git a/Source/VisualModes/VisualThing.cs b/Source/VisualModes/VisualThing.cs index 70a2bda3..307a32e2 100644 --- a/Source/VisualModes/VisualThing.cs +++ b/Source/VisualModes/VisualThing.cs @@ -40,44 +40,171 @@ using CodeImp.DoomBuilder.Rendering; namespace CodeImp.DoomBuilder.VisualModes { - public abstract class VisualThing : IComparable + public abstract class VisualThing : IVisualPickable, ID3DResource, IComparable { #region ================== Constants - + #endregion - + #region ================== Variables - + // Thing private Thing thing; - + + // Texture + private ImageData texture; + + // Geometry + private WorldVertex[] spritevertices; + private WorldVertex[] cagevertices; + private VertexBuffer geobuffer; + private bool updategeo; + private int spritetriangles; + private int cagetriangles; + + // Disposing + private bool isdisposed = false; + #endregion - + #region ================== Properties - + + internal VertexBuffer GeometryBuffer { get { return geobuffer; } } + internal bool NeedsUpdateGeo { get { return updategeo; } } + internal int SpriteTriangles { get { return spritetriangles; } } + internal int CageTriangles { get { return cagetriangles; } } + internal int CageOffset { get { return spritevertices.Length; } } + public Thing Thing { get { return thing; } } - + public bool IsDisposed { get { return isdisposed; } } + #endregion - + #region ================== Constructor / Destructor - + // Constructor public VisualThing(Thing t) { // Initialize this.thing = t; + + // Register as resource + General.Map.Graphics.RegisterResource(this); } + // Disposer + public virtual void Dispose() + { + // Not already disposed? + if(!isdisposed) + { + // Clean up + if(geobuffer != null) geobuffer.Dispose(); + geobuffer = null; + + // Unregister resource + General.Map.Graphics.UnregisterResource(this); + + // Done + isdisposed = true; + } + } + #endregion - + #region ================== Methods - + + // This is called before a device is reset + // (when resized or display adapter was changed) + public void UnloadResource() + { + // Trash geometry buffer + if(geobuffer != null) geobuffer.Dispose(); + geobuffer = null; + updategeo = true; + } + + // This is called resets when the device is reset + // (when resized or display adapter was changed) + public void ReloadResource() + { + // Make new geometry + //Update(); + } + // This compares for sorting by sprite public int CompareTo(VisualThing other) { - return 0; + return Math.Sign(this.texture.LongName - other.texture.LongName); + } + + // This sets the vertices for the thing sprite + protected void SetSpriteVertices(ICollection verts) + { + // Copy vertices + spritevertices = new WorldVertex[verts.Count]; + verts.CopyTo(spritevertices, 0); + spritetriangles = spritevertices.Length / 3; + updategeo = true; + } + + // This sets the vertices for the thing cage + protected void SetCageVertices(ICollection verts) + { + // Copy vertices + cagevertices = new WorldVertex[verts.Count]; + verts.CopyTo(cagevertices, 0); + cagetriangles = cagevertices.Length / 3; + updategeo = true; } + // This updates the visual sector + public void Update() + { + // Trash geometry buffer + if(geobuffer != null) geobuffer.Dispose(); + geobuffer = null; + + // Count the number of vertices there are + int numverts = spritevertices.Length + cagevertices.Length; + + // Any vertics? + if(numverts > 0) + { + // Make a new buffer + geobuffer = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * numverts, + Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default); + + // Fill the buffer + DataStream bufferstream = geobuffer.Lock(0, WorldVertex.Stride * numverts, LockFlags.Discard); + bufferstream.WriteRange(spritevertices); + bufferstream.WriteRange(cagevertices); + geobuffer.Unlock(); + bufferstream.Dispose(); + } + + // Done + updategeo = false; + } + + /// + /// This is called when the thing must be tested for line intersection. This should reject + /// as fast as possible to rule out all geometry that certainly does not touch the line. + /// + public virtual bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir) + { + return false; + } + + /// + /// This is called when the thing must be tested for line intersection. This should perform + /// accurate hit detection and set u_ray to the position on the ray where this hits the geometry. + /// + public virtual bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray) + { + return false; + } + #endregion } }