From a78357d298966bd7eca4429915e68e42451b2470 Mon Sep 17 00:00:00 2001 From: huiyu <35286162+huiyueun@users.noreply.github.com> Date: Wed, 6 Dec 2023 13:39:22 +0900 Subject: [PATCH] [NUI] Added collider mesh support (#5782) (#5799) * [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 - list of vertices List - list of indices (3 indices are a triangle face) * Modify issue --------- Signed-off-by: huiyu.eun Co-authored-by: Adam Bialogonski --- .../src/internal/Interop/Interop.Model.cs | 13 +++- .../src/internal/Interop/Interop.ModelNode.cs | 26 ++++++++ src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs | 72 ++++++++++++++++++++++ .../src/public/ModelComponents/ModelNode.cs | 35 +++++++++++ 4 files changed, 144 insertions(+), 2 deletions(-) diff --git a/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.Model.cs b/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.Model.cs index adf1bde..610c542 100755 --- a/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.Model.cs +++ b/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.Model.cs @@ -14,13 +14,15 @@ * 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); } } } diff --git a/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.ModelNode.cs b/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.ModelNode.cs index 93e487d..c2acf46 100755 --- a/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.ModelNode.cs +++ b/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.ModelNode.cs @@ -15,12 +15,27 @@ * */ +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(); @@ -56,6 +71,17 @@ namespace Tizen.NUI.Scene3D [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_Model_Node_FindChildModelNodeByName")] public static extern global::System.IntPtr FindChildModelNodeByName(global::System.Runtime.InteropServices.HandleRef model, string nodeName); + + [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_Model_Node_GetChildModelNodeCount")] + public static extern uint GetChildModelNodeCount(global::System.Runtime.InteropServices.HandleRef model); + + [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); } } } diff --git a/src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs b/src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs index ae24095..3823f9f 100755 --- a/src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs +++ b/src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs @@ -16,6 +16,7 @@ */ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.ComponentModel; using Tizen.NUI; @@ -664,5 +665,76 @@ namespace Tizen.NUI.Scene3D { Interop.Model.DeleteModel(swigCPtr); } + + + private EventHandler meshHitEventHandler; + private MeshHitCallbackType meshHitCallback; + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void MeshHitCallbackType(IntPtr motionData); + + /// + /// MeshHitEventArgs + /// Contains arguments when MeshHitSignal called + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class MeshHitEventArgs : EventArgs + { + private ModelNode modelNode; + + /// + /// ModelNode that's been hit + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ModelNode ModelNode + { + get + { + return modelNode; + } + set + { + modelNode = value; + } + } + } + + /// + /// EventHandler event. + /// It will be invoked when collider mesh is hit. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public event EventHandler ColliderMeshHitted + { + add + { + if (meshHitEventHandler == null) + { + meshHitCallback = MeshHitCollision; + Interop.Model.MeshHitSignalConnect(SwigCPtr, meshHitCallback.ToHandleRef(this)); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + meshHitEventHandler += value; + } + remove + { + meshHitEventHandler -= value; + if (meshHitEventHandler == null && meshHitCallback != null) + { + Interop.Model.MeshHitSignalDisconnect(SwigCPtr, meshHitCallback.ToHandleRef(this)); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + meshHitCallback = null; + } + } + } + + private void MeshHitCollision(IntPtr modelNode) + { + if (meshHitEventHandler != null) + { + var args = new MeshHitEventArgs(); + args.ModelNode = new ModelNode(modelNode, false); + meshHitEventHandler(this, args); + } + } } } diff --git a/src/Tizen.NUI.Scene3D/src/public/ModelComponents/ModelNode.cs b/src/Tizen.NUI.Scene3D/src/public/ModelComponents/ModelNode.cs index 1f23f10..878db87 100755 --- a/src/Tizen.NUI.Scene3D/src/public/ModelComponents/ModelNode.cs +++ b/src/Tizen.NUI.Scene3D/src/public/ModelComponents/ModelNode.cs @@ -16,6 +16,7 @@ */ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.ComponentModel; using Tizen.NUI; @@ -192,6 +193,40 @@ namespace Tizen.NUI.Scene3D if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } + + /// + /// Sets collider mesh on current node + /// + /// List of vertices + /// List of vertex normals + /// List of mesh indices + // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetColliderMesh(List vertexList, List normalList, List 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(); + } /// /// Gets the number of ModelPrimitive objects in the ModelNode object. -- 2.7.4