Physx/PhysxTriger.cs
2023-07-31 13:55:44 +08:00

282 lines
8.4 KiB
C#

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<std::string> 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<physx::PxShape*> shapes(nb);
//List<IntPtr> shapes = new List<IntPtr>((int)nb);
//
PxShape*[] shapes = new PxShape*[num];
//UInt32 nbShapes = actor->GetShapes(reinterpret_cast<physx::PxShape**>(&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<physx::PxShape*> 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<ClassType*>(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<TriggerCallBack*> callbacks_;
List<IntPtr> callbacks_;
};
}