Browse Source

Adding Frustum to bindings (C# primarily as JS/TS need stack marshaling helpers)

Josh Engebretson 9 years ago
parent
commit
9ecd830954

+ 29 - 9
Script/AtomicNET/AtomicNET/Application/Application.cs

@@ -45,18 +45,38 @@ namespace AtomicEngine
 
 
             appDelegate = (AppDelegate)Activator.CreateInstance(appDelegateType);
             appDelegate = (AppDelegate)Activator.CreateInstance(appDelegateType);
 
 
-            appDelegate.Start();
-
-            // Managed code in charge of main loop
-            while (app.RunFrame())
+            try
             {
             {
-                appDelegate.PostFrame();
-            }
 
 
-            appDelegate.Shutdown();
 
 
-            // Shut 'er down
-            app.Shutdown();
+                appDelegate.Start();
+
+                // Managed code in charge of main loop
+                while (app.RunFrame())
+                {
+                    appDelegate.PostFrame();
+                }
+
+                appDelegate.Shutdown();
+
+                // Shut 'er down
+                app.Shutdown();
+            }
+            catch (Exception e)
+            {
+                if (e.InnerException != null)
+                {
+                    Log.Error(e.InnerException.StackTrace);
+                    // rethrow inner exception
+                    throw e.InnerException;
+                }
+                else
+                {
+                    Log.Error(e.StackTrace);
+                    // rethrow
+                    throw e;
+                }
+            }
 
 
             return 0;
             return 0;
         }
         }

+ 172 - 0
Script/AtomicNET/AtomicNET/Math/Frustum.cs

@@ -0,0 +1,172 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AtomicEngine
+{
+    [StructLayout(LayoutKind.Sequential)]
+    public unsafe struct Frustum
+    {
+        /// <summary>
+        /// Define with projection parameters and a transform.
+        /// </summary>
+        public void Define(float fov, float aspectRatio, float zoom, float nearZ, float farZ, Vector3 position, Quaternion rotation)
+        {
+            csi_Atomic_Frustum_Define(ref this, fov, aspectRatio, zoom, nearZ, farZ, ref position, ref rotation);
+        }
+
+        /// <summary>
+        /// Define with projection parameters
+        /// </summary>
+        public void Define(float fov, float aspectRatio, float zoom, float nearZ, float farZ)
+        {
+            var zero = Vector3.Zero;
+            var identity = Quaternion.Identity;
+
+            csi_Atomic_Frustum_Define(ref this, fov, aspectRatio, zoom, nearZ, farZ, ref zero, ref identity);
+        }
+
+        /// <summary>
+        /// Define with orthographic projection parameters and a transform.
+        /// </summary>
+        public void DefineOrtho(float orthoSize, float aspectRatio, float zoom, float nearZ, float farZ, Vector3 position, Quaternion rotation)
+        {
+            csi_Atomic_Frustum_DefineOrtho(ref this, orthoSize, aspectRatio, zoom, nearZ, farZ, ref position, ref rotation);
+        }
+
+        /// <summary>
+        /// Define with orthographic projection parameters.
+        /// </summary>
+        public void DefineOrtho(float orthoSize, float aspectRatio, float zoom, float nearZ, float farZ)
+        {
+            var zero = Vector3.Zero;
+            var identity = Quaternion.Identity;
+
+            csi_Atomic_Frustum_DefineOrtho(ref this, orthoSize, aspectRatio, zoom, nearZ, farZ, ref zero, ref identity);
+        }
+
+        /// <summary>
+        /// Test if a point is inside or outside.
+        /// </summary>
+        public Intersection IsInside(Vector3 point)
+        {
+            for (uint i = 0; i < Constants.NUM_FRUSTUM_PLANES; ++i)
+            {
+                if (Planes[i].Distance(point) < 0.0f)
+                    return Intersection.OUTSIDE;
+            }
+
+            return Intersection.INSIDE;
+        }
+
+        /// <summary>
+        /// Test if a bounding box is inside, outside or intersects.
+        /// </summary>
+        public Intersection IsInside(BoundingBox box)
+        {
+            return csi_Atomic_Frustum_IsInside_BoundingBox(ref this, ref box);
+        }
+
+        /// <summary>
+        /// Test if a bounding box is (partially) inside or outside.
+        /// </summary>
+        Intersection IsInsideFast(BoundingBox box)
+        {
+            return csi_Atomic_Frustum_IsInsideFast_BoundingBox(ref this, ref box);
+        }
+
+        /// <summary>
+        /// Return distance of a point to the frustum, or 0 if inside.
+        /// </summary>
+        float Distance(Vector3 point)
+        {
+            return csi_Atomic_Frustum_Distance(ref this, ref point);
+        }
+
+        public Plane[] Planes
+        {
+            get
+            {
+                if (planes == null)
+                {
+                    planes = new Plane[Constants.NUM_FRUSTUM_PLANES];
+
+                    for (uint i = 0; i < Constants.NUM_FRUSTUM_PLANES; i++)
+                    {
+                        planes[i] = new Plane();
+                    }
+                }
+
+                return planes;
+            }
+
+        }
+
+        public Vector3[] Vertices
+        {
+            get
+            {
+                if (vertices == null)
+                {
+                    vertices = new Vector3[Constants.NUM_FRUSTUM_VERTICES];
+
+                    for (uint i = 0; i < Constants.NUM_FRUSTUM_VERTICES; i++)
+                    {
+                        vertices[i] = new Vector3();
+                    }
+                }
+
+                return vertices;
+            }
+
+        }
+
+
+        public override string ToString()
+        {
+            StringBuilder builder = new StringBuilder();
+
+            // ensure planes is initialized
+            var oplanes = Planes;
+
+            builder.Append("Frustum Planes:\n");
+
+            for (uint i = 0; i < Constants.NUM_FRUSTUM_PLANES; i++)
+            {
+                builder.Append(String.Format("{0} : {1} - ", oplanes[i].Normal.ToString(), oplanes[i].D));
+            }
+
+            return builder.ToString();
+
+        }
+
+        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+        private static extern void csi_Atomic_Frustum_Define(ref Frustum self, float fov, float aspectRatio, float zoom, float nearZ, float farZ, ref Vector3 position, ref Quaternion rotation);
+
+        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+        private static extern void csi_Atomic_Frustum_DefineOrtho(ref Frustum self, float orthoSize, float aspectRatio, float zoom, float nearZ, float farZ, ref Vector3 position, ref Quaternion rotation);
+
+        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+        private static extern Intersection csi_Atomic_Frustum_IsInside_Vector3(ref Frustum self, ref Vector3 point);
+
+        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+        private static extern Intersection csi_Atomic_Frustum_IsInside_BoundingBox(ref Frustum self, ref BoundingBox bbox);
+
+        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+        private static extern Intersection csi_Atomic_Frustum_IsInsideFast_BoundingBox(ref Frustum self, ref BoundingBox box);
+
+        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+        private static extern float csi_Atomic_Frustum_Distance(ref Frustum self, ref Vector3 point);
+
+        // marking planes/vertices as private causes mono error loading type?
+        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = sizeOfPlaneArray)]
+        internal Plane[] planes;
+
+        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = sizeOfVerticesArray)]
+        internal Vector3[] vertices;
+
+        private const int sizeOfPlaneArray = (int)(28 * Constants.NUM_FRUSTUM_PLANES);
+        private const int sizeOfVerticesArray = (int)(12 * Constants.NUM_FRUSTUM_VERTICES);
+
+    }
+}

+ 7 - 0
Script/AtomicNET/AtomicNET/Math/Plane.cs

@@ -40,5 +40,12 @@ namespace AtomicEngine
             AbsNormal = new Vector3(Math.Abs(plane.X), Math.Abs(plane.Y), Math.Abs(plane.Z));
             AbsNormal = new Vector3(Math.Abs(plane.X), Math.Abs(plane.Y), Math.Abs(plane.Z));
             D = plane.W;
             D = plane.W;
         }
         }
+
+        /// Return signed distance to a point.
+        public float Distance(Vector3 point)  
+        { 
+            return Vector3.Dot(Normal, point) + D; 
+        }
+
     }
     }
 }
 }

+ 1 - 1
Script/Packages/Atomic/Math.json

@@ -1,5 +1,5 @@
 {
 {
 	"name" : "Math",
 	"name" : "Math",
 	"sources" : ["Source/Atomic/Math"],
 	"sources" : ["Source/Atomic/Math"],
-	"classes" : ["Color", "Vector2", "Vector3", "Vector4", "Quaternion", "BoundingBox", "Rect", "IntRect", "IntVector2"]
+	"classes" : ["Color", "Vector2", "Vector3", "Vector4", "Quaternion", "BoundingBox", "Rect", "IntRect", "IntVector2", "Frustum"]
 }
 }

+ 28 - 0
Source/Atomic/Math/Frustum.h

@@ -181,6 +181,34 @@ public:
     Plane planes_[NUM_FRUSTUM_PLANES];
     Plane planes_[NUM_FRUSTUM_PLANES];
     /// Frustum vertices.
     /// Frustum vertices.
     Vector3 vertices_[NUM_FRUSTUM_VERTICES];
     Vector3 vertices_[NUM_FRUSTUM_VERTICES];
+
+    // ATOMIC BEGIN
+    /// Construct from a float array for bindings
+    explicit Frustum(const float* data)
+    {
+        // unpack planes
+        for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
+        {
+            planes_[i].normal_ = Vector3(data);
+            data += 3;
+            planes_[i].absNormal_ = Vector3(data);
+            data += 3;
+            planes_[i].d_ = *data;
+            data++;
+        }
+
+        // unpack vertices
+        for (unsigned i = 0; i < NUM_FRUSTUM_VERTICES; ++i)
+        {
+            vertices_[i] = Vector3(data);
+            data += 3;
+        }
+
+    }
+
+    /// Return float data for bindings
+    const float* Data() const { return (float*) &planes_; }
+    // ATOMIC END
 };
 };
 
 
 }
 }

+ 63 - 0
Source/AtomicNET/NETNative/NETCInterop.cpp

@@ -607,6 +607,69 @@ namespace Atomic
             return new CSComponent(NETCore::GetContext());
             return new CSComponent(NETCore::GetContext());
         }
         }
 
 
+        // Frustum
+
+        ATOMIC_EXPORT_API void csi_Atomic_Frustum_Define(Frustum* self, float fov, float aspectRatio, float zoom, float nearZ, float farZ, Vector3* position, Quaternion* rotation)
+        {
+            if (!self || !position || !rotation)
+            {
+                return;
+            }
+
+            self->Define(fov, aspectRatio, zoom, nearZ, farZ, Matrix3x4(*position, *rotation, 1.0f));
+
+        }
+
+        ATOMIC_EXPORT_API void csi_Atomic_Frustum_DefineOrtho(Frustum* self, float orthoSize, float aspectRatio, float zoom, float nearZ, float farZ, Vector3* position, Quaternion* rotation)
+        {
+            if (!self || !position || !rotation)
+            {
+                return;
+            }
+
+            self->DefineOrtho(orthoSize, aspectRatio, zoom, nearZ, farZ, Matrix3x4(*position, *rotation, 1.0f));
+
+        }
+
+        ATOMIC_EXPORT_API Intersection csi_Atomic_Frustum_IsInside_Vector3(Frustum* self, Vector3* point)
+        {
+            if (!self || !point)
+            {
+                return OUTSIDE;
+            }
+
+            return self->IsInside(*point);
+        }
+
+        ATOMIC_EXPORT_API Intersection csi_Atomic_Frustum_IsInside_BoundingBox(Frustum* self, BoundingBox* bbox)
+        {
+            if (!self || !bbox)
+            {
+                return OUTSIDE;
+            }
+
+            return self->IsInside(*bbox);
+        }
+
+        ATOMIC_EXPORT_API Intersection csi_Atomic_Frustum_IsInsideFast_BoundingBox(Frustum* self, BoundingBox* bbox)
+        {
+            if (!self || !bbox)
+            {
+                return OUTSIDE;
+            }
+
+            return self->IsInsideFast(*bbox);
+        }
+
+        ATOMIC_EXPORT_API float csi_Atomic_Frustum_Distance(Frustum* self, Vector3* point)
+        {
+            if (!self || !point)
+            {
+                return 0.0f;
+            }
+
+            return self->Distance(*point);
+        }
 
 
 
 
 #ifdef ATOMIC_PLATFORM_IOS
 #ifdef ATOMIC_PLATFORM_IOS

+ 3 - 0
Source/AtomicPlayer/Player.h

@@ -63,6 +63,9 @@ public:
     /// Unload all loaded scenes
     /// Unload all loaded scenes
     void UnloadAllScenes();    
     void UnloadAllScenes();    
 
 
+    /// Get the player default viewport
+    Viewport* GetViewport() const { return viewport_; }
+
 private:
 private:
 
 
     void HandleExitRequested(StringHash eventType, VariantMap& eventData);
     void HandleExitRequested(StringHash eventType, VariantMap& eventData);

+ 8 - 0
Source/ToolCore/JSBind/JSBClass.cpp

@@ -20,6 +20,7 @@
 // THE SOFTWARE.
 // THE SOFTWARE.
 //
 //
 
 
+#include <Atomic/Math/Plane.h>
 #include <Atomic/Core/ProcessUtils.h>
 #include <Atomic/Core/ProcessUtils.h>
 #include <Atomic/IO/Log.h>
 #include <Atomic/IO/Log.h>
 #include <Atomic/IO/File.h>
 #include <Atomic/IO/File.h>
@@ -160,6 +161,13 @@ JSBClass::JSBClass(Context* context, JSBModule *module, const String& name, cons
         numberArrayElements_ = 2;
         numberArrayElements_ = 2;
         arrayElementType_ = "int";
         arrayElementType_ = "int";
     }
     }
+    else if (name_ == "Frustum")
+    {
+        // NUM_FRUSTUM_PLANES = 6;
+        numberArrayElements_ = (int) ((sizeof(Plane) * 6) / sizeof(float));
+        // NUM_FRUSTUM_VERTICES = 8;
+        numberArrayElements_ += (int) ((sizeof(Vector3) * 8) / sizeof(float));
+    }
 
 
 }
 }