using System; using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Linq; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using MagicPhysX; // for enable Extension Methods. using MagicPhysX.Toolkit; using static MagicPhysX.NativeMethods; // recommend to use C API. namespace Physx { //delegate void TRIGGER_FUNC(PxRigidActor* actorA, PxRigidActor* actorB, UInt32 c); //先用原来的命名方式 后续修改为微软命名方式 public unsafe struct TriggerCallBack : IDisposable { public PxShape* shape_; public TRIGGER_FUNC enter_func_; public TRIGGER_FUNC leave_func_; public UInt32 effectType_; public UInt64 endStamp_; //std::shared_ptr shape_name_ptr_; public IntPtr StrPtr; public delegate void TRIGGER_FUNC(PxRigidActor* actorA, PxRigidActor* actorB, UInt32 c); public TriggerCallBack() { } public TriggerCallBack(PxShape* shape, UInt32 effectType, UInt64 effectValue, TRIGGER_FUNC enter, TRIGGER_FUNC leave) { shape_ = shape; enter_func_ = enter; leave_func_ = leave; effectType_ = effectType; } public void Dispose() { //TODO 这里需要详细测试 如何释放内存 shape_ 是delete 指向的对象 还是只是 置为null } //TriggerCallBack(PxShape* shape, UInt32 effectType, // UInt64 effectValue, TRIGGER_FUNC** enter, // TRIGGER_FUNC** leave); //~TriggerCallBack(); public void OnEnter(PxRigidActor* tActor, PxRigidActor* oActor, UInt32 args = 0) { if (enter_func_ != null) { enter_func_(tActor, oActor, args); } } public void OnLeave(PxRigidActor* tActor, PxRigidActor* oActor, UInt32 args = 0) { if (leave_func_ != null) { leave_func_(tActor, oActor, args); } } public void ResetCall() { enter_func_ = null; leave_func_ = null; } public bool IsNeedDelete() { if (endStamp_ > 0) { //return endStamp_ < KG_GetTimeStamp(); } return false; } //TODO;需要测试 public bool EuqalShapeName(IntPtr strPtr) { return strPtr.Equals(strPtr); } } ///////////////////////////////////////////////////////////////////////// // TriggerManager ///////////////////////////////////////////////////////////////////////// public unsafe struct TriggerManager { //TriggerManager(); //~TriggerManager(); // add a TriggerCallBackPtr public void Push(TriggerCallBack* ptr) { callbacks_.Add((nint)ptr); } // remve a trigger by shape public void Remove(PxShape* shape) { if (shape == null) return; foreach (IntPtr it in callbacks_) { TriggerCallBack* call = (TriggerCallBack*)it.ToPointer(); if (call->EuqalShapeName((IntPtr)shape->GetName())) { callbacks_.Remove(it); //TODO 需要测试 //因为it 原先是智能指针实现 这里需要释放智能指针指向的对象 //需要考虑引用次数? //call->Dispose(); return; } } } // reset all triggers of a actor shapes public void ResetTriggersInActor(PxRigidActor* actor) { if (actor == null) return; UInt32 num = actor->GetNbShapes(); //NativeMethodsGroupingExtensions.GetNbShapes(ref *actor); if (num < 1) return; //std::vector shapes(nb); //List shapes = new List((int)nb); // PxShape*[] shapes = new PxShape*[num]; //UInt32 nbShapes = actor->GetShapes(reinterpret_cast(&shapes[0]), nb); fixed (PxShape** p = shapes) { UInt32 nbShapes = actor->GetShapes(p, num, 0); if (num != nbShapes) return; } for (UInt32 i = 0; i < num; i++) { if (((int)shapes[i]->GetFlags() & (int)PxShapeFlag.TriggerShape) != 0) { //TriggerCallBackPtr ptr = FindTrigger(shapes[i]); TriggerCallBack* TriggerCallBackPtr = FindTrigger(shapes[i]); if (TriggerCallBackPtr != null) { TriggerCallBackPtr->ResetCall(); //(IntPtr)(TriggerCallBackPtr)->ResetCall(); } } } } // when release actor, remove all TriggerCallBackPtrs of the actor public void OnReleaseActor(PxRigidActor* actor) { if (actor == null) return; UInt32 num = actor->GetNbShapes(); if (num < 1) return; //std::vector shapes(nb); PxShape*[] shapes = new PxShape*[num]; fixed (PxShape** p = shapes) { UInt32 nbShapes = actor->GetShapes(p, num, 0); if (num != nbShapes) return; } for (UInt32 i = 0; i < num; i++) { if (((int)shapes[i]->GetFlags() & (int)PxShapeFlag.TriggerShape) != 0) { Remove(shapes[i]); } } } // find a TriggerCallBackPtr by shape public TriggerCallBack* FindTrigger(PxShape* shape) { if (shape == null) return null; if (((int)shape->GetFlags() & (int)PxShapeFlag.TriggerShape) != 0) { } else { //LogMgr::GetInstance()->Error( // "TriggerManager::FindTrigger is not triggerrrrrrrrrrrrrrrrrrrr\n"); } foreach (IntPtr it in callbacks_) { TriggerCallBack* call = (TriggerCallBack*)it.ToPointer(); if (call->EuqalShapeName((IntPtr)shape->GetName())) { return call; } } return null; } public void Update() { if (callbacks_.Count() == 0) return; foreach (IntPtr it in callbacks_) { TriggerCallBack* call = (TriggerCallBack*)it.ToPointer(); { PxRigidActor* actor = call->shape_->GetActor(); if (actor != null) { UInt32 nb = actor->GetNbShapes(); if (nb <= 2) { //KHero* hero = static_cast(actor->userData)->is < KHero *> (); //if (hero) //{ // auto cur = hero->attribute_manager_.GetCurrent(); // cur.hp = 0; // hero->attribute_manager_.SetCurrent(cur); // hero->Die(nullptr); //} } } callbacks_.Remove(it); } } } public void Clear() { callbacks_.Clear(); } public void PrintV() { //LogMgr::GetInstance()->Error("TriggerManager::PrintV ============\n"); //for (auto it : callbacks_) //{ // printf("shape=%p,", it->shape_); // physx::PxSphereGeometry geo; // if (it->shape_->getSphereGeometry(geo)) // { // printf("radius=%f\n", geo.radius); // } //} } //禁止拷贝构造 c#中是否有这样语法 // private: //TriggerManager& operator=(const TriggerManager&); //TriggerCallBack* 是否存在指向内容的释放 //List callbacks_; List callbacks_; }; }