//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// #include "BsScriptPhysics.h" #include "BsMonoManager.h" #include "BsMonoClass.h" #include "BsMonoUtil.h" #include "BsPhysics.h" #include "BsScriptPhysicsMesh.h" #include "BsScriptCollider.h" #include "BsCollider.h" namespace BansheeEngine { ScriptPhysics::ScriptPhysics(MonoObject* instance) :ScriptObject(instance) { } void ScriptPhysics::initRuntimeData() { metaData.scriptClass->addInternalCall("Internal_GetGravity", &ScriptPhysics::internal_GetGravity); metaData.scriptClass->addInternalCall("Internal_SetGravity", &ScriptPhysics::internal_SetGravity); metaData.scriptClass->addInternalCall("Internal_AddPhysicsRegion", &ScriptPhysics::internal_AddPhysicsRegion); metaData.scriptClass->addInternalCall("Internal_RemovePhysicsRegion", &ScriptPhysics::internal_RemovePhysicsRegion); metaData.scriptClass->addInternalCall("Internal_ClearPhysicsRegions", &ScriptPhysics::internal_ClearPhysicsRegions); metaData.scriptClass->addInternalCall("Internal_ToggleCollision", &ScriptPhysics::internal_ToggleCollision); metaData.scriptClass->addInternalCall("Internal_IsCollisionEnabled", &ScriptPhysics::internal_IsCollisionEnabled); metaData.scriptClass->addInternalCall("Internal_IsUpdateInProgress", &ScriptPhysics::internal_IsUpdateInProgress); metaData.scriptClass->addInternalCall("Internal_RayCast", &ScriptPhysics::internal_RayCast); metaData.scriptClass->addInternalCall("Internal_BoxCast", &ScriptPhysics::internal_BoxCast); metaData.scriptClass->addInternalCall("Internal_SphereCast", &ScriptPhysics::internal_SphereCast); metaData.scriptClass->addInternalCall("Internal_CapsuleCast", &ScriptPhysics::internal_CapsuleCast); metaData.scriptClass->addInternalCall("Internal_ConvexCast", &ScriptPhysics::internal_ConvexCast); metaData.scriptClass->addInternalCall("Internal_RayCastAll", &ScriptPhysics::internal_RayCastAll); metaData.scriptClass->addInternalCall("Internal_BoxCastAll", &ScriptPhysics::internal_BoxCastAll); metaData.scriptClass->addInternalCall("Internal_SphereCastAll", &ScriptPhysics::internal_SphereCastAll); metaData.scriptClass->addInternalCall("Internal_CapsuleCastAll", &ScriptPhysics::internal_CapsuleCastAll); metaData.scriptClass->addInternalCall("Internal_ConvexCastAll", &ScriptPhysics::internal_ConvexCastAll); metaData.scriptClass->addInternalCall("Internal_RayCastAny", &ScriptPhysics::internal_RayCastAny); metaData.scriptClass->addInternalCall("Internal_BoxCastAny", &ScriptPhysics::internal_BoxCastAny); metaData.scriptClass->addInternalCall("Internal_SphereCastAny", &ScriptPhysics::internal_SphereCastAny); metaData.scriptClass->addInternalCall("Internal_CapsuleCastAny", &ScriptPhysics::internal_CapsuleCastAny); metaData.scriptClass->addInternalCall("Internal_ConvexCastAny", &ScriptPhysics::internal_ConvexCastAny); metaData.scriptClass->addInternalCall("Internal_BoxOverlap", &ScriptPhysics::internal_BoxOverlap); metaData.scriptClass->addInternalCall("Internal_SphereOverlap", &ScriptPhysics::internal_SphereOverlap); metaData.scriptClass->addInternalCall("Internal_CapsuleOverlap", &ScriptPhysics::internal_CapsuleOverlap); metaData.scriptClass->addInternalCall("Internal_ConvexOverlap", &ScriptPhysics::internal_ConvexOverlap); metaData.scriptClass->addInternalCall("Internal_BoxOverlapAny", &ScriptPhysics::internal_BoxOverlapAny); metaData.scriptClass->addInternalCall("Internal_SphereOverlapAny", &ScriptPhysics::internal_SphereOverlapAny); metaData.scriptClass->addInternalCall("Internal_CapsuleOverlapAny", &ScriptPhysics::internal_CapsuleOverlapAny); metaData.scriptClass->addInternalCall("Internal_ConvexOverlapAny", &ScriptPhysics::internal_ConvexOverlapAny); } void ScriptPhysics::internal_GetGravity(Vector3* gravity) { *gravity = gPhysics().getGravity(); } void ScriptPhysics::internal_SetGravity(Vector3* gravity) { gPhysics().setGravity(*gravity); } int ScriptPhysics::internal_AddPhysicsRegion(AABox* region) { return gPhysics().addBroadPhaseRegion(*region); } void ScriptPhysics::internal_RemovePhysicsRegion(int handle) { gPhysics().removeBroadPhaseRegion(handle); } void ScriptPhysics::internal_ClearPhysicsRegions() { gPhysics().clearBroadPhaseRegions(); } void ScriptPhysics::internal_ToggleCollision(UINT64 layerA, UINT64 layerB, bool enabled) { gPhysics().toggleCollision(layerA, layerB, enabled); } bool ScriptPhysics::internal_IsCollisionEnabled(UINT64 layerA, UINT64 layerB) { return gPhysics().isCollisionEnabled(layerA, layerB); } bool ScriptPhysics::internal_IsUpdateInProgress() { return gPhysics()._isUpdateInProgress(); } bool ScriptPhysics::internal_RayCast(Vector3* origin, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max) { PhysicsQueryHit nativeHit; bool wasHit = gPhysics().rayCast(*origin, *unitDir, nativeHit, layer, max); *hit = ScriptPhysicsQueryHitHelper::create(nativeHit); return wasHit; } bool ScriptPhysics::internal_BoxCast(AABox* box, Quaternion* rotation, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max) { PhysicsQueryHit nativeHit; bool wasHit = gPhysics().boxCast(*box, *rotation, *unitDir, nativeHit, layer, max); *hit = ScriptPhysicsQueryHitHelper::create(nativeHit); return wasHit; } bool ScriptPhysics::internal_SphereCast(Sphere* sphere, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max) { PhysicsQueryHit nativeHit; bool wasHit = gPhysics().sphereCast(*sphere, *unitDir, nativeHit, layer, max); *hit = ScriptPhysicsQueryHitHelper::create(nativeHit); return wasHit; } bool ScriptPhysics::internal_CapsuleCast(Capsule* capsule, Quaternion* rotation, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max) { PhysicsQueryHit nativeHit; bool wasHit = gPhysics().capsuleCast(*capsule, *rotation, *unitDir, nativeHit, layer, max); *hit = ScriptPhysicsQueryHitHelper::create(nativeHit); return wasHit; } bool ScriptPhysics::internal_ConvexCast(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max) { HPhysicsMesh meshHandle; if (mesh != nullptr) meshHandle = mesh->getHandle(); PhysicsQueryHit nativeHit; bool wasHit = gPhysics().convexCast(meshHandle, *position, *rotation, *unitDir, nativeHit, layer, max); *hit = ScriptPhysicsQueryHitHelper::create(nativeHit); return wasHit; } MonoArray* nativeToManagedHitArray(const Vector& hits) { UINT32 numHits = (UINT32)hits.size(); ScriptArray output = ScriptArray::create(numHits); for (UINT32 i = 0; i < numHits; i++) output.set(i, ScriptPhysicsQueryHitHelper::create(hits[i])); return output.getInternal(); } MonoArray* ScriptPhysics::internal_RayCastAll(Vector3* origin, Vector3* unitDir, UINT64 layer, float max) { return nativeToManagedHitArray(gPhysics().rayCastAll(*origin, *unitDir, layer, max)); } MonoArray* ScriptPhysics::internal_BoxCastAll(AABox* box, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max) { return nativeToManagedHitArray(gPhysics().boxCastAll(*box, *rotation, *unitDir, layer, max)); } MonoArray* ScriptPhysics::internal_SphereCastAll(Sphere* sphere, Vector3* unitDir, UINT64 layer, float max) { return nativeToManagedHitArray(gPhysics().sphereCastAll(*sphere, *unitDir, layer, max)); } MonoArray* ScriptPhysics::internal_CapsuleCastAll(Capsule* capsule, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max) { return nativeToManagedHitArray(gPhysics().capsuleCastAll(*capsule, *rotation, *unitDir, layer, max)); } MonoArray* ScriptPhysics::internal_ConvexCastAll(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max) { HPhysicsMesh meshHandle; if (mesh != nullptr) meshHandle = mesh->getHandle(); return nativeToManagedHitArray(gPhysics().convexCastAll(meshHandle, *position, *rotation, *unitDir, layer, max)); } bool ScriptPhysics::internal_RayCastAny(Vector3* origin, Vector3* unitDir, UINT64 layer, float max) { return gPhysics().rayCastAny(*origin, *unitDir, layer, max); } bool ScriptPhysics::internal_BoxCastAny(AABox* box, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max) { return gPhysics().boxCastAny(*box, *rotation, *unitDir, layer, max); } bool ScriptPhysics::internal_SphereCastAny(Sphere* sphere, Vector3* unitDir, UINT64 layer, float max) { return gPhysics().sphereCastAny(*sphere, *unitDir, layer, max); } bool ScriptPhysics::internal_CapsuleCastAny(Capsule* capsule, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max) { return gPhysics().capsuleCastAny(*capsule, *rotation, *unitDir, layer, max); } bool ScriptPhysics::internal_ConvexCastAny(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max) { HPhysicsMesh meshHandle; if (mesh != nullptr) meshHandle = mesh->getHandle(); return gPhysics().convexCastAny(meshHandle, *position, *rotation, *unitDir, layer, max); } MonoArray* nativeToManagedColliderArray(const Vector& colliders) { UINT32 numColliders = (UINT32)colliders.size(); ScriptArray output = ScriptArray::create(numColliders); for (UINT32 i = 0; i < numColliders; i++) output.set(i, colliders[i]->_getOwner(PhysicsOwnerType::Script)); return output.getInternal(); } MonoArray* ScriptPhysics::internal_BoxOverlap(AABox* box, Quaternion* rotation, UINT64 layer) { return nativeToManagedColliderArray(gPhysics()._boxOverlap(*box, *rotation, layer)); } MonoArray* ScriptPhysics::internal_SphereOverlap(Sphere* sphere, UINT64 layer) { return nativeToManagedColliderArray(gPhysics()._sphereOverlap(*sphere, layer)); } MonoArray* ScriptPhysics::internal_CapsuleOverlap(Capsule* capsule, Quaternion* rotation, UINT64 layer) { return nativeToManagedColliderArray(gPhysics()._capsuleOverlap(*capsule, *rotation, layer)); } MonoArray* ScriptPhysics::internal_ConvexOverlap(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, UINT64 layer) { HPhysicsMesh meshHandle; if (mesh != nullptr) meshHandle = mesh->getHandle(); return nativeToManagedColliderArray(gPhysics()._convexOverlap(meshHandle, *position, *rotation, layer)); } bool ScriptPhysics::internal_BoxOverlapAny(AABox* box, Quaternion* rotation, UINT64 layer) { return gPhysics().boxOverlapAny(*box, *rotation, layer); } bool ScriptPhysics::internal_SphereOverlapAny(Sphere* sphere, UINT64 layer) { return gPhysics().sphereOverlapAny(*sphere, layer); } bool ScriptPhysics::internal_CapsuleOverlapAny(Capsule* capsule, Quaternion* rotation, UINT64 layer) { return gPhysics().capsuleOverlapAny(*capsule, *rotation, layer); } bool ScriptPhysics::internal_ConvexOverlapAny(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, UINT64 layer) { HPhysicsMesh meshHandle; if (mesh != nullptr) meshHandle = mesh->getHandle(); return gPhysics().convexOverlapAny(meshHandle, *position, *rotation, layer); } }