Octree.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. namespace AtomicEngine
  5. {
  6. [StructLayout(LayoutKind.Sequential)]
  7. public struct RayQueryResult
  8. {
  9. public Vector3 Position;
  10. public Vector3 Normal;
  11. public Vector2 TextureUV;
  12. public float Distance;
  13. IntPtr drawablePtr;
  14. IntPtr nodePtr;
  15. // Optimize
  16. public Drawable Drawable => NativeCore.WrapNative<Drawable>(drawablePtr);
  17. public Node Node => NativeCore.WrapNative<Node>(nodePtr);
  18. public uint SubObject;
  19. }
  20. public class RayOctreeQuery
  21. {
  22. /// Construct with ray and query parameters.
  23. public RayOctreeQuery(Ray ray, RayQueryLevel level = RayQueryLevel.RAY_TRIANGLE, float maxDistance = Single.PositiveInfinity, uint drawableFlags = Constants.DRAWABLE_ANY, uint viewMask = Constants.DEFAULT_VIEWMASK)
  24. {
  25. this.Ray = ray;
  26. this.Level = level;
  27. this.MaxDistance = maxDistance;
  28. this.DrawableFlags = drawableFlags;
  29. this.ViewMask = viewMask;
  30. }
  31. public List<RayQueryResult> Results = new List<RayQueryResult>();
  32. /// Ray.
  33. public Ray Ray;
  34. /// Drawable flags to include.
  35. public uint DrawableFlags;
  36. /// Drawable layers to include.
  37. public uint ViewMask;
  38. /// Maximum ray distance.
  39. public float MaxDistance;
  40. /// Raycast detail level.
  41. public RayQueryLevel Level;
  42. }
  43. public partial class Octree : Component
  44. {
  45. /// Return the closest drawable object by a ray query.
  46. public void RaycastSingle(RayOctreeQuery query)
  47. {
  48. Raycast(query, true);
  49. }
  50. public void Raycast(RayOctreeQuery query, bool single = false)
  51. {
  52. query.Results.Clear();
  53. if (query.Ray == null)
  54. return;
  55. int count;
  56. IntPtr resultVector;
  57. var ptr = csi_Atomic_Octree_Raycast(nativeInstance, ref query.Ray, ref query.Level, query.MaxDistance, query.DrawableFlags, query.ViewMask, single, out resultVector, out count);
  58. if (ptr == IntPtr.Zero)
  59. {
  60. return;
  61. }
  62. int structSize = Marshal.SizeOf(typeof(RayQueryResult));
  63. for (int i = 0; i < count; i++)
  64. {
  65. IntPtr data = new IntPtr(ptr.ToInt64() + structSize * i);
  66. RayQueryResult item = (RayQueryResult)Marshal.PtrToStructure(data, typeof(RayQueryResult));
  67. query.Results.Add(item);
  68. }
  69. csi_Atomic_Octree_Raycast_FreeResult(resultVector);
  70. }
  71. // Any resultVector returned here, must be freed with csi_Atomic_Octree_Raycast_FreeResult
  72. [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
  73. internal static extern IntPtr csi_Atomic_Octree_Raycast(IntPtr self, ref Ray ray, ref RayQueryLevel level, float maxDistance, uint drawableFlags, uint viewMask, bool single, out IntPtr resultVector, out int count);
  74. [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
  75. internal static extern IntPtr csi_Atomic_Octree_Raycast_FreeResult(IntPtr resultVector);
  76. };
  77. }