add PhysX SDK and some tweaks
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -26,3 +26,6 @@
|
||||
[submodule "Prism/vendor/Box2D"]
|
||||
path = Prism/vendor/Box2D
|
||||
url = https://github.com/erincatto/box2d.git
|
||||
[submodule "Prism/vendor/PhysX"]
|
||||
path = Prism/vendor/PhysX
|
||||
url = https://github.com/NVIDIA-Omniverse/PhysX.git
|
||||
|
||||
@ -182,6 +182,7 @@ namespace Prism
|
||||
|
||||
void EditorLayer::OnDetach()
|
||||
{
|
||||
m_EditorScene->OnShutdown();
|
||||
}
|
||||
|
||||
void EditorLayer::OnUpdate(const TimeStep deltaTime)
|
||||
@ -953,7 +954,12 @@ namespace Prism
|
||||
SelectedSubmesh selection;
|
||||
if (entity.HasComponent<MeshComponent>())
|
||||
{
|
||||
selection.Mesh = &entity.GetComponent<MeshComponent>().Mesh->GetSubmeshes()[0];
|
||||
auto& meshComp = entity.GetComponent<MeshComponent>();
|
||||
|
||||
if (meshComp.Mesh)
|
||||
{
|
||||
selection.Mesh = &meshComp.Mesh->GetSubmeshes()[0];
|
||||
}
|
||||
}
|
||||
selection.Entity = entity;
|
||||
m_SelectionContext.clear();
|
||||
|
||||
95
Editor/assets/scenes/Physics3DTest.scene
Normal file
95
Editor/assets/scenes/Physics3DTest.scene
Normal file
@ -0,0 +1,95 @@
|
||||
Scene: Scene Name
|
||||
Environment:
|
||||
AssetPath: assets/env/pink_sunrise_4k.hdr
|
||||
Light:
|
||||
Direction: [-0.787, -0.73299998, 1]
|
||||
Radiance: [1, 1, 1]
|
||||
Multiplier: 0.514999986
|
||||
Entities:
|
||||
- Entity: 10169503531257462571
|
||||
TagComponent:
|
||||
Tag: Box
|
||||
TransformComponent:
|
||||
Position: [0, 1.5, 0]
|
||||
Rotation: [1, 0, 0, 0]
|
||||
Scale: [2, 2, 2]
|
||||
MeshComponent:
|
||||
AssetPath: assets/meshes/Cube1m.fbx
|
||||
RigidBodyComponent:
|
||||
BodyType: 1
|
||||
Mass: 0.5
|
||||
PhysicsMaterialComponent:
|
||||
StaticFriction: 1
|
||||
DynamicFriction: 1
|
||||
Bounciness: 0
|
||||
BoxColliderComponent:
|
||||
Offset: [0, 0, 0]
|
||||
Size: [2, 2, 2]
|
||||
- Entity: 14057422478420564497
|
||||
TagComponent:
|
||||
Tag: Player
|
||||
TransformComponent:
|
||||
Position: [-19.43363, 4.50874043, -1.96695328e-06]
|
||||
Rotation: [1, 0, 0, 0]
|
||||
Scale: [1, 1, 1]
|
||||
ScriptComponent:
|
||||
ModuleName: Example.PlayerSphere
|
||||
StoredFields:
|
||||
- Name: HorizontalForce
|
||||
Type: 1
|
||||
Data: 10
|
||||
- Name: MaxSpeed
|
||||
Type: 6
|
||||
Data: [10, 10, 10]
|
||||
- Name: JumpForce
|
||||
Type: 1
|
||||
Data: 200
|
||||
MeshComponent:
|
||||
AssetPath: assets/meshes/Sphere1m.fbx
|
||||
RigidBodyComponent:
|
||||
BodyType: 1
|
||||
Mass: 1
|
||||
PhysicsMaterialComponent:
|
||||
StaticFriction: 1
|
||||
DynamicFriction: 1
|
||||
Bounciness: 0
|
||||
SphereColliderComponent:
|
||||
Radius: 0.5
|
||||
- Entity: 5178862374589434728
|
||||
TagComponent:
|
||||
Tag: Camera
|
||||
TransformComponent:
|
||||
Position: [-21.7406311, 9.70659542, 15]
|
||||
Rotation: [0.999910355, -0.0133911213, 0, 0]
|
||||
Scale: [1, 1, 1]
|
||||
ScriptComponent:
|
||||
ModuleName: Example.BasicController
|
||||
StoredFields:
|
||||
- Name: Speed
|
||||
Type: 1
|
||||
Data: 12
|
||||
- Name: DistanceFromPlayer
|
||||
Type: 1
|
||||
Data: 15
|
||||
CameraComponent:
|
||||
Camera: some camera data...
|
||||
Primary: true
|
||||
- Entity: 18306113171518048249
|
||||
TagComponent:
|
||||
Tag: Box
|
||||
TransformComponent:
|
||||
Position: [0, 0, 0]
|
||||
Rotation: [1, 0, 0, 0]
|
||||
Scale: [50, 1, 50]
|
||||
MeshComponent:
|
||||
AssetPath: assets/meshes/Cube1m.fbx
|
||||
RigidBodyComponent:
|
||||
BodyType: 0
|
||||
Mass: 1
|
||||
PhysicsMaterialComponent:
|
||||
StaticFriction: 1
|
||||
DynamicFriction: 1
|
||||
Bounciness: 0
|
||||
BoxColliderComponent:
|
||||
Offset: [0, 0, 0]
|
||||
Size: [50, 1, 50]
|
||||
@ -5,6 +5,7 @@ namespace Example
|
||||
public class BasicController : Entity
|
||||
{
|
||||
public float Speed;
|
||||
public float DistanceFromPlayer = 20.0F;
|
||||
|
||||
private Entity m_PlayerEntity;
|
||||
|
||||
@ -17,8 +18,10 @@ namespace Example
|
||||
{
|
||||
Mat4 transform = GetTransform();
|
||||
|
||||
Vec3 playerTranstation = m_PlayerEntity.GetTransform().Translation;
|
||||
Vec3 translation = transform.Translation;
|
||||
translation.XY = m_PlayerEntity.GetTransform().Translation.XY;
|
||||
translation.XY = playerTranstation.XY;
|
||||
translation.Z = playerTranstation.Z + DistanceFromPlayer;
|
||||
translation.Y = Math.Max(translation.Y, 4.5f);
|
||||
transform.Translation = translation;
|
||||
SetTransform(transform);
|
||||
|
||||
92
ExampleApp/Src/PlayerSphere.cs
Normal file
92
ExampleApp/Src/PlayerSphere.cs
Normal file
@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Prism;
|
||||
|
||||
namespace Example
|
||||
{
|
||||
class PlayerSphere : Entity
|
||||
{
|
||||
public float HorizontalForce = 10.0f;
|
||||
public float JumpForce = 10.0f;
|
||||
|
||||
private RigidBodyComponent m_PhysicsBody;
|
||||
private MaterialInstance m_MeshMaterial;
|
||||
|
||||
public int m_CollisionCounter = 0;
|
||||
|
||||
public Vec3 MaxSpeed = new Vec3();
|
||||
|
||||
private bool Colliding => m_CollisionCounter > 0;
|
||||
|
||||
void OnCreate()
|
||||
{
|
||||
m_PhysicsBody = GetComponent<RigidBodyComponent>();
|
||||
|
||||
MeshComponent meshComponent = GetComponent<MeshComponent>();
|
||||
m_MeshMaterial = meshComponent.Mesh.GetMaterial(0);
|
||||
m_MeshMaterial.Set("u_Metalness", 0.0f);
|
||||
|
||||
AddCollisionBeginCallback(OnPlayerCollisionBegin);
|
||||
AddCollisionEndCallback(OnPlayerCollisionEnd);
|
||||
}
|
||||
|
||||
void OnPlayerCollisionBegin(float value)
|
||||
{
|
||||
m_CollisionCounter++;
|
||||
}
|
||||
|
||||
void OnPlayerCollisionEnd(float value)
|
||||
{
|
||||
m_CollisionCounter--;
|
||||
}
|
||||
|
||||
void OnUpdate(float ts)
|
||||
{
|
||||
float movementForce = HorizontalForce;
|
||||
|
||||
if (!Colliding)
|
||||
{
|
||||
movementForce *= 0.4f;
|
||||
}
|
||||
|
||||
Vec3 forward = GetForwardDirection();
|
||||
Vec3 right = GetRightDirection();
|
||||
Vec3 up = GetUpDirection();
|
||||
|
||||
if (Input.IsKeyPressed(KeyCode.W))
|
||||
m_PhysicsBody.AddForce(forward * movementForce);
|
||||
else if (Input.IsKeyPressed(KeyCode.S))
|
||||
m_PhysicsBody.AddForce(forward * -movementForce);
|
||||
|
||||
if (Input.IsKeyPressed(KeyCode.D))
|
||||
m_PhysicsBody.AddForce(right * movementForce);
|
||||
else if (Input.IsKeyPressed(KeyCode.A))
|
||||
m_PhysicsBody.AddForce(right * -movementForce);
|
||||
|
||||
if (Colliding && Input.IsKeyPressed(KeyCode.Space))
|
||||
m_PhysicsBody.AddForce(up * JumpForce);
|
||||
|
||||
if (Colliding)
|
||||
m_MeshMaterial.Set("u_AlbedoColor", new Vec3(1.0f, 0.0f, 0.0f));
|
||||
else
|
||||
m_MeshMaterial.Set("u_AlbedoColor", new Vec3(0.8f, 0.8f, 0.8f));
|
||||
|
||||
Vec3 linearVelocity = m_PhysicsBody.GetLinearVelocity();
|
||||
linearVelocity.Clamp(new Vec3(-MaxSpeed.X, -1000, -MaxSpeed.Z), MaxSpeed);
|
||||
m_PhysicsBody.SetLinearVelocity(linearVelocity);
|
||||
|
||||
if (Input.IsKeyPressed(KeyCode.R))
|
||||
{
|
||||
Mat4 transform = GetTransform();
|
||||
transform.Translation = new Vec3(0.0f);
|
||||
SetTransform(transform);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,8 @@ namespace Prism
|
||||
|
||||
private List<Action<float>> m_Collision2DBeginCallbacks = new List<Action<float>>();
|
||||
private List<Action<float>> m_Collision2DEndCallbacks = new List<Action<float>>();
|
||||
private Action<float> m_CollisionBeginCallbacks;
|
||||
private Action<float> m_CollisionEndCallbacks;
|
||||
|
||||
protected Entity() { ID = 0; }
|
||||
|
||||
@ -63,6 +65,24 @@ namespace Prism
|
||||
SetTransform_Native(ID, ref transform);
|
||||
}
|
||||
|
||||
public Vec3 GetForwardDirection()
|
||||
{
|
||||
GetForwardDirection_Native(ID, out Vec3 forward);
|
||||
return forward;
|
||||
}
|
||||
|
||||
public Vec3 GetRightDirection()
|
||||
{
|
||||
GetRightDirection_Native(ID, out Vec3 right);
|
||||
return right;
|
||||
}
|
||||
|
||||
public Vec3 GetUpDirection()
|
||||
{
|
||||
GetUpDirection_Native(ID, out Vec3 up);
|
||||
return up;
|
||||
}
|
||||
|
||||
public void AddCollision2DBeginCallback(Action<float> callback)
|
||||
{
|
||||
m_Collision2DBeginCallbacks.Add(callback);
|
||||
@ -73,6 +93,28 @@ namespace Prism
|
||||
m_Collision2DEndCallbacks.Add(callback);
|
||||
}
|
||||
|
||||
public void AddCollisionBeginCallback(Action<float> callback)
|
||||
{
|
||||
m_CollisionBeginCallbacks += callback;
|
||||
}
|
||||
|
||||
public void AddCollisionEndCallback(Action<float> callback)
|
||||
{
|
||||
m_CollisionEndCallbacks += callback;
|
||||
}
|
||||
|
||||
private void OnCollisionBegin(float data)
|
||||
{
|
||||
if (m_CollisionBeginCallbacks != null)
|
||||
m_CollisionBeginCallbacks.Invoke(data);
|
||||
}
|
||||
|
||||
private void OnCollisionEnd(float data)
|
||||
{
|
||||
if (m_CollisionEndCallbacks != null)
|
||||
m_CollisionEndCallbacks.Invoke(data);
|
||||
}
|
||||
|
||||
private void OnCollision2DBegin(float data)
|
||||
{
|
||||
foreach (var callback in m_Collision2DBeginCallbacks)
|
||||
@ -96,5 +138,11 @@ namespace Prism
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern ulong FindEntityByTag_Native(string tag);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern void GetForwardDirection_Native(ulong entityID, out Vec3 forward);
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern void GetRightDirection_Native(ulong entityID, out Vec3 right);
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern void GetUpDirection_Native(ulong entityID, out Vec3 up);
|
||||
}
|
||||
}
|
||||
|
||||
15
Prism-ScriptCore/Src/Prism/Math/Mathf.cs
Normal file
15
Prism-ScriptCore/Src/Prism/Math/Mathf.cs
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
public static class Mathf
|
||||
{
|
||||
public static float Clamp(float value, float min, float max)
|
||||
{
|
||||
if (value < min)
|
||||
return min;
|
||||
if (value > max)
|
||||
return max;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,6 +33,23 @@ namespace Prism
|
||||
Z = vec.Z;
|
||||
}
|
||||
|
||||
public void Clamp(Vec3 min, Vec3 max)
|
||||
{
|
||||
X = Mathf.Clamp(X, min.X, max.X);
|
||||
Y = Mathf.Clamp(Y, min.Y, max.Y);
|
||||
Z = Mathf.Clamp(Z, min.Z, max.Z);
|
||||
}
|
||||
|
||||
public static Vec3 operator *(Vec3 left, float scalar)
|
||||
{
|
||||
return new Vec3(left.X * scalar, left.Y * scalar, left.Z * scalar);
|
||||
}
|
||||
|
||||
public static Vec3 operator *(float scalar, Vec3 right)
|
||||
{
|
||||
return new Vec3(scalar * right.X, scalar * right.Y, scalar * right.Z);
|
||||
}
|
||||
|
||||
public Vec2 XY {
|
||||
get { return new Vec2(X, Y); }
|
||||
set { X = value.X; Y = value.Y; }
|
||||
|
||||
@ -123,4 +123,56 @@ namespace Prism
|
||||
public class BoxCollider2DComponent : Component
|
||||
{
|
||||
}
|
||||
|
||||
public class BoxColliderComponent : Component
|
||||
{
|
||||
}
|
||||
|
||||
public class SphereColliderComponent : Component
|
||||
{
|
||||
}
|
||||
|
||||
public class RigidBodyComponent : Component
|
||||
{
|
||||
public enum ForceMode
|
||||
{
|
||||
Force = 0,
|
||||
Impulse,
|
||||
VelocityChange,
|
||||
Acceleration
|
||||
}
|
||||
|
||||
public void AddForce(Vec3 force, ForceMode forceMode = ForceMode.Force)
|
||||
{
|
||||
AddForce_Native(Entity.ID, ref force, forceMode);
|
||||
}
|
||||
|
||||
public void AddTorque(Vec3 torque, ForceMode forceMode = ForceMode.Force)
|
||||
{
|
||||
AddTorque_Native(Entity.ID, ref torque, forceMode);
|
||||
}
|
||||
|
||||
public Vec3 GetLinearVelocity()
|
||||
{
|
||||
GetLinearVelocity_Native(Entity.ID, out Vec3 velocity);
|
||||
return velocity;
|
||||
}
|
||||
|
||||
public void SetLinearVelocity(Vec3 velocity)
|
||||
{
|
||||
SetLinearVelocity_Native(Entity.ID, ref velocity);
|
||||
}
|
||||
|
||||
// TODO: Add SetMaxLinearVelocity() as well
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern void AddForce_Native(ulong entityID, ref Vec3 force, ForceMode forceMode);
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern void AddTorque_Native(ulong entityID, ref Vec3 torque, ForceMode forceMode);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern void GetLinearVelocity_Native(ulong entityID, out Vec3 velocity);
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern void SetLinearVelocity_Native(ulong entityID, ref Vec3 velocity);
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,6 +45,36 @@ file(GLOB IMGUIZMO_SOURCE ${IMGUIZMO_DIR}/*.cpp)
|
||||
list(APPEND SRC_SOURCE ${IMGUIZMO_SOURCE})
|
||||
|
||||
|
||||
# ------------- NVIDIA PhysX -------------
|
||||
# PhysX/physx/buildtools/presets/*.xml
|
||||
# PX_GENERATE_STATIC_LIBRARIES=True
|
||||
# NV_USE_STATIC_WINCRT=False
|
||||
|
||||
set(PHYSX_BUILD_TYPE "checked" CACHE STRING "The build type of PhysX")
|
||||
set_property(CACHE PHYSX_BUILD_TYPE PROPERTY STRINGS debug checked profile release)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
if(PHYSX_BUILD_TYPE STREQUAL "debug" OR PHYSX_BUILD_TYPE STREQUAL "checked")
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(PHYSX_BUILD_TYPE "release")
|
||||
elseif (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(PHYSX_BUILD_TYPE "debug")
|
||||
endif ()
|
||||
|
||||
include_directories(vendor/PhysX/physx/include)
|
||||
link_directories("vendor/PhysX/physx/bin/win.x86_64.vc143.md/${PHYSX_BUILD_TYPE}") # This is the path where PhysX libraries are installed
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message("Building snippet in debug with PhysX ${PHYSX_BUILD_TYPE} configuration")
|
||||
add_compile_definitions(_DEBUG)
|
||||
else()
|
||||
message("Building snippet in release configuration with PhysX ${PHYSX_BUILD_TYPE} configuration")
|
||||
add_compile_definitions(NDEBUG)
|
||||
endif()
|
||||
|
||||
# ------------- link libraries -------------
|
||||
set(LINK_LIBRARIES_PRIVATE
|
||||
@ -55,6 +85,13 @@ set(LINK_LIBRARIES_PRIVATE
|
||||
tinyFileDialogs
|
||||
FastNoise
|
||||
yaml-cpp
|
||||
|
||||
PhysXExtensions_static_64
|
||||
PhysX_static_64
|
||||
PhysXPvdSDK_static_64
|
||||
PhysXCommon_static_64
|
||||
PhysXFoundation_static_64
|
||||
PhysXCooking_static_64
|
||||
)
|
||||
|
||||
set(LINK_LIBRARIES_PUBLIC
|
||||
@ -84,6 +121,7 @@ set(TARGET_INCLUDE_DIR
|
||||
# ------------- debug Defines -------------
|
||||
set(DEBUG_DEFINITIONS
|
||||
$<$<CONFIG:Debug>:PM_ENABLE_ASSERTS>
|
||||
$<$<CONFIG:RelWithDebInfo>:PM_ENABLE_ASSERTS>
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "Prism/Renderer/FrameBuffer.h"
|
||||
|
||||
#include "tinyfiledialogs.h"
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
#include "Prism/Script/ScriptEngine.h"
|
||||
|
||||
namespace Prism
|
||||
@ -35,6 +36,7 @@ namespace Prism
|
||||
PushOverlay(m_ImGuiLayer);
|
||||
|
||||
ScriptEngine::Init("assets/scripts/ExampleApp.dll");
|
||||
Physics3D::Init();
|
||||
|
||||
Renderer::Init();
|
||||
Renderer::WaitAndRender();
|
||||
@ -42,6 +44,10 @@ namespace Prism
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
for (Layer* layer : m_LayerStack)
|
||||
layer->OnDetach();
|
||||
|
||||
Physics3D::Shutdown();
|
||||
ScriptEngine::Shutdown();
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ namespace Prism
|
||||
float Noise::PerlinNoise(float x, float y)
|
||||
{
|
||||
s_FastNoise.SetNoiseType(FastNoise::Perlin);
|
||||
float result = s_FastNoise.GetNoise(x, y); // This returns a value between -1 and 1
|
||||
const float result = s_FastNoise.GetNoise(x, y); // This returns a value between -1 and 1
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -135,6 +135,48 @@ namespace Prism
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
if (!m_SelectionContext.HasComponent<RigidBodyComponent>())
|
||||
{
|
||||
if (ImGui::Button("Rigidbody"))
|
||||
{
|
||||
m_SelectionContext.AddComponent<RigidBodyComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
if (!m_SelectionContext.HasComponent<PhysicsMaterialComponent>())
|
||||
{
|
||||
if (ImGui::Button("Physics Material"))
|
||||
{
|
||||
m_SelectionContext.AddComponent<PhysicsMaterialComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
if (!m_SelectionContext.HasComponent<BoxColliderComponent>())
|
||||
{
|
||||
if (ImGui::Button("Box Collider"))
|
||||
{
|
||||
m_SelectionContext.AddComponent<BoxColliderComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
if (!m_SelectionContext.HasComponent<SphereColliderComponent>())
|
||||
{
|
||||
if (ImGui::Button("Sphere Collider"))
|
||||
{
|
||||
m_SelectionContext.AddComponent<SphereColliderComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_SelectionContext.HasComponent<MeshColliderComponent>())
|
||||
{
|
||||
if (ImGui::Button("Mesh Collider"))
|
||||
{
|
||||
m_SelectionContext.AddComponent<MeshColliderComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
@ -858,6 +900,101 @@ namespace Prism
|
||||
EndPropertyGrid();
|
||||
});
|
||||
|
||||
DrawComponent<RigidBodyComponent>("Rigidbody", entity, [](RigidBodyComponent& rbc)
|
||||
{
|
||||
// Rigidbody Type
|
||||
const char* rbTypeStrings[] = { "Static", "Dynamic", "Kinematic" };
|
||||
const char* currentType = rbTypeStrings[(int)rbc.BodyType];
|
||||
if (ImGui::BeginCombo("Type", currentType))
|
||||
{
|
||||
for (int type = 0; type < 3; type++)
|
||||
{
|
||||
bool is_selected = (currentType == rbTypeStrings[type]);
|
||||
if (ImGui::Selectable(rbTypeStrings[type], is_selected))
|
||||
{
|
||||
currentType = rbTypeStrings[type];
|
||||
rbc.BodyType = (RigidBodyComponent::Type)type;
|
||||
}
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (rbc.BodyType == RigidBodyComponent::Type::Dynamic)
|
||||
{
|
||||
BeginPropertyGrid();
|
||||
Property("Mass", rbc.Mass);
|
||||
|
||||
if (ImGui::TreeNode("RigidBodyConstraints", "Constraints"))
|
||||
{
|
||||
Property("Position: X", rbc.LockPositionX);
|
||||
Property("Position: Y", rbc.LockPositionY);
|
||||
Property("Position: Z", rbc.LockPositionZ);
|
||||
Property("Rotation: X", rbc.LockRotationX);
|
||||
Property("Rotation: Y", rbc.LockRotationY);
|
||||
Property("Rotation: Z", rbc.LockRotationZ);
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
EndPropertyGrid();
|
||||
}
|
||||
});
|
||||
|
||||
DrawComponent<PhysicsMaterialComponent>("Physics Material", entity, [](PhysicsMaterialComponent& pmc)
|
||||
{
|
||||
BeginPropertyGrid();
|
||||
|
||||
Property("Static Friction", pmc.StaticFriction);
|
||||
Property("Dynamic Friction", pmc.DynamicFriction);
|
||||
Property("Bounciness", pmc.Bounciness);
|
||||
|
||||
EndPropertyGrid();
|
||||
});
|
||||
|
||||
DrawComponent<BoxColliderComponent>("Box Collider", entity, [](BoxColliderComponent& bcc)
|
||||
{
|
||||
BeginPropertyGrid();
|
||||
|
||||
Property("Size", bcc.Size);
|
||||
//Property("Offset", bcc.Offset);
|
||||
|
||||
EndPropertyGrid();
|
||||
});
|
||||
|
||||
DrawComponent<SphereColliderComponent>("Sphere Collider", entity, [](SphereColliderComponent& scc)
|
||||
{
|
||||
BeginPropertyGrid();
|
||||
|
||||
Property("Radius", scc.Radius);
|
||||
|
||||
EndPropertyGrid();
|
||||
});
|
||||
|
||||
DrawComponent<MeshColliderComponent>("Mesh Collider", entity, [](MeshColliderComponent& mc)
|
||||
{
|
||||
ImGui::Columns(3);
|
||||
ImGui::SetColumnWidth(0, 100);
|
||||
ImGui::SetColumnWidth(1, 300);
|
||||
ImGui::SetColumnWidth(2, 40);
|
||||
ImGui::Text("File Path");
|
||||
ImGui::NextColumn();
|
||||
ImGui::PushItemWidth(-1);
|
||||
if (mc.CollisionMesh)
|
||||
ImGui::InputText("##meshfilepath", (char*)mc.CollisionMesh->GetFilePath().c_str(), 256, ImGuiInputTextFlags_ReadOnly);
|
||||
else
|
||||
ImGui::InputText("##meshfilepath", (char*)"Null", 256, ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::NextColumn();
|
||||
if (ImGui::Button("...##openmesh"))
|
||||
{
|
||||
std::string file = Application::Get().OpenFile();
|
||||
if (!file.empty())
|
||||
mc.CollisionMesh = Ref<Mesh>::Create(file);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
203
Prism/src/Prism/Physics/Physics3D.cpp
Normal file
203
Prism/src/Prism/Physics/Physics3D.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
//
|
||||
// Created by sfd on 25-12-16.
|
||||
//
|
||||
|
||||
#include "Physics3D.h"
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/matrix_decompose.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <cooking/PxCooking.h>
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
// TODO: Kinematic Actors
|
||||
// TODO: Rotation/Position Locking
|
||||
// TODO: Collision "layers"
|
||||
// TODO: Expose more of the API to scripts
|
||||
// TODO: Connect/Disconnect PVD
|
||||
// TODO: Collider Shape Rendering
|
||||
// TODO: Relative Transformations for scripts
|
||||
|
||||
static physx::PxSimulationFilterShader s_DefaultFilterShader = physx::PxDefaultSimulationFilterShader;
|
||||
|
||||
static std::tuple<glm::vec3, glm::quat, glm::vec3> GetTransformDecomposition(const glm::mat4& transform)
|
||||
{
|
||||
glm::vec3 scale, translation, skew;
|
||||
glm::vec4 perspective;
|
||||
glm::quat orientation;
|
||||
glm::decompose(transform, scale, orientation, translation, skew, perspective);
|
||||
|
||||
return { translation, orientation, scale };
|
||||
}
|
||||
|
||||
static physx::PxFilterFlags PrismFilterShader(physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1, physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize)
|
||||
{
|
||||
if (physx::PxFilterObjectIsTrigger(attributes0) || physx::PxFilterObjectIsTrigger(attributes1))
|
||||
{
|
||||
pairFlags = physx::PxPairFlag::eTRIGGER_DEFAULT;
|
||||
return physx::PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
pairFlags = physx::PxPairFlag::eCONTACT_DEFAULT;
|
||||
|
||||
if ((filterData0.word0 & filterData1.word1) || (filterData1.word0 & filterData0.word1))
|
||||
{
|
||||
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_FOUND;
|
||||
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_LOST;
|
||||
}
|
||||
|
||||
return physx::PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
|
||||
void Physics3D::Init()
|
||||
{
|
||||
PM_CORE_ASSERT(!s_PXFoundation, "PhysXManager::Init shouldn't be called more than once!");
|
||||
|
||||
s_PXFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, s_PXAllocator, s_PXErrorCallback);
|
||||
PM_CORE_ASSERT(s_PXFoundation, "PxCreateFoundation Failed!");
|
||||
|
||||
PM_CORE_INFO("Try to connect PVD...");
|
||||
s_PXPvd = PxCreatePvd(*s_PXFoundation);
|
||||
physx::PxPvdTransport* transport = physx::PxDefaultPvdSocketTransportCreate("localhost", 5425, 100000000);
|
||||
const bool isConnect = s_PXPvd->connect(*transport, physx::PxPvdInstrumentationFlag::eALL);
|
||||
if (isConnect)
|
||||
{
|
||||
PM_CORE_INFO("PVD connect success");
|
||||
}else
|
||||
{
|
||||
PM_CORE_ERROR("PVD connect failed");
|
||||
}
|
||||
|
||||
s_PXPhysicsFactory = PxCreatePhysics(PX_PHYSICS_VERSION, *s_PXFoundation, physx::PxTolerancesScale(), true, isConnect ? s_PXPvd : nullptr);
|
||||
PM_CORE_ASSERT(s_PXPhysicsFactory, "PxCreatePhysics Failed!");
|
||||
}
|
||||
|
||||
void Physics3D::Shutdown()
|
||||
{
|
||||
s_PXPhysicsFactory->release();
|
||||
s_PXFoundation->release();
|
||||
}
|
||||
|
||||
physx::PxSceneDesc Physics3D::CreateSceneDesc()
|
||||
{
|
||||
physx::PxSceneDesc sceneDesc(s_PXPhysicsFactory->getTolerancesScale());
|
||||
if (!sceneDesc.cpuDispatcher)
|
||||
{
|
||||
physx::PxDefaultCpuDispatcher* mCpuDispatcher = physx::PxDefaultCpuDispatcherCreate(4);
|
||||
PM_CORE_ASSERT(mCpuDispatcher);
|
||||
sceneDesc.cpuDispatcher = mCpuDispatcher;
|
||||
}
|
||||
|
||||
if (!sceneDesc.filterShader)
|
||||
sceneDesc.filterShader = PrismFilterShader;
|
||||
|
||||
return sceneDesc;
|
||||
}
|
||||
|
||||
physx::PxScene* Physics3D::CreateScene(const physx::PxSceneDesc& sceneDesc)
|
||||
{
|
||||
return s_PXPhysicsFactory->createScene(sceneDesc);
|
||||
}
|
||||
|
||||
physx::PxRigidActor* Physics3D::CreateAndAddActor(physx::PxScene* scene, const RigidBodyComponent& rigidbody, const glm::mat4& transform)
|
||||
{
|
||||
physx::PxRigidActor* actor = nullptr;
|
||||
|
||||
if (rigidbody.BodyType == RigidBodyComponent::Type::Static)
|
||||
{
|
||||
actor = s_PXPhysicsFactory->createRigidStatic(CreatePose(transform));
|
||||
}
|
||||
else if (rigidbody.BodyType == RigidBodyComponent::Type::Dynamic)
|
||||
{
|
||||
physx::PxRigidDynamic* dynamicActor = s_PXPhysicsFactory->createRigidDynamic(CreatePose(transform));
|
||||
physx::PxRigidBodyExt::updateMassAndInertia(*dynamicActor, rigidbody.Mass);
|
||||
|
||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X, rigidbody.LockPositionX);
|
||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y, rigidbody.LockPositionY);
|
||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z, rigidbody.LockPositionZ);
|
||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, rigidbody.LockRotationX);
|
||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, rigidbody.LockRotationY);
|
||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, rigidbody.LockRotationZ);
|
||||
|
||||
actor = dynamicActor;
|
||||
}
|
||||
|
||||
actor->setActorFlag(physx::PxActorFlag::eVISUALIZATION, true);
|
||||
|
||||
scene->addActor(*actor);
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
physx::PxMaterial* Physics3D::CreateMaterial(float staticFriction, float dynamicFriction, float restitution)
|
||||
{
|
||||
return s_PXPhysicsFactory->createMaterial(staticFriction, dynamicFriction, restitution);
|
||||
}
|
||||
|
||||
physx::PxConvexMesh* Physics3D::CreateMeshCollider(const Ref<Mesh>& mesh)
|
||||
{
|
||||
const auto& vertices = mesh->GetStaticVertices();
|
||||
const auto& indices = mesh->GetIndices();
|
||||
const physx::PxCookingParams cookingParams(s_PXPhysicsFactory->getTolerancesScale());
|
||||
|
||||
physx::PxConvexMeshDesc convexDesc;
|
||||
convexDesc.points.count = (physx::PxU32)vertices.size();
|
||||
convexDesc.points.stride = sizeof(Vertex);
|
||||
convexDesc.points.data = vertices.data();
|
||||
convexDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX;
|
||||
|
||||
const physx::PxDefaultMemoryOutputStream buf;
|
||||
physx::PxConvexMeshCookingResult::Enum result;
|
||||
|
||||
physx::PxConvexMesh* convexMesh = PxCreateConvexMesh(
|
||||
cookingParams, // 第一步准备的烹饪参数
|
||||
convexDesc, // 第二步准备的网格描述
|
||||
*PxGetStandaloneInsertionCallback(), // 便捷的回调函数,用于将资源插入物理SDK
|
||||
&result // [可选] 获取烹饪结果详情
|
||||
);
|
||||
if (!convexMesh) {
|
||||
PM_CORE_ERROR("Failed to create convex mesh. Cooking result code: {}", static_cast<int>(result));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return convexMesh;
|
||||
}
|
||||
|
||||
physx::PxTransform Physics3D::CreatePose(const glm::mat4& transform)
|
||||
{
|
||||
auto [translation, rotationQuat, scale] = GetTransformDecomposition(transform);
|
||||
const glm::vec3 rotation = glm::eulerAngles(rotationQuat);
|
||||
|
||||
physx::PxTransform physxTransform(physx::PxVec3(translation.x, translation.y, translation.z));
|
||||
physxTransform.rotate(physx::PxVec3(rotation.x, rotation.y, rotation.z));
|
||||
return physxTransform;
|
||||
}
|
||||
|
||||
void Physics3D::SetCollisionFilters(physx::PxRigidActor* actor, uint32_t filterGroup, uint32_t filterMask)
|
||||
{
|
||||
physx::PxFilterData filterData;
|
||||
filterData.word0 = filterGroup; // word0 = own ID
|
||||
filterData.word1 = filterMask; // word1 = ID mask to filter pairs that trigger a
|
||||
// contact callback;
|
||||
const physx::PxU32 numShapes = actor->getNbShapes();
|
||||
physx::PxShape** shapes = (physx::PxShape**)s_PXAllocator.allocate(sizeof(physx::PxShape*) * numShapes, "", "", 0);
|
||||
actor->getShapes(shapes, numShapes);
|
||||
for (physx::PxU32 i = 0; i < numShapes; i++)
|
||||
{
|
||||
physx::PxShape* shape = shapes[i];
|
||||
shape->setFlag(physx::PxShapeFlag::eVISUALIZATION, true);
|
||||
shape->setSimulationFilterData(filterData);
|
||||
}
|
||||
|
||||
s_PXAllocator.deallocate(shapes);
|
||||
}
|
||||
|
||||
physx::PxDefaultErrorCallback Physics3D::s_PXErrorCallback;
|
||||
physx::PxDefaultAllocator Physics3D::s_PXAllocator;
|
||||
physx::PxFoundation* Physics3D::s_PXFoundation;
|
||||
physx::PxPhysics* Physics3D::s_PXPhysicsFactory;
|
||||
physx::PxPvd* Physics3D::s_PXPvd;
|
||||
}
|
||||
56
Prism/src/Prism/Physics/Physics3D.h
Normal file
56
Prism/src/Prism/Physics/Physics3D.h
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// Created by sfd on 25-12-16.
|
||||
//
|
||||
|
||||
#ifndef PHYSXMANAGER_H
|
||||
#define PHYSXMANAGER_H
|
||||
#define PX_PHYSX_STATIC_LIB
|
||||
#include <PxPhysicsAPI.h>
|
||||
#include "glm/glm.hpp"
|
||||
#include "Prism/Scene/Components.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
enum class ForceMode : uint16_t
|
||||
{
|
||||
Force = 0,
|
||||
Impulse,
|
||||
VelocityChange,
|
||||
Acceleration
|
||||
};
|
||||
|
||||
enum class FilterGroup : uint32_t
|
||||
{
|
||||
Static = BIT(0),
|
||||
Dynamic = BIT(1),
|
||||
Kinematic = BIT(2),
|
||||
All = Static | Dynamic | Kinematic
|
||||
};
|
||||
|
||||
class PRISM_API Physics3D
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
|
||||
static physx::PxSceneDesc CreateSceneDesc();
|
||||
static physx::PxScene* CreateScene(const physx::PxSceneDesc& sceneDesc);
|
||||
static physx::PxRigidActor* CreateAndAddActor(physx::PxScene* scene, const RigidBodyComponent& rigidbody, const glm::mat4& transform);
|
||||
static physx::PxMaterial* CreateMaterial(float staticFriction, float dynamicFriction, float restitution);
|
||||
static physx::PxConvexMesh* CreateMeshCollider(const Ref<Mesh>& mesh);
|
||||
|
||||
static physx::PxTransform CreatePose(const glm::mat4& transform);
|
||||
|
||||
static void SetCollisionFilters(physx::PxRigidActor* actor, uint32_t filterGroup, uint32_t filterMask);
|
||||
|
||||
// private:
|
||||
static physx::PxDefaultErrorCallback s_PXErrorCallback;
|
||||
static physx::PxDefaultAllocator s_PXAllocator;
|
||||
static physx::PxFoundation* s_PXFoundation;
|
||||
static physx::PxPhysics* s_PXPhysicsFactory;
|
||||
static physx::PxPvd* s_PXPvd;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PHYSXMANAGER_H
|
||||
@ -115,6 +115,9 @@ namespace Prism
|
||||
std::vector<Submesh>& GetSubmeshes() { return m_Submeshes; }
|
||||
const std::vector<Submesh>& GetSubmeshes() const { return m_Submeshes; }
|
||||
|
||||
const std::vector<Vertex>& GetStaticVertices() const { return m_StaticVertices; }
|
||||
const std::vector<Index>& GetIndices() const { return m_Indices; }
|
||||
|
||||
inline Ref<Shader> GetMeshShader() { return m_MeshShader; }
|
||||
inline Ref<Material> GetMaterial() { return m_BaseMaterial; }
|
||||
std::vector<Ref<MaterialInstance>>& GetMaterials() { return m_Materials; }
|
||||
|
||||
@ -137,6 +137,81 @@ namespace Prism
|
||||
CircleCollider2DComponent() = default;
|
||||
CircleCollider2DComponent(const CircleCollider2DComponent& other) = default;
|
||||
};
|
||||
|
||||
|
||||
struct SphereColliderComponent
|
||||
{
|
||||
float Radius = 1.0f;
|
||||
|
||||
// TODO: Physics Material
|
||||
|
||||
SphereColliderComponent() = default;
|
||||
SphereColliderComponent(const SphereColliderComponent& other) = default;
|
||||
};
|
||||
|
||||
struct RigidBodyComponent
|
||||
{
|
||||
enum class Type { Static, Dynamic, Kinematic };
|
||||
Type BodyType;
|
||||
float Mass = 1.0f;
|
||||
|
||||
bool LockPositionX = false;
|
||||
bool LockPositionY = false;
|
||||
bool LockPositionZ = false;
|
||||
bool LockRotationX = false;
|
||||
bool LockRotationY = false;
|
||||
bool LockRotationZ = false;
|
||||
|
||||
void* RuntimeActor = nullptr;
|
||||
|
||||
RigidBodyComponent() = default;
|
||||
RigidBodyComponent(const RigidBodyComponent& other) = default;
|
||||
};
|
||||
|
||||
// TODO: This will eventually be a resource, but that requires object referencing through the editor
|
||||
struct PhysicsMaterialComponent
|
||||
{
|
||||
float StaticFriction = 1.0f;
|
||||
float DynamicFriction = 1.0f;
|
||||
float Bounciness = 1.0f;
|
||||
|
||||
PhysicsMaterialComponent() = default;
|
||||
PhysicsMaterialComponent(const PhysicsMaterialComponent& other) = default;
|
||||
};
|
||||
|
||||
struct BoxColliderComponent
|
||||
{
|
||||
glm::vec3 Size = { 1.0f, 1.0f, 1.0f };
|
||||
glm::vec3 Offset = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
BoxColliderComponent() = default;
|
||||
BoxColliderComponent(const BoxColliderComponent& other) = default;
|
||||
};
|
||||
|
||||
struct CapsuleColliderComponent
|
||||
{
|
||||
float Radius = 0.5f;
|
||||
float Height = 1.0f;
|
||||
|
||||
CapsuleColliderComponent() = default;
|
||||
CapsuleColliderComponent(const CapsuleColliderComponent& other) = default;
|
||||
};
|
||||
|
||||
struct MeshColliderComponent
|
||||
{
|
||||
Ref<Prism::Mesh> CollisionMesh;
|
||||
|
||||
MeshColliderComponent() = default;
|
||||
MeshColliderComponent(const MeshColliderComponent& other) = default;
|
||||
MeshColliderComponent(const Ref<Prism::Mesh>& mesh)
|
||||
: CollisionMesh(mesh)
|
||||
{
|
||||
}
|
||||
|
||||
operator Ref<Prism::Mesh>() { return CollisionMesh; }
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -14,15 +14,18 @@
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/matrix_decompose.hpp>
|
||||
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
|
||||
// TODO: THIS SHOULD MOVE TO PHYSICS FILE!
|
||||
|
||||
|
||||
|
||||
std::unordered_map<UUID, Scene*> s_ActiveScenes;
|
||||
|
||||
static physx::PxDefaultErrorCallback s_PXErrorCallback;
|
||||
static physx::PxDefaultAllocator s_PXAllocator;
|
||||
static physx::PxFoundation* s_PXFoundation;
|
||||
|
||||
static uint32_t s_SceneIDCounter = 0;
|
||||
|
||||
struct SceneComponent
|
||||
@ -42,6 +45,13 @@ namespace Prism
|
||||
}
|
||||
};
|
||||
|
||||
struct PhysXSceneComponent
|
||||
{
|
||||
// NOTE: PhysX does some internal ref counting, and thus doesn't allow unique_ptr
|
||||
physx::PxScene* World;
|
||||
};
|
||||
|
||||
|
||||
void ProcessContactEvents(const b2WorldId worldId) {
|
||||
const b2ContactEvents contactEvents = b2World_GetContactEvents(worldId);
|
||||
|
||||
@ -75,6 +85,65 @@ namespace Prism
|
||||
}
|
||||
}
|
||||
|
||||
class PhysXContactListener : public physx::PxSimulationEventCallback
|
||||
{
|
||||
public:
|
||||
virtual void onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count) override
|
||||
{
|
||||
PX_UNUSED(constraints);
|
||||
PX_UNUSED(count);
|
||||
}
|
||||
|
||||
virtual void onWake(physx::PxActor** actors, physx::PxU32 count) override
|
||||
{
|
||||
PX_UNUSED(actors);
|
||||
PX_UNUSED(count);
|
||||
}
|
||||
|
||||
virtual void onSleep(physx::PxActor** actors, physx::PxU32 count) override
|
||||
{
|
||||
PX_UNUSED(actors);
|
||||
PX_UNUSED(count);
|
||||
}
|
||||
|
||||
virtual void onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) override
|
||||
{
|
||||
Entity& a = *(Entity*)pairHeader.actors[0]->userData;
|
||||
Entity& b = *(Entity*)pairHeader.actors[1]->userData;
|
||||
|
||||
if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_HAS_FIRST_TOUCH)
|
||||
{
|
||||
if (a.HasComponent<ScriptComponent>() && ScriptEngine::ModuleExists(a.GetComponent<ScriptComponent>().ModuleName))
|
||||
ScriptEngine::OnCollisionBegin(a);
|
||||
|
||||
if (b.HasComponent<ScriptComponent>() && ScriptEngine::ModuleExists(b.GetComponent<ScriptComponent>().ModuleName))
|
||||
ScriptEngine::OnCollisionBegin(b);
|
||||
}
|
||||
else if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_LOST_TOUCH)
|
||||
{
|
||||
if (a.HasComponent<ScriptComponent>() && ScriptEngine::ModuleExists(a.GetComponent<ScriptComponent>().ModuleName))
|
||||
ScriptEngine::OnCollisionEnd(a);
|
||||
|
||||
if (b.HasComponent<ScriptComponent>() && ScriptEngine::ModuleExists(b.GetComponent<ScriptComponent>().ModuleName))
|
||||
ScriptEngine::OnCollisionEnd(b);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count) override
|
||||
{
|
||||
PX_UNUSED(pairs);
|
||||
PX_UNUSED(count);
|
||||
}
|
||||
|
||||
virtual void onAdvance(const physx::PxRigidBody* const* bodyBuffer, const physx::PxTransform* poseBuffer, const physx::PxU32 count) override
|
||||
{
|
||||
PX_UNUSED(bodyBuffer);
|
||||
PX_UNUSED(poseBuffer);
|
||||
PX_UNUSED(count);
|
||||
}
|
||||
};
|
||||
|
||||
static PhysXContactListener s_PhysXContactListener;
|
||||
|
||||
|
||||
void OnTransformConstruct(entt::registry& registry, entt::entity entity)
|
||||
@ -134,6 +203,26 @@ namespace Prism
|
||||
|
||||
s_ActiveScenes[m_SceneID] = this;
|
||||
|
||||
|
||||
physx::PxSceneDesc sceneDesc = Physics3D::CreateSceneDesc();
|
||||
sceneDesc.gravity = physx::PxVec3(0.0f, -9.8f, 0.0f);
|
||||
sceneDesc.simulationEventCallback = &s_PhysXContactListener;
|
||||
|
||||
const PhysXSceneComponent& physxWorld = m_Registry.emplace<PhysXSceneComponent>(m_SceneEntity, Physics3D::CreateScene(sceneDesc));
|
||||
physx::PxPvdSceneClient* pvdClient = physxWorld.World->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(physx::PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(physx::PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(physx::PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}else
|
||||
{
|
||||
PM_CORE_WARN("you are using pvd to debug: ");
|
||||
PM_CORE_WARN("PvdSceneClient is null is pvd running or you are using release/profile PhysX?");
|
||||
PM_CORE_WARN("to using Pvd, should using debug/checked version to build!");
|
||||
}
|
||||
PM_CORE_ASSERT(physxWorld.World);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
@ -147,11 +236,20 @@ namespace Prism
|
||||
|
||||
void Scene::Init()
|
||||
{
|
||||
auto skyboxShader = Shader::Create("assets/shaders/Skybox.glsl");
|
||||
const auto skyboxShader = Shader::Create("assets/shaders/Skybox.glsl");
|
||||
m_SkyboxMaterial = MaterialInstance::Create(Material::Create(skyboxShader));
|
||||
m_SkyboxMaterial->SetFlag(MaterialFlag::DepthTest, false);
|
||||
}
|
||||
|
||||
void Scene::OnShutdown()
|
||||
{
|
||||
auto b2WorldView = m_Registry.view<Box2DWorldComponent>();
|
||||
b2DestroyWorld(m_Registry.get<Box2DWorldComponent>(m_SceneEntity).World);
|
||||
|
||||
auto physxView = m_Registry.view<PhysXSceneComponent>();
|
||||
m_Registry.get<PhysXSceneComponent>(m_SceneEntity).World->release();
|
||||
}
|
||||
|
||||
void Scene::OnUpdate(TimeStep ts)
|
||||
{
|
||||
// Update all entities
|
||||
@ -175,16 +273,8 @@ namespace Prism
|
||||
// box2DWorld->Step(ts, velocityIterations, positionIterations);
|
||||
b2World_Step(box2DWorld, ts, positionIterations);
|
||||
|
||||
{
|
||||
// Process Contact Envents box2d version 3.0^ should impl contact event after b2World_Step
|
||||
ProcessContactEvents(box2DWorld);
|
||||
/*
|
||||
const b2ContactEvents contactEvents = b2World_GetContactEvents(box2DWorld);
|
||||
if (contactEvents.beginCount > 0)
|
||||
PM_CORE_WARN("collision box counts in begin: {}", contactEvents.beginCount);
|
||||
if (contactEvents.endCount > 0)
|
||||
PM_CORE_WARN("collision box counts in end: {}", contactEvents.endCount);
|
||||
*/
|
||||
}
|
||||
|
||||
{
|
||||
const auto view = m_Registry.view<RigidBody2DComponent>();
|
||||
@ -206,6 +296,65 @@ namespace Prism
|
||||
}
|
||||
}
|
||||
|
||||
// PhysX Physics
|
||||
auto physxView = m_Registry.view<PhysXSceneComponent>();
|
||||
physx::PxScene* physxScene = m_Registry.get<PhysXSceneComponent>(physxView.front()).World;
|
||||
|
||||
constexpr float stepSize = 0.016666660f;
|
||||
physxScene->simulate(stepSize);
|
||||
physxScene->fetchResults(true);
|
||||
|
||||
{
|
||||
auto view = m_Registry.view<RigidBodyComponent>();
|
||||
for (auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& transform = e.Transform();
|
||||
RigidBodyComponent& rb = e.GetComponent<RigidBodyComponent>();
|
||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rb.RuntimeActor);
|
||||
const auto& position = actor->getGlobalPose().p;
|
||||
const physx::PxQuat& physicsBodyRotation = actor->getGlobalPose().q;
|
||||
|
||||
auto [translation, rotationQuat, scale] = GetTransformDecomposition(transform);
|
||||
|
||||
if (rb.BodyType == RigidBodyComponent::Type::Dynamic)
|
||||
{
|
||||
/*
|
||||
// If the rigidbody is dynamic, the position of the entity is determined by the rigidbody
|
||||
// TODO: Get rotation from RigidActor
|
||||
float xAngle, yAngle, zAngle;
|
||||
physx::PxVec3 axis;
|
||||
physicsBodyRotation.toRadiansAndUnitAxis(xAngle, axis);
|
||||
physicsBodyRotation.toRadiansAndUnitAxis(yAngle, axis);
|
||||
physicsBodyRotation.toRadiansAndUnitAxis(zAngle, axis);
|
||||
|
||||
transform = glm::translate(glm::mat4(1.0f), { position.x, position.y, position.z }) *
|
||||
glm::toMat4(glm::quat({ xAngle, yAngle, zAngle })) *
|
||||
glm::scale(glm::mat4(1.0f), scale);
|
||||
*/
|
||||
|
||||
// 获取物理引擎的位置和旋转
|
||||
physx::PxTransform globalPose = actor->getGlobalPose();
|
||||
const physx::PxVec3& pos = globalPose.p;
|
||||
const physx::PxQuat& physicsQuat = globalPose.q;
|
||||
|
||||
glm::quat glmQuat{physicsQuat.w, physicsQuat.x, physicsQuat.y, physicsQuat.z};
|
||||
|
||||
// 使用转换后的四元数创建变换矩阵
|
||||
transform = glm::translate(glm::mat4(1.0f),
|
||||
glm::vec3(pos.x, pos.y, pos.z)) *
|
||||
glm::toMat4(glmQuat) *
|
||||
glm::scale(glm::mat4(1.0f), scale);
|
||||
|
||||
}
|
||||
else if (rb.BodyType == RigidBodyComponent::Type::Static)
|
||||
{
|
||||
// If the rigidbody is static, make sure the actor is at the entitys position
|
||||
actor->setGlobalPose(Physics3D::CreatePose(transform));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Scene::OnRenderRuntime(TimeStep ts)
|
||||
@ -328,7 +477,7 @@ namespace Prism
|
||||
auto& world = m_Registry.get<Box2DWorldComponent>(sceneView.front()).World;
|
||||
{
|
||||
auto view = m_Registry.view<RigidBody2DComponent>();
|
||||
m_PhysicsBodyEntityBuffer = new Entity[view.size()];
|
||||
m_Physics2DBodyEntityBuffer = new Entity[view.size()];
|
||||
uint32_t physicsBodyEntityBufferIndex = 0;
|
||||
for (auto entity : view)
|
||||
{
|
||||
@ -353,7 +502,7 @@ namespace Prism
|
||||
// box2D fixRotation renamed to motionlocks
|
||||
bodyDef.motionLocks = b2MotionLocks{false, false, rigidBody2D.FixedRotation};
|
||||
|
||||
Entity* entityStorage = &m_PhysicsBodyEntityBuffer[physicsBodyEntityBufferIndex++];
|
||||
Entity* entityStorage = &m_Physics2DBodyEntityBuffer[physicsBodyEntityBufferIndex++];
|
||||
*entityStorage = e;
|
||||
bodyDef.userData = entityStorage;
|
||||
|
||||
@ -420,12 +569,161 @@ namespace Prism
|
||||
}
|
||||
|
||||
|
||||
auto physxView = m_Registry.view<PhysXSceneComponent>();
|
||||
physx::PxScene* physxWorld = m_Registry.get<PhysXSceneComponent>(physxView.front()).World;
|
||||
|
||||
{
|
||||
auto view = m_Registry.view<RigidBodyComponent>();
|
||||
m_Physics3DBodyEntityBuffer = new Entity[view.size()];
|
||||
uint32_t physicsBodyEntityBufferIndex = 0;
|
||||
|
||||
for (auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
UUID entityID = e.GetComponent<IDComponent>().ID;
|
||||
auto& transform = e.Transform();
|
||||
auto& rigidbody = m_Registry.get<RigidBodyComponent>(entity);
|
||||
|
||||
physx::PxRigidActor* actor = Physics3D::CreateAndAddActor(physxWorld, rigidbody, transform);
|
||||
PM_CORE_ASSERT(actor);
|
||||
|
||||
Entity* entityStorage = &m_Physics3DBodyEntityBuffer[physicsBodyEntityBufferIndex++];
|
||||
*entityStorage = e;
|
||||
actor->userData = (void*)entityStorage;
|
||||
|
||||
rigidbody.RuntimeActor = actor;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto view = m_Registry.view<BoxColliderComponent>();
|
||||
for (auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& transform = e.Transform();
|
||||
|
||||
auto& boxCollider = m_Registry.get<BoxColliderComponent>(entity);
|
||||
if (e.HasComponent<RigidBodyComponent>())
|
||||
{
|
||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
||||
auto& physicsMaterial = e.GetComponent<PhysicsMaterialComponent>();
|
||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
||||
|
||||
physx::PxBoxGeometry boxGeometry = physx::PxBoxGeometry(boxCollider.Size.x / 2.0F, boxCollider.Size.y / 2.0F, boxCollider.Size.z / 2.0F);
|
||||
physx::PxMaterial* material = Physics3D::CreateMaterial(physicsMaterial.StaticFriction, physicsMaterial.DynamicFriction, physicsMaterial.Bounciness);
|
||||
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor, boxGeometry, *material);
|
||||
shape->setLocalPose(Physics3D::CreatePose(glm::translate(glm::mat4(1.0F), boxCollider.Offset)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto view = m_Registry.view<SphereColliderComponent>();
|
||||
for (auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& transform = e.Transform();
|
||||
|
||||
auto& sphereCollider = m_Registry.get<SphereColliderComponent>(entity);
|
||||
if (e.HasComponent<RigidBodyComponent>())
|
||||
{
|
||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
||||
auto& physicsMaterial = e.GetComponent<PhysicsMaterialComponent>();
|
||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
||||
physx::PxSphereGeometry sphereGeometry = physx::PxSphereGeometry(sphereCollider.Radius);
|
||||
physx::PxMaterial* material = Physics3D::CreateMaterial(physicsMaterial.StaticFriction, physicsMaterial.DynamicFriction, physicsMaterial.Bounciness);
|
||||
physx::PxRigidActorExt::createExclusiveShape(*actor, sphereGeometry, *material);
|
||||
|
||||
physx::PxRigidDynamic* rigidBodyActor = actor->is<physx::PxRigidDynamic>();
|
||||
|
||||
if (rigidBodyActor)
|
||||
{
|
||||
rigidBodyActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, true);
|
||||
rigidBodyActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, true);
|
||||
rigidBodyActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto view = m_Registry.view<CapsuleColliderComponent>();
|
||||
for (auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& transform = e.Transform();
|
||||
|
||||
auto& capsuleCollider = m_Registry.get<CapsuleColliderComponent>(entity);
|
||||
if (e.HasComponent<RigidBodyComponent>())
|
||||
{
|
||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
||||
auto& physicsMaterial = e.GetComponent<PhysicsMaterialComponent>();
|
||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
||||
physx::PxCapsuleGeometry capsuleGeometry = physx::PxCapsuleGeometry(capsuleCollider.Radius, capsuleCollider.Height / 2.0F);
|
||||
physx::PxMaterial* material = Physics3D::CreateMaterial(physicsMaterial.StaticFriction, physicsMaterial.DynamicFriction, physicsMaterial.Bounciness);
|
||||
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor, capsuleGeometry, *material);
|
||||
|
||||
// Make sure that the capsule is facing up (+Y)
|
||||
shape->setLocalPose(physx::PxTransform(physx::PxQuat(physx::PxHalfPi, physx::PxVec3(0, 0, 1))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto meshView = m_Registry.view<MeshColliderComponent>();
|
||||
for (auto entity : meshView)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& transform = e.Transform();
|
||||
|
||||
auto& meshCollider = m_Registry.get<MeshColliderComponent>(entity);
|
||||
if (e.HasComponent<RigidBodyComponent>())
|
||||
{
|
||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
||||
auto& physicsMaterial = e.GetComponent<PhysicsMaterialComponent>();
|
||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
||||
|
||||
physx::PxConvexMesh* triangleMesh = Physics3D::CreateMeshCollider(meshCollider);
|
||||
PM_CORE_ASSERT(triangleMesh);
|
||||
|
||||
physx::PxConvexMeshGeometry triangleGeometry = physx::PxConvexMeshGeometry(triangleMesh);
|
||||
physx::PxMaterial* material = Physics3D::CreateMaterial(physicsMaterial.StaticFriction, physicsMaterial.DynamicFriction, physicsMaterial.Bounciness);
|
||||
physx::PxRigidActorExt::createExclusiveShape(*actor, triangleGeometry, *material);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup Collision Filters
|
||||
auto rbView = m_Registry.view<RigidBodyComponent>();
|
||||
for (auto entity : rbView)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
||||
|
||||
if (rigidBody.BodyType == RigidBodyComponent::Type::Static)
|
||||
Physics3D::SetCollisionFilters(actor, (uint32_t)FilterGroup::Static, (uint32_t)FilterGroup::All);
|
||||
else if (rigidBody.BodyType == RigidBodyComponent::Type::Dynamic)
|
||||
Physics3D::SetCollisionFilters(actor, (uint32_t)FilterGroup::Dynamic, (uint32_t)FilterGroup::All);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_IsPlaying = true;
|
||||
}
|
||||
|
||||
void Scene::OnRuntimeStop()
|
||||
{
|
||||
delete[] m_PhysicsBodyEntityBuffer;
|
||||
auto physxView = m_Registry.view<PhysXSceneComponent>();
|
||||
m_Registry.get<PhysXSceneComponent>(m_SceneEntity).World->release();
|
||||
|
||||
|
||||
delete[] m_Physics3DBodyEntityBuffer;
|
||||
delete[] m_Physics2DBodyEntityBuffer;
|
||||
m_IsPlaying = false;
|
||||
}
|
||||
|
||||
@ -534,6 +832,11 @@ namespace Prism
|
||||
CopyComponentIfExists<RigidBody2DComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||
CopyComponentIfExists<BoxCollider2DComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||
CopyComponentIfExists<CircleCollider2DComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||
CopyComponentIfExists<RigidBodyComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||
CopyComponentIfExists<PhysicsMaterialComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||
CopyComponentIfExists<BoxColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||
CopyComponentIfExists<SphereColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||
CopyComponentIfExists<MeshColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||
}
|
||||
|
||||
Entity Scene::FindEntityByTag(const std::string &tag) {
|
||||
@ -577,6 +880,11 @@ namespace Prism
|
||||
CopyComponent<RigidBody2DComponent>(target->m_Registry, m_Registry, enttMap);
|
||||
CopyComponent<BoxCollider2DComponent>(target->m_Registry, m_Registry, enttMap);
|
||||
CopyComponent<CircleCollider2DComponent>(target->m_Registry, m_Registry, enttMap);
|
||||
CopyComponent<RigidBodyComponent>(target->m_Registry, m_Registry, enttMap);
|
||||
CopyComponent<PhysicsMaterialComponent>(target->m_Registry, m_Registry, enttMap);
|
||||
CopyComponent<BoxColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
||||
CopyComponent<SphereColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
||||
CopyComponent<MeshColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
||||
|
||||
const auto& entityInstanceMap = ScriptEngine::GetEntityInstanceMap();
|
||||
if (entityInstanceMap.find(target->GetUUID()) != entityInstanceMap.end())
|
||||
|
||||
@ -44,6 +44,7 @@ namespace Prism
|
||||
~Scene();
|
||||
|
||||
void Init();
|
||||
void OnShutdown();
|
||||
|
||||
void OnUpdate(TimeStep ts);
|
||||
void OnRenderRuntime(TimeStep ts);
|
||||
@ -109,7 +110,8 @@ namespace Prism
|
||||
EntityMap m_EntityIDMap;
|
||||
|
||||
entt::entity m_SelectedEntity;
|
||||
Entity* m_PhysicsBodyEntityBuffer = nullptr;
|
||||
Entity* m_Physics2DBodyEntityBuffer = nullptr;
|
||||
Entity* m_Physics3DBodyEntityBuffer = nullptr;
|
||||
|
||||
Light m_Light;
|
||||
float m_LightMultiplier = 0.3f;
|
||||
|
||||
@ -329,6 +329,77 @@ namespace Prism
|
||||
out << YAML::EndMap; // CircleCollider2DComponent
|
||||
}
|
||||
|
||||
if (entity.HasComponent<RigidBodyComponent>())
|
||||
{
|
||||
out << YAML::Key << "RigidBodyComponent";
|
||||
out << YAML::BeginMap; // RigidBodyComponent
|
||||
|
||||
auto& rigidbodyComponent = entity.GetComponent<RigidBodyComponent>();
|
||||
out << YAML::Key << "BodyType" << YAML::Value << (int)rigidbodyComponent.BodyType;
|
||||
out << YAML::Key << "Mass" << YAML::Value << rigidbodyComponent.Mass;
|
||||
|
||||
out << YAML::Key << "Constraints";
|
||||
out << YAML::BeginMap; // Constraints
|
||||
|
||||
out << YAML::Key << "LockPositionX" << YAML::Value << rigidbodyComponent.LockPositionX;
|
||||
out << YAML::Key << "LockPositionY" << YAML::Value << rigidbodyComponent.LockPositionY;
|
||||
out << YAML::Key << "LockPositionZ" << YAML::Value << rigidbodyComponent.LockPositionZ;
|
||||
out << YAML::Key << "LockRotationX" << YAML::Value << rigidbodyComponent.LockRotationX;
|
||||
out << YAML::Key << "LockRotationY" << YAML::Value << rigidbodyComponent.LockRotationY;
|
||||
out << YAML::Key << "LockRotationZ" << YAML::Value << rigidbodyComponent.LockRotationZ;
|
||||
|
||||
out << YAML::EndMap;
|
||||
|
||||
out << YAML::EndMap; // RigidBodyComponent
|
||||
}
|
||||
|
||||
if (entity.HasComponent<PhysicsMaterialComponent>())
|
||||
{
|
||||
out << YAML::Key << "PhysicsMaterialComponent";
|
||||
out << YAML::BeginMap; // PhysicsMaterialComponent
|
||||
|
||||
auto& physicsMaterial = entity.GetComponent<PhysicsMaterialComponent>();
|
||||
out << YAML::Key << "StaticFriction" << YAML::Value << physicsMaterial.StaticFriction;
|
||||
out << YAML::Key << "DynamicFriction" << YAML::Value << physicsMaterial.DynamicFriction;
|
||||
out << YAML::Key << "Bounciness" << YAML::Value << physicsMaterial.Bounciness;
|
||||
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
if (entity.HasComponent<BoxColliderComponent>())
|
||||
{
|
||||
out << YAML::Key << "BoxColliderComponent";
|
||||
out << YAML::BeginMap; // BoxColliderComponent
|
||||
|
||||
auto& boxColliderComponent = entity.GetComponent<BoxColliderComponent>();
|
||||
out << YAML::Key << "Offset" << YAML::Value << boxColliderComponent.Offset;
|
||||
out << YAML::Key << "Size" << YAML::Value << boxColliderComponent.Size;
|
||||
|
||||
out << YAML::EndMap; // BoxColliderComponent
|
||||
}
|
||||
|
||||
if (entity.HasComponent<SphereColliderComponent>())
|
||||
{
|
||||
out << YAML::Key << "SphereColliderComponent";
|
||||
out << YAML::BeginMap; // SphereColliderComponent
|
||||
|
||||
auto& sphereColliderComponent = entity.GetComponent<SphereColliderComponent>();
|
||||
out << YAML::Key << "Radius" << YAML::Value << sphereColliderComponent.Radius;
|
||||
|
||||
out << YAML::EndMap; // SphereColliderComponent
|
||||
}
|
||||
|
||||
if (entity.HasComponent<MeshColliderComponent>())
|
||||
{
|
||||
out << YAML::Key << "MeshColliderComponent";
|
||||
out << YAML::BeginMap; // MeshColliderComponent
|
||||
|
||||
auto mesh = entity.GetComponent<MeshColliderComponent>().CollisionMesh;
|
||||
out << YAML::Key << "AssetPath" << YAML::Value << mesh->GetFilePath();
|
||||
|
||||
out << YAML::EndMap; // MeshColliderComponent
|
||||
}
|
||||
|
||||
out << YAML::EndMap; // Entity
|
||||
}
|
||||
|
||||
@ -562,6 +633,49 @@ namespace Prism
|
||||
component.Density = circleCollider2DComponent["Density"] ? circleCollider2DComponent["Density"].as<float>() : 1.0f;
|
||||
component.Friction = circleCollider2DComponent["Friction"] ? circleCollider2DComponent["Friction"].as<float>() : 1.0f;
|
||||
}
|
||||
|
||||
if (auto rigidBodyComponent = entity["RigidBodyComponent"])
|
||||
{
|
||||
auto& component = deserializedEntity.AddComponent<RigidBodyComponent>();
|
||||
component.BodyType = (RigidBodyComponent::Type)rigidBodyComponent["BodyType"].as<int>();
|
||||
component.Mass = rigidBodyComponent["Mass"].as<float>();
|
||||
|
||||
component.LockPositionX = rigidBodyComponent["LockPositionX"] ? rigidBodyComponent["LockPositionX"].as<bool>() : false;
|
||||
component.LockPositionY = rigidBodyComponent["LockPositionY"] ? rigidBodyComponent["LockPositionY"].as<bool>() : false;
|
||||
component.LockPositionZ = rigidBodyComponent["LockPositionZ"] ? rigidBodyComponent["LockPositionZ"].as<bool>() : false;
|
||||
component.LockRotationX = rigidBodyComponent["LockRotationX"] ? rigidBodyComponent["LockRotationX"].as<bool>() : false;
|
||||
component.LockRotationY = rigidBodyComponent["LockRotationY"] ? rigidBodyComponent["LockRotationY"].as<bool>() : false;
|
||||
component.LockRotationZ = rigidBodyComponent["LockRotationZ"] ? rigidBodyComponent["LockRotationZ"].as<bool>() : false;
|
||||
}
|
||||
|
||||
if (auto physicsMaterialComponent = entity["PhysicsMaterialComponent"])
|
||||
{
|
||||
auto& component = deserializedEntity.AddComponent<PhysicsMaterialComponent>();
|
||||
component.StaticFriction = physicsMaterialComponent["StaticFriction"].as<float>();
|
||||
component.DynamicFriction = physicsMaterialComponent["DynamicFriction"].as<float>();
|
||||
component.Bounciness = physicsMaterialComponent["Bounciness"].as<float>();
|
||||
}
|
||||
|
||||
if (auto boxColliderComponent = entity["BoxColliderComponent"])
|
||||
{
|
||||
auto& component = deserializedEntity.AddComponent<BoxColliderComponent>();
|
||||
component.Offset = boxColliderComponent["Offset"].as<glm::vec3>();
|
||||
component.Size = boxColliderComponent["Size"].as<glm::vec3>();
|
||||
}
|
||||
|
||||
if (auto sphereColliderComponent = entity["SphereColliderComponent"])
|
||||
{
|
||||
auto& component = deserializedEntity.AddComponent<SphereColliderComponent>();
|
||||
component.Radius = sphereColliderComponent["Radius"].as<float>();
|
||||
}
|
||||
|
||||
if (auto meshColliderComponent = entity["MeshColliderComponent"])
|
||||
{
|
||||
auto meshPath = meshColliderComponent["AssetPath"].as<std::string>();
|
||||
deserializedEntity.AddComponent<MeshColliderComponent>(Ref<Mesh>::Create(meshPath));
|
||||
|
||||
PM_CORE_INFO(" Mesh Collider Asset Path: {0}", meshPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -20,6 +20,8 @@
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
#define ENABLE_MONO_DEBUG
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
static MonoDomain* s_MonoDomain = nullptr;
|
||||
@ -48,6 +50,8 @@ namespace Prism
|
||||
MonoMethod* OnUpdateMethod = nullptr;
|
||||
|
||||
// Physics
|
||||
MonoMethod* OnCollisionBeginMethod = nullptr;
|
||||
MonoMethod* OnCollisionEndMethod = nullptr;
|
||||
MonoMethod* OnCollision2DBeginMethod = nullptr;
|
||||
MonoMethod* OnCollision2DEndMethod = nullptr;
|
||||
|
||||
@ -59,6 +63,9 @@ namespace Prism
|
||||
// Physics (Entity class)
|
||||
OnCollision2DBeginMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollision2DBegin(single)");
|
||||
OnCollision2DEndMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollision2DEnd(single)");
|
||||
OnCollisionBeginMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollisionBegin(single)");
|
||||
OnCollisionEndMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollisionEnd(single)");
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@ -423,6 +430,7 @@ namespace Prism
|
||||
auto& dstModuleFieldMap = dstEntityMap[entityID].ModuleFieldMap;
|
||||
for (auto& [fieldName, field] : srcFieldMap)
|
||||
{
|
||||
volatile auto name = fieldName;
|
||||
PM_CORE_ASSERT(dstModuleFieldMap.find(moduleName) != dstModuleFieldMap.end());
|
||||
auto& fieldMap = dstModuleFieldMap.at(moduleName);
|
||||
PM_CORE_ASSERT(fieldMap.find(fieldName) != fieldMap.end());
|
||||
@ -488,6 +496,38 @@ namespace Prism
|
||||
|
||||
}
|
||||
|
||||
void ScriptEngine::OnCollisionBegin(Entity entity)
|
||||
{
|
||||
OnCollisionBegin(entity.m_Scene->GetUUID(), entity.GetComponent<IDComponent>().ID);
|
||||
}
|
||||
|
||||
void ScriptEngine::OnCollisionBegin(const UUID& sceneID, const UUID& entityID)
|
||||
{
|
||||
EntityInstance& entityInstance = GetEntityInstanceData(sceneID, entityID).Instance;
|
||||
if (entityInstance.ScriptClass->OnCollisionBeginMethod)
|
||||
{
|
||||
float value = 5.0f;
|
||||
void* args[] = { &value };
|
||||
CallMethod(entityInstance.GetInstance(), entityInstance.ScriptClass->OnCollisionBeginMethod, args);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::OnCollisionEnd(Entity entity)
|
||||
{
|
||||
OnCollisionEnd(entity.m_Scene->GetUUID(), entity.GetComponent<IDComponent>().ID);
|
||||
}
|
||||
|
||||
void ScriptEngine::OnCollisionEnd(const UUID& sceneID, const UUID& entityID)
|
||||
{
|
||||
EntityInstance& entityInstance = GetEntityInstanceData(sceneID, entityID).Instance;
|
||||
if (entityInstance.ScriptClass->OnCollisionEndMethod)
|
||||
{
|
||||
float value = 5.0f;
|
||||
void* args[] = { &value };
|
||||
CallMethod(entityInstance.GetInstance(), entityInstance.ScriptClass->OnCollisionEndMethod, args);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::OnScriptComponentDestroyed(const UUID &sceneID, const UUID &entityID)
|
||||
{
|
||||
PM_CORE_ASSERT(s_EntityInstanceMap.find(sceneID) != s_EntityInstanceMap.end());
|
||||
|
||||
@ -123,6 +123,11 @@ namespace Prism
|
||||
static void OnCollision2DEnd(Entity entity);
|
||||
static void OnCollision2DEnd(const UUID &sceneID, const UUID &entityID);
|
||||
|
||||
static void OnCollisionBegin(Entity entity);
|
||||
static void OnCollisionBegin(const UUID& sceneID, const UUID& entityID);
|
||||
static void OnCollisionEnd(Entity entity);
|
||||
static void OnCollisionEnd(const UUID& sceneID, const UUID& entityID);
|
||||
|
||||
static void OnScriptComponentDestroyed(const UUID &sceneID, const UUID &entityID);
|
||||
|
||||
static bool ModuleExists(const std::string& moduleName);
|
||||
|
||||
@ -26,7 +26,7 @@ namespace Prism
|
||||
s_HasComponentFuncs[type] = [](Entity& entity) { return entity.HasComponent<Type>(); };\
|
||||
s_CreateComponentFuncs[type] = [](Entity& entity) { entity.AddComponent<Type>(); };\
|
||||
} else {\
|
||||
PM_CORE_ERROR("No C# component class found for " #Type "!");\
|
||||
PM_CORE_ERROR("No C# component class found for {0}", #Type);\
|
||||
}\
|
||||
}
|
||||
|
||||
@ -40,6 +40,9 @@ namespace Prism
|
||||
Component_RegisterType(SpriteRendererComponent);
|
||||
Component_RegisterType(RigidBody2DComponent);
|
||||
Component_RegisterType(BoxCollider2DComponent);
|
||||
Component_RegisterType(RigidBodyComponent);
|
||||
Component_RegisterType(BoxColliderComponent);
|
||||
Component_RegisterType(SphereColliderComponent);
|
||||
}
|
||||
|
||||
void ScriptEngineRegistry::RegisterAll()
|
||||
@ -50,6 +53,10 @@ namespace Prism
|
||||
|
||||
mono_add_internal_call("Prism.Entity::GetTransform_Native",(const void*)Prism::Script::Prism_Entity_GetTransform);
|
||||
mono_add_internal_call("Prism.Entity::SetTransform_Native",(const void*)Prism::Script::Prism_Entity_SetTransform);
|
||||
mono_add_internal_call("Prism.Entity::GetForwardDirection_Native", Prism::Script::Prism_Entity_GetForwardDirection);
|
||||
mono_add_internal_call("Prism.Entity::GetRightDirection_Native", Prism::Script::Prism_Entity_GetRightDirection);
|
||||
mono_add_internal_call("Prism.Entity::GetUpDirection_Native", Prism::Script::Prism_Entity_GetUpDirection);
|
||||
|
||||
mono_add_internal_call("Prism.Entity::CreateComponent_Native",(const void*)Prism::Script::Prism_Entity_CreateComponent);
|
||||
mono_add_internal_call("Prism.Entity::HasComponent_Native",(const void*)Prism::Script::Prism_Entity_HasComponent);
|
||||
mono_add_internal_call("Prism.Entity::FindEntityByTag_Native", (const void*)Prism::Script::Prism_Entity_FindEntityByTag);
|
||||
@ -67,6 +74,11 @@ namespace Prism
|
||||
mono_add_internal_call("Prism.Texture2D::Destructor_Native", (const void*)Prism::Script::Prism_Texture2D_Destructor);
|
||||
mono_add_internal_call("Prism.Texture2D::SetData_Native", (const void*)Prism::Script::Prism_Texture2D_SetData);
|
||||
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::AddForce_Native", Prism::Script::Prism_RigidBodyComponent_AddForce);
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::AddTorque_Native", Prism::Script::Prism_RigidBodyComponent_AddTorque);
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::GetLinearVelocity_Native", Prism::Script::Prism_RigidBodyComponent_GetLinearVelocity);
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::SetLinearVelocity_Native", Prism::Script::Prism_RigidBodyComponent_SetLinearVelocity);
|
||||
|
||||
mono_add_internal_call("Prism.Material::Destructor_Native", (const void*)Prism::Script::Prism_Material_Destructor);
|
||||
mono_add_internal_call("Prism.Material::SetFloat_Native", (const void*)Prism::Script::Prism_Material_SetFloat);
|
||||
mono_add_internal_call("Prism.Material::SetTexture_Native", (const void*)Prism::Script::Prism_Material_SetTexture);
|
||||
|
||||
@ -14,6 +14,13 @@
|
||||
#include "Prism/Scene/Entity.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/matrix_decompose.hpp>
|
||||
|
||||
#include "PxRigidActor.h"
|
||||
#include "PxRigidDynamic.h"
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
|
||||
namespace Prism {
|
||||
extern std::unordered_map<MonoType*, std::function<bool(Entity&)>> s_HasComponentFuncs;
|
||||
@ -31,13 +38,23 @@ namespace Prism { namespace Script {
|
||||
SpriteRenderer = 4
|
||||
};
|
||||
|
||||
static std::tuple<glm::vec3, glm::quat, glm::vec3> GetTransformDecomposition(const glm::mat4& transform)
|
||||
{
|
||||
glm::vec3 scale, translation, skew;
|
||||
glm::vec4 perspective;
|
||||
glm::quat orientation;
|
||||
glm::decompose(transform, scale, orientation, translation, skew, perspective);
|
||||
|
||||
return { translation, orientation, scale };
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Math ////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
float Prism_Noise_PerlinNoise(float x, float y)
|
||||
float Prism_Noise_PerlinNoise(const float x, const float y)
|
||||
{
|
||||
return Noise::PerlinNoise(x, y);
|
||||
}
|
||||
@ -48,7 +65,7 @@ namespace Prism { namespace Script {
|
||||
// Input ///////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Prism_Input_IsKeyPressed(KeyCode key)
|
||||
bool Prism_Input_IsKeyPressed(const KeyCode key)
|
||||
{
|
||||
return Input::IsKeyPressed(key);
|
||||
}
|
||||
@ -59,7 +76,7 @@ namespace Prism { namespace Script {
|
||||
// Entity //////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void Prism_Entity_GetTransform(uint64_t entityID, glm::mat4* outTransform)
|
||||
void Prism_Entity_GetTransform(const uint64_t entityID, glm::mat4* outTransform)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
@ -71,7 +88,7 @@ namespace Prism { namespace Script {
|
||||
memcpy(outTransform, glm::value_ptr(transformComponent.Transform), sizeof(glm::mat4));
|
||||
}
|
||||
|
||||
void Prism_Entity_SetTransform(uint64_t entityID, glm::mat4* inTransform)
|
||||
void Prism_Entity_SetTransform(const uint64_t entityID, const glm::mat4* inTransform)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
@ -82,8 +99,7 @@ namespace Prism { namespace Script {
|
||||
auto& transformComponent = entity.GetComponent<TransformComponent>();
|
||||
memcpy(glm::value_ptr(transformComponent.Transform), inTransform, sizeof(glm::mat4));
|
||||
}
|
||||
|
||||
void Prism_Entity_CreateComponent(uint64_t entityID, void* type)
|
||||
void Prism_Entity_GetForwardDirection(const uint64_t entityID, glm::vec3* outForward)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
@ -91,11 +107,56 @@ namespace Prism { namespace Script {
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
MonoType* monoType = mono_reflection_type_get_type((MonoReflectionType*)type);
|
||||
const auto& transformComponent = entity.GetComponent<TransformComponent>();
|
||||
|
||||
auto [position, rotation, scale] = GetTransformDecomposition(transformComponent.Transform);
|
||||
*outForward = glm::rotate(glm::inverse(glm::normalize(rotation)), glm::vec3(0, 0, -1));
|
||||
}
|
||||
|
||||
void Prism_Entity_GetRightDirection(const uint64_t entityID, glm::vec3* outRight)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
const auto& transformComponent = entity.GetComponent<TransformComponent>();
|
||||
|
||||
auto [position, rotation, scale] = GetTransformDecomposition(transformComponent.Transform);
|
||||
*outRight = glm::rotate(glm::inverse(glm::normalize(rotation)), glm::vec3(1, 0, 0));
|
||||
}
|
||||
|
||||
void Prism_Entity_GetUpDirection(const uint64_t entityID, glm::vec3* outUp)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
const auto& transformComponent = entity.GetComponent<TransformComponent>();
|
||||
|
||||
auto [position, rotation, scale] = GetTransformDecomposition(transformComponent.Transform);
|
||||
*outUp = glm::rotate(glm::inverse(glm::normalize(rotation)), glm::vec3(0, 1, 0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Prism_Entity_CreateComponent(const uint64_t entityID, void* type)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
MonoType* monoType = mono_reflection_type_get_type(static_cast<MonoReflectionType*>(type));
|
||||
s_CreateComponentFuncs[monoType](entity);
|
||||
}
|
||||
|
||||
bool Prism_Entity_HasComponent(uint64_t entityID, void* type)
|
||||
bool Prism_Entity_HasComponent(const uint64_t entityID, void* type)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
@ -103,8 +164,8 @@ namespace Prism { namespace Script {
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
MonoType* monoType = mono_reflection_type_get_type((MonoReflectionType*)type);
|
||||
bool result = s_HasComponentFuncs[monoType](entity);
|
||||
MonoType* monoType = mono_reflection_type_get_type(static_cast<MonoReflectionType*>(type));
|
||||
const bool result = s_HasComponentFuncs[monoType](entity);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -120,7 +181,7 @@ namespace Prism { namespace Script {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* Prism_MeshComponent_GetMesh(uint64_t entityID)
|
||||
void* Prism_MeshComponent_GetMesh(const uint64_t entityID)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
@ -132,7 +193,7 @@ namespace Prism { namespace Script {
|
||||
return new Ref<Mesh>(meshComponent.Mesh);
|
||||
}
|
||||
|
||||
void Prism_MeshComponent_SetMesh(uint64_t entityID, Ref<Mesh>* inMesh)
|
||||
void Prism_MeshComponent_SetMesh(const uint64_t entityID, const Ref<Mesh>* inMesh)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
@ -144,70 +205,7 @@ namespace Prism { namespace Script {
|
||||
meshComponent.Mesh = inMesh ? *inMesh : nullptr;
|
||||
}
|
||||
|
||||
void Prism_RigidBody2DComponent_ApplyLinearImpulse(uint64_t entityID, glm::vec2 *impulse, glm::vec2 *offset, bool wake)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBody2DComponent>());
|
||||
auto& component = entity.GetComponent<RigidBody2DComponent>();
|
||||
|
||||
b2BodyId body = component.RuntimeBodyID;
|
||||
|
||||
b2Body_ApplyLinearImpulse(body, *(const b2Vec2*)impulse, b2Body_GetWorldCenterOfMass(body) + *(const b2Vec2*)offset, wake);
|
||||
}
|
||||
|
||||
void Prism_RigidBody2DComponent_GetLinearVelocity(uint64_t entityID, glm::vec2 *outVelocity)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBody2DComponent>());
|
||||
auto& component = entity.GetComponent<RigidBody2DComponent>();
|
||||
|
||||
b2Vec2 velocity = b2Body_GetLinearVelocity(component.RuntimeBodyID);
|
||||
|
||||
PM_CORE_ASSERT(outVelocity);
|
||||
*outVelocity = { velocity.x, velocity.y };
|
||||
}
|
||||
|
||||
void Prism_RigidBody2DComponent_SetLinearVelocity(uint64_t entityID, glm::vec2 *velocity)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBody2DComponent>());
|
||||
auto& component = entity.GetComponent<RigidBody2DComponent>();
|
||||
|
||||
PM_CORE_ASSERT(velocity);
|
||||
b2Body_SetLinearVelocity(component.RuntimeBodyID, {velocity->x, velocity->y});
|
||||
}
|
||||
|
||||
void Hazel_RigidBody2DComponent_GetLinearVelocity(uint64_t entityID, glm::vec2* outVelocity)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBody2DComponent>());
|
||||
auto& component = entity.GetComponent<RigidBody2DComponent>();
|
||||
const auto& velocity = b2Body_GetLinearVelocity(component.RuntimeBodyID);
|
||||
PM_CORE_ASSERT(outVelocity);
|
||||
*outVelocity = { velocity.x, velocity.y };
|
||||
}
|
||||
|
||||
void Hazel_RigidBody2DComponent_SetLinearVelocity(uint64_t entityID, glm::vec2* velocity)
|
||||
void Prism_RigidBody2DComponent_ApplyLinearImpulse(const uint64_t entityID, const glm::vec2 *impulse, const glm::vec2 *offset, const bool wake)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
@ -217,10 +215,133 @@ namespace Prism { namespace Script {
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBody2DComponent>());
|
||||
const auto& component = entity.GetComponent<RigidBody2DComponent>();
|
||||
|
||||
const b2BodyId body = component.RuntimeBodyID;
|
||||
|
||||
b2Body_ApplyLinearImpulse(body, *(const b2Vec2*)impulse, b2Body_GetWorldCenterOfMass(body) + *(const b2Vec2*)offset, wake);
|
||||
}
|
||||
|
||||
void Prism_RigidBody2DComponent_GetLinearVelocity(const uint64_t entityID, glm::vec2 *outVelocity)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBody2DComponent>());
|
||||
const auto& component = entity.GetComponent<RigidBody2DComponent>();
|
||||
|
||||
b2Vec2 velocity = b2Body_GetLinearVelocity(component.RuntimeBodyID);
|
||||
|
||||
PM_CORE_ASSERT(outVelocity);
|
||||
*outVelocity = { velocity.x, velocity.y };
|
||||
}
|
||||
|
||||
void Prism_RigidBody2DComponent_SetLinearVelocity(const uint64_t entityID, const glm::vec2 *velocity)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBody2DComponent>());
|
||||
const auto& component = entity.GetComponent<RigidBody2DComponent>();
|
||||
|
||||
PM_CORE_ASSERT(velocity);
|
||||
b2Body_SetLinearVelocity(component.RuntimeBodyID, {velocity->x, velocity->y});
|
||||
}
|
||||
|
||||
void Prism_RigidBodyComponent_AddForce(const uint64_t entityID, glm::vec3* force, ForceMode forceMode)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
||||
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
||||
physx::PxRigidActor* actor = (physx::PxRigidActor*)component.RuntimeActor;
|
||||
physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||
|
||||
// We don't want to assert since scripts might want to be able to switch
|
||||
// between a static and dynamic actor at runtime
|
||||
if (!dynamicActor)
|
||||
return;
|
||||
|
||||
PM_CORE_ASSERT(force);
|
||||
dynamicActor->addForce({ force->x, force->y, force->z }, (physx::PxForceMode::Enum)forceMode);
|
||||
}
|
||||
|
||||
void Prism_RigidBodyComponent_AddTorque(const uint64_t entityID, glm::vec3* torque, ForceMode forceMode)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
||||
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
||||
physx::PxRigidActor* actor = (physx::PxRigidActor*)component.RuntimeActor;
|
||||
physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||
|
||||
// We don't want to assert since scripts might want to be able to switch
|
||||
// between a static and dynamic actor at runtime
|
||||
if (!dynamicActor)
|
||||
return;
|
||||
|
||||
PM_CORE_ASSERT(torque);
|
||||
dynamicActor->addTorque({ torque->x, torque->y, torque->z }, (physx::PxForceMode::Enum)forceMode);
|
||||
}
|
||||
|
||||
void Prism_RigidBodyComponent_GetLinearVelocity(const uint64_t entityID, glm::vec3* outVelocity)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
||||
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
||||
physx::PxRigidActor* actor = (physx::PxRigidActor*)component.RuntimeActor;
|
||||
const physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||
|
||||
// We don't want to assert since scripts might want to be able to switch
|
||||
// between a static and dynamic actor at runtime
|
||||
if (!dynamicActor)
|
||||
return;
|
||||
|
||||
PM_CORE_ASSERT(outVelocity);
|
||||
physx::PxVec3 velocity = dynamicActor->getLinearVelocity();
|
||||
*outVelocity = { velocity.x, velocity.y, velocity.z };
|
||||
}
|
||||
|
||||
void Prism_RigidBodyComponent_SetLinearVelocity(const uint64_t entityID, glm::vec3* velocity)
|
||||
{
|
||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||
PM_CORE_ASSERT(scene, "No active scene!");
|
||||
const auto& entityMap = scene->GetEntityMap();
|
||||
PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!");
|
||||
|
||||
Entity entity = entityMap.at(entityID);
|
||||
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
||||
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
||||
physx::PxRigidActor* actor = (physx::PxRigidActor*)component.RuntimeActor;
|
||||
physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||
|
||||
// We don't want to assert since scripts might want to be able to switch
|
||||
// between a static and dynamic actor at runtime
|
||||
if (!dynamicActor)
|
||||
return;
|
||||
|
||||
PM_CORE_ASSERT(velocity);
|
||||
dynamicActor->setLinearVelocity({ velocity->x, velocity->y, velocity->z });
|
||||
}
|
||||
|
||||
|
||||
Ref<Mesh>* Prism_Mesh_Constructor(MonoString* filepath)
|
||||
{
|
||||
@ -239,7 +360,7 @@ namespace Prism { namespace Script {
|
||||
return new Ref<Material>(mesh->GetMaterial());
|
||||
}
|
||||
|
||||
Ref<MaterialInstance>* Prism_Mesh_GetMaterialByIndex(Ref<Mesh>* inMesh, int index)
|
||||
Ref<MaterialInstance>* Prism_Mesh_GetMaterialByIndex(Ref<Mesh>* inMesh, const int index)
|
||||
{
|
||||
Ref<Mesh>& mesh = *(Ref<Mesh>*)inMesh;
|
||||
const auto& materials = mesh->GetMaterials();
|
||||
@ -255,13 +376,13 @@ namespace Prism { namespace Script {
|
||||
return (int)materials.size();
|
||||
}
|
||||
|
||||
void* Prism_Texture2D_Constructor(uint32_t width, uint32_t height)
|
||||
void* Prism_Texture2D_Constructor(const uint32_t width, const uint32_t height)
|
||||
{
|
||||
auto result = Texture2D::Create(TextureFormat::RGBA, width, height);
|
||||
const auto result = Texture2D::Create(TextureFormat::RGBA, width, height);
|
||||
return new Ref<Texture2D>(result);
|
||||
}
|
||||
|
||||
void Prism_Texture2D_Destructor(Ref<Texture2D>* _this)
|
||||
void Prism_Texture2D_Destructor(const Ref<Texture2D>* _this)
|
||||
{
|
||||
delete _this;
|
||||
}
|
||||
@ -270,67 +391,67 @@ namespace Prism { namespace Script {
|
||||
{
|
||||
Ref<Texture2D>& instance = *_this;
|
||||
|
||||
uint32_t dataSize = count * sizeof(glm::vec4) / 4;
|
||||
const uint32_t dataSize = count * sizeof(glm::vec4) / 4;
|
||||
|
||||
instance->Lock();
|
||||
Buffer buffer = instance->GetWriteableBuffer();
|
||||
const Buffer buffer = instance->GetWriteableBuffer();
|
||||
PM_CORE_ASSERT(dataSize <= buffer.Size);
|
||||
// Convert RGBA32F color to RGBA8
|
||||
uint8_t* pixels = (uint8_t*)buffer.Data;
|
||||
auto pixels = static_cast<uint8_t*>(buffer.Data);
|
||||
uint32_t index = 0;
|
||||
for (uint32_t i = 0; i < instance->GetWidth() * instance->GetHeight(); i++)
|
||||
{
|
||||
glm::vec4& value = mono_array_get(inData, glm::vec4, i);
|
||||
*pixels++ = (uint32_t)(value.x * 255.0f);
|
||||
*pixels++ = (uint32_t)(value.y * 255.0f);
|
||||
*pixels++ = (uint32_t)(value.z * 255.0f);
|
||||
*pixels++ = (uint32_t)(value.w * 255.0f);
|
||||
const glm::vec4& value = mono_array_get(inData, glm::vec4, i);
|
||||
*pixels++ = static_cast<uint32_t>(value.x * 255.0f);
|
||||
*pixels++ = static_cast<uint32_t>(value.y * 255.0f);
|
||||
*pixels++ = static_cast<uint32_t>(value.z * 255.0f);
|
||||
*pixels++ = static_cast<uint32_t>(value.w * 255.0f);
|
||||
}
|
||||
|
||||
instance->Unlock();
|
||||
}
|
||||
|
||||
void Prism_Material_Destructor(Ref<Material>* _this)
|
||||
void Prism_Material_Destructor(const Ref<Material>* _this)
|
||||
{
|
||||
delete _this;
|
||||
}
|
||||
|
||||
void Prism_Material_SetFloat(Ref<Material>* _this, MonoString* uniform, float value)
|
||||
void Prism_Material_SetFloat(Ref<Material>* _this, MonoString* uniform, const float value)
|
||||
{
|
||||
Ref<Material>& instance = *(Ref<Material>*)_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), value);
|
||||
}
|
||||
|
||||
void Prism_Material_SetTexture(Ref<Material>* _this, MonoString* uniform, Ref<Texture2D>* texture)
|
||||
void Prism_Material_SetTexture(Ref<Material>* _this, MonoString* uniform, const Ref<Texture2D>* texture)
|
||||
{
|
||||
Ref<Material>& instance = *(Ref<Material>*)_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), *texture);
|
||||
}
|
||||
|
||||
void Prism_MaterialInstance_Destructor(Ref<MaterialInstance>* _this)
|
||||
void Prism_MaterialInstance_Destructor(const Ref<MaterialInstance>* _this)
|
||||
{
|
||||
delete _this;
|
||||
}
|
||||
|
||||
void Prism_MaterialInstance_SetFloat(Ref<MaterialInstance>* _this, MonoString* uniform, float value)
|
||||
void Prism_MaterialInstance_SetFloat(Ref<MaterialInstance>* _this, MonoString* uniform, const float value)
|
||||
{
|
||||
Ref<MaterialInstance>& instance = *(Ref<MaterialInstance>*)_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), value);
|
||||
}
|
||||
|
||||
void Prism_MaterialInstance_SetVector3(Ref<MaterialInstance>* _this, MonoString* uniform, glm::vec3* value)
|
||||
void Prism_MaterialInstance_SetVector3(Ref<MaterialInstance>* _this, MonoString* uniform, const glm::vec3* value)
|
||||
{
|
||||
Ref<MaterialInstance>& instance = *(Ref<MaterialInstance>*)_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), *value);
|
||||
}
|
||||
|
||||
void Prism_MaterialInstance_SetVector4(Ref<MaterialInstance> *_this, MonoString *uniform, glm::vec4 *value)
|
||||
void Prism_MaterialInstance_SetVector4(Ref<MaterialInstance> *_this, MonoString *uniform, const glm::vec4 *value)
|
||||
{
|
||||
Ref<MaterialInstance>& instance = *(Ref<MaterialInstance>*)_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), *value);
|
||||
}
|
||||
|
||||
void Prism_MaterialInstance_SetTexture(Ref<MaterialInstance>* _this, MonoString* uniform, Ref<Texture2D>* texture)
|
||||
void Prism_MaterialInstance_SetTexture(Ref<MaterialInstance>* _this, MonoString* uniform, const Ref<Texture2D>* texture)
|
||||
{
|
||||
Ref<MaterialInstance>& instance = *(Ref<MaterialInstance>*)_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), *texture);
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#define SCRIPTWARPPERS_H
|
||||
#include "Prism/Core/KeyCodes.h"
|
||||
#include "Prism/Core/Ref.h"
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
#include "Prism/Renderer/Material.h"
|
||||
#include "Prism/Renderer/Mesh.h"
|
||||
#include "Prism/Renderer/Texture.h"
|
||||
@ -25,35 +26,44 @@ namespace Prism { namespace Script {
|
||||
|
||||
// Entity
|
||||
void Prism_Entity_GetTransform(uint64_t entityID, glm::mat4* outTransform);
|
||||
void Prism_Entity_SetTransform(uint64_t entityID, glm::mat4* inTransform);
|
||||
void Prism_Entity_SetTransform(uint64_t entityID, const glm::mat4* inTransform);
|
||||
void Prism_Entity_GetForwardDirection(uint64_t entityID, glm::vec3* outForward);
|
||||
void Prism_Entity_GetRightDirection(uint64_t entityID, glm::vec3* outRight);
|
||||
void Prism_Entity_GetUpDirection(uint64_t entityID, glm::vec3* outUp);
|
||||
|
||||
void Prism_Entity_CreateComponent(uint64_t entityID, void* type);
|
||||
bool Prism_Entity_HasComponent(uint64_t entityID, void* type);
|
||||
uint64_t Prism_Entity_FindEntityByTag(MonoString* tag);
|
||||
|
||||
void* Prism_MeshComponent_GetMesh(uint64_t entityID);
|
||||
void Prism_MeshComponent_SetMesh(uint64_t entityID, Ref<Mesh>* inMesh);
|
||||
void Prism_MeshComponent_SetMesh(uint64_t entityID, const Ref<Mesh>* inMesh);
|
||||
|
||||
// 2D Physic
|
||||
void Prism_RigidBody2DComponent_ApplyLinearImpulse(uint64_t entityID, glm::vec2* impulse, glm::vec2* offset, bool wake);
|
||||
void Prism_RigidBody2DComponent_ApplyLinearImpulse(uint64_t entityID, const glm::vec2* impulse, const glm::vec2* offset, bool wake);
|
||||
void Prism_RigidBody2DComponent_GetLinearVelocity(uint64_t entityID, glm::vec2* outVelocity);
|
||||
void Prism_RigidBody2DComponent_SetLinearVelocity(uint64_t entityID, glm::vec2* velocity);
|
||||
void Prism_RigidBody2DComponent_SetLinearVelocity(uint64_t entityID, const glm::vec2* velocity);
|
||||
|
||||
void Prism_RigidBodyComponent_AddForce(uint64_t entityID, glm::vec3* force, ForceMode forceMode);
|
||||
void Prism_RigidBodyComponent_AddTorque(uint64_t entityID, glm::vec3* torque, ForceMode forceMode);
|
||||
void Prism_RigidBodyComponent_GetLinearVelocity(uint64_t entityID, glm::vec3* outVelocity);
|
||||
void Prism_RigidBodyComponent_SetLinearVelocity(uint64_t entityID, glm::vec3* velocity);
|
||||
|
||||
// Renderer
|
||||
// Texture2D
|
||||
void* Prism_Texture2D_Constructor(uint32_t width, uint32_t height);
|
||||
void Prism_Texture2D_Destructor(Ref<Texture2D>* _this);
|
||||
void Prism_Texture2D_Destructor(const Ref<Texture2D>* _this);
|
||||
void Prism_Texture2D_SetData(Ref<Texture2D>* _this, MonoArray* inData, int32_t count);
|
||||
|
||||
// Material
|
||||
void Prism_Material_Destructor(Ref<Material>* _this);
|
||||
void Prism_Material_Destructor(const Ref<Material>* _this);
|
||||
void Prism_Material_SetFloat(Ref<Material>* _this, MonoString* uniform, float value);
|
||||
void Prism_Material_SetTexture(Ref<Material>* _this, MonoString* uniform, Ref<Texture2D>* texture);
|
||||
void Prism_Material_SetTexture(Ref<Material>* _this, MonoString* uniform, const Ref<Texture2D>* texture);
|
||||
|
||||
void Prism_MaterialInstance_Destructor(Ref<MaterialInstance>* _this);
|
||||
void Prism_MaterialInstance_Destructor(const Ref<MaterialInstance>* _this);
|
||||
void Prism_MaterialInstance_SetFloat(Ref<MaterialInstance>* _this, MonoString* uniform, float value);
|
||||
void Prism_MaterialInstance_SetVector3(Ref<MaterialInstance>* _this, MonoString* uniform, glm::vec3* value);
|
||||
void Prism_MaterialInstance_SetVector4(Ref<MaterialInstance>* _this, MonoString* uniform, glm::vec4* value);
|
||||
void Prism_MaterialInstance_SetTexture(Ref<MaterialInstance>* _this, MonoString* uniform, Ref<Texture2D>* texture);
|
||||
void Prism_MaterialInstance_SetVector3(Ref<MaterialInstance>* _this, MonoString* uniform, const glm::vec3* value);
|
||||
void Prism_MaterialInstance_SetVector4(Ref<MaterialInstance>* _this, MonoString* uniform, const glm::vec4* value);
|
||||
void Prism_MaterialInstance_SetTexture(Ref<MaterialInstance>* _this, MonoString* uniform, const Ref<Texture2D>* texture);
|
||||
|
||||
// Mesh
|
||||
Ref<Mesh>* Prism_Mesh_Constructor(MonoString* filepath);
|
||||
|
||||
1
Prism/vendor/PhysX
vendored
Submodule
1
Prism/vendor/PhysX
vendored
Submodule
Submodule Prism/vendor/PhysX added at 09ff24f327
Reference in New Issue
Block a user