282 lines
8.4 KiB
C#
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_;
|
||
|
};
|
||
|
|
||
|
|
||
|
}
|