Browse Source

Adding C# component FixedUpdate and PostUpdate, ScriptPhysics for NodeCollision and contacts

Josh Engebretson 9 years ago
parent
commit
c90fa06656

+ 0 - 2
Script/AtomicNET/AtomicNET/Core/AObject.cs

@@ -14,8 +14,6 @@ namespace AtomicEngine
             return AtomicNET.GetSubsystem<T>();
             return AtomicNET.GetSubsystem<T>();
         }
         }
 
 
-
-
         internal void HandleEvent(uint eventType, ScriptVariantMap eventData)
         internal void HandleEvent(uint eventType, ScriptVariantMap eventData)
         {
         {
             eventHandlers[eventType](eventType, eventData);
             eventHandlers[eventType](eventType, eventData);

+ 83 - 2
Script/AtomicNET/AtomicNET/Scene/CSComponentCore.cs

@@ -28,6 +28,12 @@ namespace AtomicEngine
             Type[] updateParms = new Type[1] { typeof(float) };
             Type[] updateParms = new Type[1] { typeof(float) };
             UpdateMethod = type.GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.DefaultBinder, updateParms, null);
             UpdateMethod = type.GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.DefaultBinder, updateParms, null);
 
 
+            Type[] postUpdateParms = new Type[1] { typeof(float) };
+            PostUpdateMethod = type.GetMethod("PostUpdate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.DefaultBinder, postUpdateParms, null);
+
+            Type[] fixedUpdateParms = new Type[1] { typeof(float) };
+            FixedUpdateMethod = type.GetMethod("FixedUpdate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.DefaultBinder, fixedUpdateParms, null);
+
             Type[] startParms = new Type[0] { };
             Type[] startParms = new Type[0] { };
             StartMethod = type.GetMethod("Start", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.DefaultBinder, startParms, null);
             StartMethod = type.GetMethod("Start", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.DefaultBinder, startParms, null);
 
 
@@ -106,6 +112,47 @@ namespace AtomicEngine
 
 
         }
         }
 
 
+        public void FixedUpdate(Object[] args)
+        {
+            if (FixedUpdateMethod == null)
+                return;
+
+            foreach (var instance in Instances)
+            { 
+                var node = instance.Node;
+
+                if (node != null && node.IsEnabled())
+                {
+
+                    if (node.Scene != null)
+                    {
+                        FixedUpdateMethod.Invoke(instance, args);
+                    }
+                }
+            }
+        }
+
+        public void PostUpdate(Object[] args)
+        {
+            if (PostUpdateMethod == null)
+                return;
+
+            foreach (var instance in Instances)
+            {
+                var node = instance.Node;
+
+                if (node != null && node.IsEnabled())
+                {
+
+                    if (node.Scene != null)
+                    {
+                        PostUpdateMethod.Invoke(instance, args);
+                    }
+                }
+            }
+        }
+
+
         public void Update(Object[] args)
         public void Update(Object[] args)
         {
         {
             if (StartMethod != null)
             if (StartMethod != null)
@@ -175,8 +222,11 @@ namespace AtomicEngine
         public FieldInfo[] InspectorFields;
         public FieldInfo[] InspectorFields;
         public Type Type;
         public Type Type;
 
 
-        public MethodInfo UpdateMethod = null;
+        public MethodInfo FixedUpdateMethod = null;
+        public MethodInfo PostUpdateMethod = null;
+        public MethodInfo UpdateMethod = null;        
         public MethodInfo StartMethod = null;
         public MethodInfo StartMethod = null;
+        
 
 
         ScriptVariantMap fieldMap = new ScriptVariantMap();
         ScriptVariantMap fieldMap = new ScriptVariantMap();
 
 
@@ -202,6 +252,31 @@ namespace AtomicEngine
 
 
         }
         }
 
 
+        void HandlePhysicsPreStep(uint eventType, ScriptVariantMap eventData)
+        {
+            // TODO: eventData also has a PhysicsWorld pointer, which could be factored in for multiworld support
+
+            Object[] args = new Object[1] { eventData.GetFloat("timestep") };
+
+            foreach (var csinfo in csinfoLookup.Values)
+            {
+                csinfo.FixedUpdate(args);
+            }
+
+        }
+
+        void HandlePostUpdate(uint eventType, ScriptVariantMap eventData)
+        {
+            Object[] args = new Object[1] { eventData.GetFloat("timestep") };
+
+            foreach (var csinfo in csinfoLookup.Values)
+            {
+                csinfo.PostUpdate(args);
+            }
+
+        }
+
+
         void HandleComponentLoad(uint eventType, ScriptVariantMap eventData)
         void HandleComponentLoad(uint eventType, ScriptVariantMap eventData)
         {
         {
             var assemblyPath = eventData["AssemblyPath"];
             var assemblyPath = eventData["AssemblyPath"];
@@ -272,10 +347,16 @@ namespace AtomicEngine
         internal static void Initialize()
         internal static void Initialize()
         {
         {
             instance = new CSComponentCore();
             instance = new CSComponentCore();
-
+            
             instance.SubscribeToEvent("CSComponentAssemblyReference", instance.HandleComponentAssemblyReference);
             instance.SubscribeToEvent("CSComponentAssemblyReference", instance.HandleComponentAssemblyReference);
             instance.SubscribeToEvent("CSComponentLoad", instance.HandleComponentLoad);
             instance.SubscribeToEvent("CSComponentLoad", instance.HandleComponentLoad);
             instance.SubscribeToEvent("Update", instance.HandleUpdate);
             instance.SubscribeToEvent("Update", instance.HandleUpdate);
+
+            // PhysicsPreStep gets mapped to FixedUpdate
+            instance.SubscribeToEvent("PhysicsPreStep", instance.HandlePhysicsPreStep);
+
+            instance.SubscribeToEvent("PostUpdate", instance.HandlePostUpdate);
+
         }
         }
 
 
         Dictionary<string, Dictionary<string, CSComponentInfo>> componentCache = new Dictionary<string, Dictionary<string, CSComponentInfo>>();
         Dictionary<string, Dictionary<string, CSComponentInfo>> componentCache = new Dictionary<string, Dictionary<string, CSComponentInfo>>();

+ 14 - 0
Script/AtomicNET/AtomicNET/Script/ScriptVariantMap.cs

@@ -20,6 +20,20 @@ namespace AtomicEngine
             }
             }
         }
         }
 
 
+        public T GetPtr<T>(string key) where T : RefCounted
+        {
+            var value = GetPtr(key);
+
+            if (value == null)
+                return null;
+
+            // TODO: allow derived classes, throw error
+            if (value.GetType().Name != typeof(T).Name)
+                return null;
+
+            return (T) value;            
+        }
+
         public IntPtr GetVoidPtr(string key)
         public IntPtr GetVoidPtr(string key)
         {
         {
             return csi_Atomic_AtomicNET_ScriptVariantMap_GetVoidPtr(nativeInstance, key);
             return csi_Atomic_AtomicNET_ScriptVariantMap_GetVoidPtr(nativeInstance, key);

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

@@ -1,5 +1,5 @@
 {
 {
 	"name" : "Script",
 	"name" : "Script",
 	"sources" : ["Source/Atomic/Script"],
 	"sources" : ["Source/Atomic/Script"],
-	"classes" : ["ScriptVariantMap", "ScriptVector", "ScriptComponent", "ScriptComponentFile"]
+	"classes" : ["ScriptVariantMap", "ScriptVector", "ScriptComponent", "ScriptComponentFile", "PhysicsContact", "PhysicsNodeCollision"]
 }
 }

+ 31 - 0
Source/Atomic/Script/ScriptPhysics.cpp

@@ -0,0 +1,31 @@
+
+#include <Atomic/IO/MemoryBuffer.h>
+#include <Atomic/Physics/PhysicsEvents.h>
+#include <Atomic/Scene/Node.h>
+#include "ScriptPhysics.h"
+
+
+namespace Atomic
+{
+
+void PhysicsNodeCollision::SetFromNodeCollisionEvent(VariantMap& eventData)
+{
+    using namespace NodeCollision;
+
+    body_ = static_cast<RigidBody*>(eventData[P_BODY].GetPtr());
+
+    otherNode_ = static_cast<Node*>(eventData[P_OTHERNODE].GetPtr());
+    otherBody_ = static_cast<RigidBody*>(eventData[P_OTHERBODY].GetPtr());
+
+    trigger_ = eventData[P_TRIGGER].GetBool();
+    
+    MemoryBuffer contacts(eventData[P_CONTACTS].GetBuffer());
+
+    while (!contacts.IsEof())
+    {
+        contacts_.Push(SharedPtr<PhysicsContact>(new PhysicsContact(contacts.ReadVector3(), contacts.ReadVector3(), contacts.ReadFloat(), contacts.ReadFloat())));
+    }
+    
+}
+
+}

+ 78 - 0
Source/Atomic/Script/ScriptPhysics.h

@@ -0,0 +1,78 @@
+
+#pragma once
+
+
+#include <Atomic/Core/Variant.h>
+#include <Atomic/Physics/RigidBody.h>
+#include <Atomic/Scene/Node.h>
+
+namespace Atomic
+{
+    class Node;
+
+    class PhysicsContact : public RefCounted
+    {
+        friend class PhysicsNodeCollision;
+
+        ATOMIC_REFCOUNTED(PhysicsNodeContact)
+
+    public:
+
+        PhysicsContact() {};
+
+        const Vector3& GetPosition() const { return position_; }
+        const Vector3& GetNormal() const { return normal_; }
+        float GetDistance() const { return distance_; }
+        float GetImpulse() const { return impulse_; }
+
+    private:
+
+        PhysicsContact(const Vector3& position, const Vector3& normal, float distance, float impulse) :
+            position_(position),
+            normal_(normal),
+            distance_(distance),
+            impulse_(impulse)
+        {
+
+        }
+
+        Vector3 position_;
+        Vector3 normal_;
+        float distance_;
+        float impulse_;
+    };
+
+    class PhysicsNodeCollision : public RefCounted
+    {
+        ATOMIC_REFCOUNTED(PhysicsNodeCollision)
+
+    public:
+
+        PhysicsNodeCollision() : trigger_(false)
+        {
+
+        }
+
+        RigidBody* GetBody() const { return body_; }
+
+        Node* GetOtherNode() const { return otherNode_; }
+        RigidBody* GetOtherBody() const { return otherBody_; }
+
+        bool GetTrigger() const { return trigger_; }
+
+        const Vector<SharedPtr<PhysicsContact>>& GetContacts() const { return contacts_;  }
+
+        void SetFromNodeCollisionEvent(VariantMap& eventData);
+
+    private:
+
+        SharedPtr<RigidBody> body_;
+
+        SharedPtr<Node> otherNode_;
+        SharedPtr<RigidBody> otherBody_;
+        bool trigger_;
+
+        Vector<SharedPtr<PhysicsContact>> contacts_;
+
+    };
+}

+ 20 - 0
Source/AtomicNET/NETNative/NETEventDispatcher.cpp

@@ -21,6 +21,8 @@
 //
 //
 
 
 #include <Atomic/Core/CoreEvents.h>
 #include <Atomic/Core/CoreEvents.h>
+#include <Atomic/Physics/PhysicsEvents.h>
+#include <Atomic/Script/ScriptPhysics.h>
 
 
 #include "NETCore.h"
 #include "NETCore.h"
 #include "NETEventDispatcher.h"
 #include "NETEventDispatcher.h"
@@ -49,6 +51,24 @@ namespace Atomic
         if (!netEvents_.Contains(eventType))
         if (!netEvents_.Contains(eventType))
             return;
             return;
 
 
+        // Do any conversion that is necessary, will probably want to factor this into something better
+
+        if (eventType == E_NODECOLLISION)
+        {
+            VariantMap ncEventData;
+
+            SharedPtr<PhysicsNodeCollision> nodeCollison(new PhysicsNodeCollision());
+            nodeCollison->SetFromNodeCollisionEvent(eventData);
+            ncEventData[StringHash("PhysicsNodeCollision")] = nodeCollison;
+
+            ncEventData[eventType] = ncEventData;
+
+            NETCore::DispatchEvent(eventType.Value(), &ncEventData);
+
+            return;
+
+        }
+
         NETCore::DispatchEvent(eventType.Value(), &eventData);
         NETCore::DispatchEvent(eventType.Value(), &eventData);
 
 
     }
     }