[NUI] Added collider mesh support (#5782)
authorhuiyu <35286162+huiyueun@users.noreply.github.com>
Fri, 1 Dec 2023 07:16:30 +0000 (16:16 +0900)
committerBowon Ryu <wonrst22@naver.com>
Tue, 5 Dec 2023 07:45:45 +0000 (16:45 +0900)
* [NUI] Added collider mesh support

Model.SetColliderMesh() function allows creating and setting a collider mesh on the node of model.

Node of model is selected by name (string).
Collider mesh data consists:
List<Vector3> - list of vertices
List<int> - list of indices (3 indices are a triangle face)

* Modify issue

Signed-off-by: huiyu.eun <huiyu.eun@samsung.com>
---------

Signed-off-by: huiyu.eun <huiyu.eun@samsung.com>
Co-authored-by: Adam Bialogonski <adam.b@samsung.com>
src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.Model.cs
src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.ModelNode.cs
src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs
src/Tizen.NUI.Scene3D/src/public/ModelComponents/ModelNode.cs

index adf1bde..610c542 100755 (executable)
  * limitations under the License.
  *
  */
-
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
 namespace Tizen.NUI.Scene3D
 {
     internal static partial class Interop
     {
         internal static partial class Model
-        {
+        {            
             [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_Model_New_SWIG_0")]
             public static extern global::System.IntPtr ModelNew(string modelUrl, string resourcePasth);
 
@@ -106,6 +108,13 @@ namespace Tizen.NUI.Scene3D
 
             [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_Model_LoadFacialAnimation_2")]
             public static extern global::System.IntPtr LoadBlendShapeAnimationFromBuffer(global::System.Runtime.InteropServices.HandleRef model, string jsonBuffer, int jsonBufferLength);
+            
+            // Signals
+            [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_Model_MeshHitSignal_Connect")]
+            public static extern void MeshHitSignalConnect(global::System.Runtime.InteropServices.HandleRef model, global::System.Runtime.InteropServices.HandleRef handler);
+
+            [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_MotionData_MeshHitSignal_Disconnect")]
+            public static extern void MeshHitSignalDisconnect(global::System.Runtime.InteropServices.HandleRef model, global::System.Runtime.InteropServices.HandleRef handler);
         }
     }
 }
index ae5af29..c2acf46 100755 (executable)
  *
  */
 
+using System;
+using System.Runtime.InteropServices;
+
 namespace Tizen.NUI.Scene3D
 {
     internal static partial class Interop
     {
         internal static partial class ModelNode
         {
+            [StructLayout(LayoutKind.Sequential)]
+            internal struct Vec3
+            {
+                internal float x, y, z;
+            }
+        
+            [StructLayout(LayoutKind.Sequential)]
+            internal struct ElementIndex
+            {
+                internal Int32 index;
+            }
+            
             [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_Model_Node_New_SWIG_0")]
             public static extern global::System.IntPtr ModelNodeNew();
 
@@ -62,6 +77,11 @@ namespace Tizen.NUI.Scene3D
 
             [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_Model_Node_GetChildModelNodeAt")]
             public static extern global::System.IntPtr GetChildModelNodeAt(global::System.Runtime.InteropServices.HandleRef model, uint index);
+
+            [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_ModelNode_SetColliderMesh")]
+            public static extern global::System.IntPtr SetColliderMesh(global::System.Runtime.InteropServices.HandleRef modelNode,
+                Vec3[] vPtr,
+                Vec3[] nPtr, int vLength, int[] iPtr, int iLength);            
         }
     }
 }
index 419e770..7083221 100755 (executable)
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using System.ComponentModel;
 using Tizen.NUI;
@@ -686,5 +687,76 @@ namespace Tizen.NUI.Scene3D
         {
             Interop.Model.DeleteModel(swigCPtr);
         }
+        
+        
+        private EventHandler<MeshHitEventArgs> meshHitEventHandler;
+        private MeshHitCallbackType meshHitCallback;
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        private delegate void MeshHitCallbackType(IntPtr motionData);
+
+        /// <summary>
+        /// MeshHitEventArgs
+        /// Contains arguments when MeshHitSignal called
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public class MeshHitEventArgs : EventArgs
+        {
+            private ModelNode modelNode;
+            
+            /// <summary>
+            /// ModelNode that's been hit
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            public ModelNode ModelNode
+            {
+                get
+                {
+                    return modelNode;
+                }
+                set
+                {
+                    modelNode = value;
+                }
+            }
+        }
+        
+        /// <summary>
+        /// EventHandler event.
+        /// It will be invoked when collider mesh is hit.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<MeshHitEventArgs> ColliderMeshHitted
+        {
+            add
+            {
+                if (meshHitEventHandler == null)
+                {
+                    meshHitCallback = MeshHitCollision;
+                    Interop.Model.MeshHitSignalConnect(SwigCPtr, meshHitCallback.ToHandleRef(this));
+                    NDalicPINVOKE.ThrowExceptionIfExists();
+                }
+                meshHitEventHandler += value;
+            }
+            remove
+            {
+                meshHitEventHandler -= value;
+                if (meshHitEventHandler == null && meshHitCallback != null)
+                {
+                    Interop.Model.MeshHitSignalDisconnect(SwigCPtr, meshHitCallback.ToHandleRef(this));
+                    NDalicPINVOKE.ThrowExceptionIfExists();
+                    meshHitCallback = null;
+                }
+            }
+        }
+
+        private void MeshHitCollision(IntPtr modelNode)
+        {
+            if (meshHitEventHandler != null)
+            {
+                var args = new MeshHitEventArgs();
+                args.ModelNode = new ModelNode(modelNode, false);
+                meshHitEventHandler(this, args);
+            }
+        }
     }
 }
index 64f15bb..2247436 100755 (executable)
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using System.ComponentModel;
 using System.Collections.Generic;
@@ -202,6 +203,40 @@ namespace Tizen.NUI.Scene3D
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
         }
+        
+        /// <summary>
+        /// Sets collider mesh on current node
+        /// </summary>
+        /// <param name="vertexList">List of vertices</param>
+        /// <param name="normalList">List of vertex normals</param>
+        /// <param name="indexList">List of mesh indices</param>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetColliderMesh(List<Vector3> vertexList, List<Vector3> normalList, List<int> indexList)
+        {
+            var vertices = new Interop.ModelNode.Vec3[vertexList.Count];
+            var idx = 0;
+            foreach (var vertex in vertexList)
+            {
+                vertices[idx].x = vertex.X;
+                vertices[idx].y = vertex.Y;
+                vertices[idx].z = vertex.Z;
+                ++idx;
+            }
+            
+            var normals = new Interop.ModelNode.Vec3[normalList.Count];
+            idx = 0;
+            foreach (var normal in normalList)
+            {
+                normals[idx].x = normal.X;
+                normals[idx].y = normal.Y;
+                normals[idx].z = normal.Z;
+                ++idx;
+            }
+            
+            Interop.ModelNode.SetColliderMesh(SwigCPtr,vertices, normals, vertexList.Count, indexList.ToArray(), indexList.Count);
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
 
         /// <summary>
         /// Gets the number of ModelPrimitive objects in the ModelNode object.