diff --git a/Source/Engine/Physics/PhysX/Types.h b/Source/Engine/Physics/PhysX/Types.h index d95d6b140..c86a03a62 100644 --- a/Source/Engine/Physics/PhysX/Types.h +++ b/Source/Engine/Physics/PhysX/Types.h @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace physx @@ -233,12 +234,28 @@ inline float RadPerSToRpm(float v) return v * (30.0f / PI); } +inline PhysicalMaterial* GetMaterial(const PxShape* shape, PxU32 faceIndex) +{ + if (faceIndex != 0xFFFFffff) + { + PxBaseMaterial* mat = shape->getMaterialFromInternalFaceIndex(faceIndex); + return mat ? (PhysicalMaterial*)mat->userData : nullptr; + } + else + { + PxMaterial* mat; + shape->getMaterials(&mat, 1); + return mat ? (PhysicalMaterial*)mat->userData : nullptr; + } +} + inline void P2C(const PxRaycastHit& hit, RayCastHit& result) { result.Point = P2C(hit.position); result.Normal = P2C(hit.normal); result.Distance = hit.distance; result.Collider = hit.shape ? static_cast(hit.shape->userData) : nullptr; + result.Material = hit.shape ? GetMaterial(hit.shape, hit.faceIndex) : nullptr; result.FaceIndex = hit.faceIndex; result.UV.X = hit.u; result.UV.Y = hit.v; @@ -250,6 +267,7 @@ inline void P2C(const PxSweepHit& hit, RayCastHit& result) result.Normal = P2C(hit.normal); result.Distance = hit.distance; result.Collider = hit.shape ? static_cast(hit.shape->userData) : nullptr; + result.Material = hit.shape ? GetMaterial(hit.shape, hit.faceIndex) : nullptr; result.FaceIndex = hit.faceIndex; result.UV = Vector2::Zero; } diff --git a/Source/Engine/Physics/PhysicalMaterial.h b/Source/Engine/Physics/PhysicalMaterial.h index f1aa0c1fd..cb8202876 100644 --- a/Source/Engine/Physics/PhysicalMaterial.h +++ b/Source/Engine/Physics/PhysicalMaterial.h @@ -4,16 +4,17 @@ #include "Types.h" #include "Engine/Core/ISerializable.h" +#include "Engine/Scripting/ScriptingObject.h" #include "Engine/Level/Tags.h" /// /// Physical materials are used to define the response of a physical object when interacting dynamically with the world. /// API_CLASS(Attributes = "ContentContextMenu(\"New/Physics/Physical Material\")") -class FLAXENGINE_API PhysicalMaterial final : public ISerializable +class FLAXENGINE_API PhysicalMaterial final : public ScriptingObject, public ISerializable { API_AUTO_SERIALIZATION(); - DECLARE_SCRIPTING_TYPE_MINIMAL(PhysicalMaterial); + DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(PhysicalMaterial, ScriptingObject); private: void* _material = nullptr; diff --git a/Source/Engine/Physics/Types.h b/Source/Engine/Physics/Types.h index 1631f694b..f7cb9f89c 100644 --- a/Source/Engine/Physics/Types.h +++ b/Source/Engine/Physics/Types.h @@ -10,6 +10,7 @@ struct PhysicsStatistics; class PhysicsColliderActor; class PhysicsScene; +class PhysicalMaterial; class Joint; class Collider; class CollisionData; @@ -132,7 +133,7 @@ DECLARE_ENUM_OPERATORS(RigidbodyConstraints); /// /// Raycast hit result data. /// -API_STRUCT() struct RayCastHit +API_STRUCT(NoDefault) struct RayCastHit { DECLARE_SCRIPTING_TYPE_NO_SPAWN(RayCastHit); @@ -141,6 +142,11 @@ API_STRUCT() struct RayCastHit /// API_FIELD() PhysicsColliderActor* Collider = nullptr; + /// + /// The physical material of the surface that was hit. + /// + API_FIELD() PhysicalMaterial* Material = nullptr; + /// /// The normal of the surface the ray hit. ///