add overlapBox/Sphere/Capsule function, fixed OnWake/OnSleep not work
This commit is contained in:
@ -9,6 +9,7 @@
|
||||
|
||||
#include "glm/gtx/matrix_decompose.hpp"
|
||||
#include "Prism/Core/Input.h"
|
||||
#include "Prism/Editor/PhysicsSettingsWindow.h"
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
#include "Prism/Renderer/Renderer2D.h"
|
||||
#include "Prism/Script/ScriptEngine.h"
|
||||
@ -192,7 +193,7 @@ namespace Prism
|
||||
{
|
||||
case SceneState::Edit:
|
||||
{
|
||||
// if (m_ViewportPanelFocused)
|
||||
if (m_ViewportPanelHovered || m_ViewportPanelFocused)
|
||||
m_EditorCamera.OnUpdate(deltaTime);
|
||||
|
||||
m_EditorScene->OnRenderEditor(deltaTime, m_EditorCamera);
|
||||
@ -361,6 +362,13 @@ namespace Prism
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Edit"))
|
||||
{
|
||||
ImGui::MenuItem("Physics Settings", nullptr, &m_ShowPhysicsSettings);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Tools"))
|
||||
{
|
||||
// PhysX Debugger
|
||||
@ -380,6 +388,7 @@ namespace Prism
|
||||
}
|
||||
|
||||
m_SceneHierarchyPanel->OnImGuiRender();
|
||||
PhysicsSettingsWindow::OnImGuiRender(&m_ShowPhysicsSettings);
|
||||
|
||||
ImGui::Begin("Materials");
|
||||
|
||||
@ -682,9 +691,13 @@ namespace Prism
|
||||
{
|
||||
if (ImGui::TreeNode(shader->GetName().c_str()))
|
||||
{
|
||||
std::string buttonName = "Reload##" + shader->GetName();
|
||||
if (ImGui::Button(buttonName.c_str()))
|
||||
|
||||
const std::string buttonName = shader->GetName();
|
||||
if (ImGui::Button(("Reload##" + buttonName).c_str()))
|
||||
{
|
||||
PM_CLIENT_INFO("Reloading Shader: {0}", buttonName);
|
||||
shader->Reload();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
@ -735,7 +748,7 @@ namespace Prism
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
ImGui::Begin("Viewport");
|
||||
|
||||
m_ViewportPanelMouseOver = ImGui::IsWindowHovered();
|
||||
m_ViewportPanelHovered = ImGui::IsWindowHovered();
|
||||
m_ViewportPanelFocused = ImGui::IsWindowFocused();
|
||||
|
||||
auto viewportOffset = ImGui::GetCursorPos(); // includes tab bar
|
||||
@ -809,7 +822,7 @@ namespace Prism
|
||||
{
|
||||
if (m_SceneState == SceneState::Edit)
|
||||
{
|
||||
if (m_ViewportPanelMouseOver)
|
||||
if (m_ViewportPanelHovered)
|
||||
m_EditorCamera.OnEvent(e);
|
||||
|
||||
m_EditorScene->OnEvent(e);
|
||||
@ -856,6 +869,9 @@ namespace Prism
|
||||
}
|
||||
|
||||
if (Input::IsKeyPressed(KeyCode::LEFT_CONTROL))
|
||||
{
|
||||
const bool IsShiftPressed = Input::IsKeyPressed(KeyCode::LEFT_SHIFT);
|
||||
if (!IsShiftPressed)
|
||||
{
|
||||
switch (e.GetKeyCode())
|
||||
{
|
||||
@ -874,7 +890,7 @@ namespace Prism
|
||||
case KeyCode::D:
|
||||
if (m_SelectionContext.size())
|
||||
{
|
||||
Entity selectedEntity = m_SelectionContext[0].Entity;
|
||||
const Entity selectedEntity = m_SelectionContext[0].Entity;
|
||||
m_EditorScene->DuplicateEntity(selectedEntity);
|
||||
}
|
||||
break;
|
||||
@ -883,16 +899,20 @@ namespace Prism
|
||||
SceneRenderer::GetOptions().ShowGrid = !SceneRenderer::GetOptions().ShowGrid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Input::IsKeyPressed(PM_KEY_LEFT_SHIFT))
|
||||
{
|
||||
if (IsShiftPressed) {
|
||||
switch (e.GetKeyCode())
|
||||
{
|
||||
case KeyCode::S:
|
||||
SaveSceneAs();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: ALT TAB
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -902,7 +922,7 @@ namespace Prism
|
||||
{
|
||||
auto [mx, my] = Input::GetMousePosition();
|
||||
|
||||
if (e.GetMouseButton() == PM_MOUSE_BUTTON_LEFT && !Input::IsKeyPressed(KeyCode::LEFT_ALT) && !ImGuizmo::IsOver() && m_SceneState != SceneState::Play)
|
||||
if (m_ViewportPanelHovered && e.GetMouseButton() == PM_MOUSE_BUTTON_LEFT && !Input::IsKeyPressed(KeyCode::LEFT_ALT) && !ImGuizmo::IsOver() && m_SceneState != SceneState::Play)
|
||||
{
|
||||
auto [mouseX, mouseY] = GetMouseViewportSpace();
|
||||
if (mouseX > -1.0f && mouseX < 1.0f && mouseY > -1.0f && mouseY < 1.0f)
|
||||
@ -912,9 +932,9 @@ namespace Prism
|
||||
m_SelectionContext.clear();
|
||||
m_EditorScene->SetSelectedEntity({});
|
||||
const auto meshEntities = m_EditorScene->GetAllEntitiesWith<MeshComponent>();
|
||||
for (auto e : meshEntities)
|
||||
for (const auto aEntity : meshEntities)
|
||||
{
|
||||
Entity entity = { e, m_EditorScene.Raw() };
|
||||
Entity entity = { aEntity, m_EditorScene.Raw() };
|
||||
auto mesh = entity.GetComponent<MeshComponent>().Mesh;
|
||||
|
||||
if (!mesh)
|
||||
@ -970,9 +990,7 @@ namespace Prism
|
||||
SelectedSubmesh selection;
|
||||
if (entity.HasComponent<MeshComponent>())
|
||||
{
|
||||
auto& meshComp = entity.GetComponent<MeshComponent>();
|
||||
|
||||
if (meshComp.Mesh)
|
||||
if (auto& meshComp = entity.GetComponent<MeshComponent>(); meshComp.Mesh)
|
||||
{
|
||||
selection.Mesh = &meshComp.Mesh->GetSubmeshes()[0];
|
||||
}
|
||||
@ -1066,6 +1084,7 @@ namespace Prism
|
||||
|
||||
void EditorLayer::SaveScene()
|
||||
{
|
||||
PM_CLIENT_INFO("Saving scene to: {0}", m_SceneFilePath);
|
||||
SceneSerializer serializer(m_EditorScene);
|
||||
serializer.Serialize(m_SceneFilePath);
|
||||
}
|
||||
@ -1076,6 +1095,7 @@ namespace Prism
|
||||
std::string filepath = app.SaveFile("Prism Scene (*.hsc)\0*.hsc\0");
|
||||
if (!filepath.empty())
|
||||
{
|
||||
PM_CLIENT_INFO("Saving scene to: {0}", m_SceneFilePath);
|
||||
SceneSerializer serializer(m_EditorScene);
|
||||
serializer.Serialize(filepath);
|
||||
|
||||
@ -1112,6 +1132,8 @@ namespace Prism
|
||||
m_SelectionContext.clear();
|
||||
ScriptEngine::SetSceneContext(m_EditorScene);
|
||||
m_SceneHierarchyPanel->SetContext(m_EditorScene);
|
||||
|
||||
Input::SetCursorMode(CursorMode::Normal);
|
||||
}
|
||||
|
||||
float EditorLayer::GetSnapValue()
|
||||
|
||||
@ -143,8 +143,9 @@ namespace Prism
|
||||
};
|
||||
SceneType m_SceneType;
|
||||
|
||||
bool m_ViewportPanelMouseOver = false;
|
||||
bool m_ViewportPanelHovered = false;
|
||||
bool m_ViewportPanelFocused = false;
|
||||
bool m_ShowPhysicsSettings = false;
|
||||
|
||||
enum class SceneState
|
||||
{
|
||||
|
||||
@ -2,15 +2,15 @@ Scene: Scene Name
|
||||
Environment:
|
||||
AssetPath: assets/env/pink_sunrise_4k.hdr
|
||||
Light:
|
||||
Direction: [-0.787, -0.73299998, 1]
|
||||
Direction: [-0.787, -0.733, 1]
|
||||
Radiance: [1, 1, 1]
|
||||
Multiplier: 0.514999986
|
||||
Multiplier: 0.515
|
||||
Entities:
|
||||
- Entity: 3247025703490125974
|
||||
TagComponent:
|
||||
Tag: Player
|
||||
TransformComponent:
|
||||
Position: [2.80803752, 1.5, 0]
|
||||
Position: [2.8080375, 1.5, 0]
|
||||
Rotation: [1, 0, 0, 0]
|
||||
Scale: [2, 2, 2]
|
||||
ScriptComponent:
|
||||
@ -25,23 +25,30 @@ Entities:
|
||||
- Name: JumpForce
|
||||
Type: 1
|
||||
Data: 50
|
||||
- Name: MouseSensitivity
|
||||
Type: 1
|
||||
Data: 10
|
||||
- Name: Distance
|
||||
Type: 1
|
||||
Data: 0
|
||||
MeshComponent:
|
||||
AssetPath: assets/meshes/Capsule.fbx
|
||||
RigidBodyComponent:
|
||||
BodyType: 1
|
||||
Mass: 1
|
||||
IsKinematic: false
|
||||
Layer: 1
|
||||
Constraints:
|
||||
LockPositionX: false
|
||||
LockPositionY: false
|
||||
LockPositionZ: false
|
||||
LockRotationX: true
|
||||
LockRotationY: false
|
||||
LockRotationY: true
|
||||
LockRotationZ: true
|
||||
PhysicsMaterialComponent:
|
||||
StaticFriction: 0.100000001
|
||||
DynamicFriction: 0.100000001
|
||||
Bounciness: 0.100000001
|
||||
StaticFriction: 0.1
|
||||
DynamicFriction: 0.1
|
||||
Bounciness: 0.1
|
||||
MeshColliderComponent:
|
||||
AssetPath: assets/meshes/Capsule.fbx
|
||||
IsTrigger: false
|
||||
@ -49,15 +56,16 @@ Entities:
|
||||
TagComponent:
|
||||
Tag: Mesh Collider
|
||||
TransformComponent:
|
||||
Position: [-2.60455179, 1, -0.00171399117]
|
||||
Position: [-2.6045518, 1, -0.0017139912]
|
||||
Rotation: [1, 0, 0, 0]
|
||||
Scale: [1, 1, 1]
|
||||
MeshComponent:
|
||||
AssetPath: assets/meshes/Sphere1m.fbx
|
||||
RigidBodyComponent:
|
||||
BodyType: 1
|
||||
Mass: 0.100000001
|
||||
Mass: 0.1
|
||||
IsKinematic: false
|
||||
Layer: 1
|
||||
Constraints:
|
||||
LockPositionX: false
|
||||
LockPositionY: false
|
||||
@ -68,7 +76,7 @@ Entities:
|
||||
PhysicsMaterialComponent:
|
||||
StaticFriction: 1
|
||||
DynamicFriction: 1
|
||||
Bounciness: 0.100000001
|
||||
Bounciness: 0.1
|
||||
MeshColliderComponent:
|
||||
AssetPath: assets/meshes/Sphere1m.fbx
|
||||
IsTrigger: false
|
||||
@ -85,6 +93,7 @@ Entities:
|
||||
BodyType: 1
|
||||
Mass: 0.5
|
||||
IsKinematic: false
|
||||
Layer: 0
|
||||
Constraints:
|
||||
LockPositionX: false
|
||||
LockPositionY: false
|
||||
@ -104,7 +113,7 @@ Entities:
|
||||
TagComponent:
|
||||
Tag: Sphere
|
||||
TransformComponent:
|
||||
Position: [-3.98769951, 1, -1.96695328e-06]
|
||||
Position: [-3.9876995, 1, -1.9669533e-06]
|
||||
Rotation: [1, 0, 0, 0]
|
||||
Scale: [1, 1, 1]
|
||||
MeshComponent:
|
||||
@ -113,17 +122,18 @@ Entities:
|
||||
BodyType: 1
|
||||
Mass: 1
|
||||
IsKinematic: false
|
||||
Layer: 1
|
||||
Constraints:
|
||||
LockPositionX: false
|
||||
LockPositionY: false
|
||||
LockPositionZ: false
|
||||
LockRotationX: true
|
||||
LockRotationY: true
|
||||
LockRotationZ: true
|
||||
LockRotationX: false
|
||||
LockRotationY: false
|
||||
LockRotationZ: false
|
||||
PhysicsMaterialComponent:
|
||||
StaticFriction: 0.100000001
|
||||
DynamicFriction: 0.100000001
|
||||
Bounciness: 0.100000001
|
||||
StaticFriction: 0.1
|
||||
DynamicFriction: 0.1
|
||||
Bounciness: 0.1
|
||||
SphereColliderComponent:
|
||||
Radius: 0.5
|
||||
IsTrigger: false
|
||||
@ -131,7 +141,7 @@ Entities:
|
||||
TagComponent:
|
||||
Tag: Camera
|
||||
TransformComponent:
|
||||
Position: [2.80800009, 2.25, 0]
|
||||
Position: [2.808, 2.25, 0]
|
||||
Rotation: [1, 0, 0, 0]
|
||||
Scale: [1, 1, 1]
|
||||
CameraComponent:
|
||||
@ -150,6 +160,7 @@ Entities:
|
||||
BodyType: 0
|
||||
Mass: 1
|
||||
IsKinematic: false
|
||||
Layer: 0
|
||||
Constraints:
|
||||
LockPositionX: false
|
||||
LockPositionY: false
|
||||
@ -165,3 +176,7 @@ Entities:
|
||||
Offset: [0, 0, 0]
|
||||
Size: [1, 1, 1]
|
||||
IsTrigger: false
|
||||
PhysicsLayers:
|
||||
- Name: Default
|
||||
CollidesWith:
|
||||
[]
|
||||
@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using Prism;
|
||||
|
||||
namespace FPSExample
|
||||
@ -9,7 +8,7 @@ namespace FPSExample
|
||||
public float RunSpeed = 20.0F;
|
||||
public float JumpForce = 50.0F;
|
||||
public float MouseSensitivity = 10.0F;
|
||||
public Vec3 Forward = new Vec3(0.0f, 0.0f, 1.0f);
|
||||
public float Distance = 5.0F;
|
||||
|
||||
private bool m_Colliding = false;
|
||||
private float m_CurrentSpeed;
|
||||
@ -44,12 +43,11 @@ namespace FPSExample
|
||||
|
||||
void OnUpdate(float ts)
|
||||
{
|
||||
Forward = m_Transform.Forward;
|
||||
|
||||
if (Input.IsKeyPressed(KeyCode.Escape) && Input.GetCursorMode() == Input.CursorMode.Locked)
|
||||
{
|
||||
Input.SetCursorMode(Input.CursorMode.Normal);
|
||||
}
|
||||
|
||||
if(Input.IsMouseButtonPressed(Input.MouseButton.Left) && Input.GetCursorMode() == Input.CursorMode.Normal)
|
||||
Input.SetCursorMode(Input.CursorMode.Locked);
|
||||
|
||||
m_CurrentSpeed = Input.IsKeyPressed(KeyCode.LeftControl) ? RunSpeed : WalkingSpeed;
|
||||
|
||||
@ -78,8 +76,32 @@ namespace FPSExample
|
||||
m_LastMousePosition = currentMousePosition;
|
||||
}
|
||||
|
||||
Collider[] colliders = new Collider[10];
|
||||
|
||||
private void UpdateMovement()
|
||||
{
|
||||
RaycastHit hitInfo;
|
||||
if (Input.IsKeyPressed(KeyCode.H) &&
|
||||
Physics.Raycast(m_CameraTransform.Transform.Translation + (m_CameraTransform.Forward * 5.0f),
|
||||
m_CameraTransform.Forward, 20.0f, out hitInfo))
|
||||
{
|
||||
FindEntityByID(hitInfo.EntityID).GetComponent<MeshComponent>().Mesh.GetMaterial(0).Set("u_AlbedoColor", new Vec3(1.0f ,0.0f, 0.0f));
|
||||
}
|
||||
|
||||
if (Input.IsKeyPressed(KeyCode.I))
|
||||
{
|
||||
// NOTE: The NonAlloc version of Overlap functions should be used when possible since it doesn't allocate a new array
|
||||
// whenever you call it. The normal versions allocates a brand new array every time.
|
||||
|
||||
int numColliders = Physics.OverlapBoxNonAlloc(m_Transform.Transform.Translation, new Vec3(1.0F), colliders);
|
||||
|
||||
Console.WriteLine("Colliders: {0}", numColliders);
|
||||
// When using NonAlloc it's not safe to use a foreach loop since some of the colliders may not exist
|
||||
for (int i = 0; i < numColliders; i++)
|
||||
{
|
||||
Console.WriteLine(colliders[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (Input.IsKeyPressed(KeyCode.W))
|
||||
m_RigidBody.AddForce(m_Transform.Forward * m_CurrentSpeed);
|
||||
@ -105,7 +127,7 @@ namespace FPSExample
|
||||
Vec3 translation = m_Transform.Transform.Translation;
|
||||
cameraTranslation.XZ = translation.XZ;
|
||||
cameraTranslation.Y = translation.Y + 1.5F;
|
||||
cameraTransform.Translation = cameraTranslation;
|
||||
cameraTransform.Translation = cameraTranslation + m_CameraTransform.Forward * -Mathf.Clamp(Distance, 0, 10);
|
||||
m_CameraTransform.Transform = cameraTransform;
|
||||
|
||||
m_CameraTransform.Rotation = new Vec3(m_CameraRotationX, m_RotationY, 0.0f);
|
||||
|
||||
@ -55,6 +55,12 @@ namespace Prism
|
||||
return new Entity(entityID);
|
||||
}
|
||||
|
||||
public Entity FindEntityByID(ulong entityID)
|
||||
{
|
||||
// TODO: to verify it
|
||||
return new Entity(entityID);
|
||||
}
|
||||
|
||||
public Mat4 GetTransform()
|
||||
{
|
||||
Mat4 mat4Instance;
|
||||
|
||||
@ -11,11 +11,30 @@ namespace Prism
|
||||
Locked = 2,
|
||||
}
|
||||
|
||||
public enum MouseButton
|
||||
{
|
||||
Button0 = 0,
|
||||
Button1 = 1,
|
||||
Button2 = 2,
|
||||
Button3 = 3,
|
||||
Button4 = 4,
|
||||
Button5 = 5,
|
||||
Left = Button0,
|
||||
Right = Button1,
|
||||
Middle = Button2
|
||||
}
|
||||
|
||||
|
||||
public static bool IsKeyPressed(KeyCode keycode)
|
||||
{
|
||||
return IsKeyPressed_Native(keycode);
|
||||
}
|
||||
|
||||
public static bool IsMouseButtonPressed(MouseButton button)
|
||||
{
|
||||
return IsMouseButtonPressed_Native(button);
|
||||
}
|
||||
|
||||
public static Vec2 GetMousePosition()
|
||||
{
|
||||
GetMousePosition_Native(out Vec2 position);
|
||||
@ -30,6 +49,9 @@ namespace Prism
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern bool IsKeyPressed_Native(KeyCode keycode);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern bool IsMouseButtonPressed_Native(MouseButton button);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern void GetMousePosition_Native(out Vec2 position);
|
||||
|
||||
|
||||
@ -46,6 +46,25 @@ namespace Prism
|
||||
Z = Mathf.Clamp(Z, min.Z, max.Z);
|
||||
}
|
||||
|
||||
public float Length()
|
||||
{
|
||||
return (float)Math.Sqrt(X * X + Y * Y + Z * Z);
|
||||
}
|
||||
|
||||
public Vec3 Normalized()
|
||||
{
|
||||
float length = Length();
|
||||
return new Vec3(X / length, Y / length, Z / length);
|
||||
}
|
||||
|
||||
public void Normalize()
|
||||
{
|
||||
float length = Length();
|
||||
X = X / length;
|
||||
Y = Y / length;
|
||||
Z = Z / length;
|
||||
}
|
||||
|
||||
|
||||
public Vec2 XY {
|
||||
get { return new Vec2(X, Y); }
|
||||
@ -79,6 +98,11 @@ namespace Prism
|
||||
return new Vec3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||
}
|
||||
|
||||
public static Vec3 operator +(Vec3 left, float right)
|
||||
{
|
||||
return new Vec3(left.X + right, left.Y + right, left.Z + right);
|
||||
}
|
||||
|
||||
public static Vec3 operator -(Vec3 left, Vec3 right)
|
||||
{
|
||||
return new Vec3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||
|
||||
@ -4,29 +4,55 @@ namespace Prism
|
||||
{
|
||||
public class Collider
|
||||
{
|
||||
public enum ColliderType
|
||||
{
|
||||
Box,
|
||||
Sphere,
|
||||
Capsule,
|
||||
Mesh
|
||||
}
|
||||
|
||||
public Entity ColliderEntity { get; protected set; }
|
||||
public ColliderType Type { get; protected set; }
|
||||
public ulong EntityID { get; protected set; }
|
||||
public bool IsTrigger { get; protected set; }
|
||||
|
||||
private Entity entity;
|
||||
private RigidBodyComponent _rigidBodyComponent;
|
||||
|
||||
public Entity Entity
|
||||
{
|
||||
get
|
||||
{
|
||||
if (entity == null)
|
||||
entity = new Entity(EntityID);
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
public RigidBodyComponent RigidBody
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_rigidBodyComponent == null)
|
||||
_rigidBodyComponent = Entity.GetComponent<RigidBodyComponent>();
|
||||
|
||||
return _rigidBodyComponent;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string type = "Collider";
|
||||
|
||||
if (this is BoxCollider) type = "BoxCollider";
|
||||
else if (this is SphereCollider) type = "SphereCollider";
|
||||
else if (this is CapsuleCollider) type = "CapsuleCollider";
|
||||
else if (this is MeshCollider) type = "MeshCollider";
|
||||
|
||||
return "Collider(" + type + ", " + EntityID + ", " + IsTrigger + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public class BoxCollider : Collider
|
||||
{
|
||||
public Vec3 Size { get; private set; }
|
||||
public Vec3 Offset { get; private set; }
|
||||
public Vec3 Size { get; protected set; }
|
||||
public Vec3 Offset { get; protected set; }
|
||||
|
||||
internal BoxCollider(ulong entityID, Vec3 size, Vec3 offset, bool isTrigger)
|
||||
private BoxCollider(ulong entityID, bool isTrigger, Vec3 size, Vec3 offset)
|
||||
{
|
||||
ColliderEntity = new Entity(entityID);
|
||||
Type = ColliderType.Box;
|
||||
EntityID = entityID;
|
||||
Size = size;
|
||||
Offset = offset;
|
||||
IsTrigger = isTrigger;
|
||||
@ -35,12 +61,11 @@ namespace Prism
|
||||
|
||||
public class SphereCollider : Collider
|
||||
{
|
||||
public float Radius { get; private set; }
|
||||
public float Radius { get; protected set; }
|
||||
|
||||
internal SphereCollider(ulong entityID, float radius, bool isTrigger)
|
||||
private SphereCollider(ulong entityID, bool isTrigger, float radius)
|
||||
{
|
||||
ColliderEntity = new Entity(entityID);
|
||||
Type = ColliderType.Box;
|
||||
EntityID = entityID;
|
||||
Radius = radius;
|
||||
IsTrigger = isTrigger;
|
||||
}
|
||||
@ -48,13 +73,12 @@ namespace Prism
|
||||
|
||||
public class CapsuleCollider : Collider
|
||||
{
|
||||
public float Radius { get; private set; }
|
||||
public float Height { get; private set; }
|
||||
public float Radius { get; protected set; }
|
||||
public float Height { get; protected set; }
|
||||
|
||||
internal CapsuleCollider(ulong entityID, float radius, float height, bool isTrigger)
|
||||
private CapsuleCollider(ulong entityID, bool isTrigger, float radius, float height)
|
||||
{
|
||||
ColliderEntity = new Entity(entityID);
|
||||
Type = ColliderType.Box;
|
||||
EntityID = entityID;
|
||||
Radius = radius;
|
||||
Height = height;
|
||||
IsTrigger = isTrigger;
|
||||
@ -63,13 +87,12 @@ namespace Prism
|
||||
|
||||
public class MeshCollider : Collider
|
||||
{
|
||||
public Mesh Mesh { get; private set; }
|
||||
public Mesh Mesh { get; protected set; }
|
||||
|
||||
internal MeshCollider(ulong entityID, Mesh mesh, bool isTrigger)
|
||||
private MeshCollider(ulong entityID, bool isTrigger, IntPtr filepath)
|
||||
{
|
||||
ColliderEntity = new Entity(entityID);
|
||||
Type = ColliderType.Box;
|
||||
Mesh = mesh;
|
||||
EntityID = entityID;
|
||||
Mesh = new Mesh(filepath);
|
||||
IsTrigger = isTrigger;
|
||||
}
|
||||
}
|
||||
|
||||
74
Prism-ScriptCore/Src/Prism/Physics/Physics.cs
Normal file
74
Prism-ScriptCore/Src/Prism/Physics/Physics.cs
Normal file
@ -0,0 +1,74 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RaycastHit
|
||||
{
|
||||
public ulong EntityID { get; private set; }
|
||||
public Vec3 Position { get; private set; }
|
||||
public Vec3 Normal { get; private set; }
|
||||
public float Distance { get; private set; }
|
||||
}
|
||||
|
||||
public static class Physics
|
||||
{
|
||||
public static bool Raycast(Vec3 origin, Vec3 direction, float maxDistance, out RaycastHit hit)
|
||||
{
|
||||
return Raycast_Native(ref origin, ref direction, maxDistance, out hit);
|
||||
}
|
||||
|
||||
public static Collider[] OverlapBox(Vec3 origin, Vec3 halfSize)
|
||||
{
|
||||
return OverlapBox_Native(ref origin, ref halfSize);
|
||||
}
|
||||
|
||||
public static Collider[] OverlapCapsule(Vec3 origin, float radius, float halfHeight)
|
||||
{
|
||||
return OverlapCapsule_Native(ref origin, radius, halfHeight);
|
||||
}
|
||||
|
||||
public static Collider[] OverlapSphere(Vec3 origin, float radius)
|
||||
{
|
||||
return OverlapSphere_Native(ref origin, radius);
|
||||
}
|
||||
|
||||
public static int OverlapBoxNonAlloc(Vec3 origin, Vec3 halfSize, Collider[] colliders)
|
||||
{
|
||||
return OverlapBoxNonAlloc_Native(ref origin, ref halfSize, colliders);
|
||||
}
|
||||
|
||||
public static int OverlapCapsuleNonAlloc(Vec3 origin, float radius, float halfHeight, Collider[] colliders)
|
||||
{
|
||||
return OverlapCapsuleNonAlloc_Native(ref origin, radius, halfHeight, colliders);
|
||||
}
|
||||
|
||||
public static int OverlapSphereNonAlloc(Vec3 origin, float radius, Collider[] colliders)
|
||||
{
|
||||
return OverlapSphereNonAlloc_Native(ref origin, radius, colliders);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern bool Raycast_Native(ref Vec3 origin, ref Vec3 direction, float maxDistance, out RaycastHit hit);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern Collider[] OverlapBox_Native(ref Vec3 origin, ref Vec3 halfSize);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern Collider[] OverlapCapsule_Native(ref Vec3 origin, float radius, float halfHeight);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern Collider[] OverlapSphere_Native(ref Vec3 origin, float radius);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern int OverlapBoxNonAlloc_Native(ref Vec3 origin, ref Vec3 halfSize, Collider[] colliders);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern int OverlapCapsuleNonAlloc_Native(ref Vec3 origin, float radius, float halfHeight, Collider[] colliders);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern int OverlapSphereNonAlloc_Native(ref Vec3 origin, float radius, Collider[] colliders);
|
||||
}
|
||||
}
|
||||
@ -193,6 +193,18 @@ namespace Prism
|
||||
Acceleration
|
||||
}
|
||||
|
||||
public float Mass
|
||||
{
|
||||
get { return GetMass_Native(Entity.ID); }
|
||||
set { SetMass_Native(Entity.ID, value); }
|
||||
}
|
||||
|
||||
public uint Layer
|
||||
{
|
||||
get { return GetLayer_Native(Entity.ID); }
|
||||
}
|
||||
|
||||
|
||||
public void AddForce(Vec3 force, ForceMode forceMode = ForceMode.Force)
|
||||
{
|
||||
AddForce_Native(Entity.ID, ref force, forceMode);
|
||||
@ -234,5 +246,14 @@ namespace Prism
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern void Rotate_Native(ulong entityID, ref Vec3 rotation);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern uint GetLayer_Native(ulong entityID);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern float GetMass_Native(ulong entityID);
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern float SetMass_Native(ulong entityID, float mass);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,19 +9,12 @@
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
enum class CursorMode
|
||||
{
|
||||
Normal = 0,
|
||||
Hidden = 1,
|
||||
Locked = 2
|
||||
};
|
||||
|
||||
class PRISM_API Input
|
||||
{
|
||||
public:
|
||||
static bool IsKeyPressed(KeyCode keycode);
|
||||
|
||||
static bool IsMouseButtonPressed(int button);
|
||||
static bool IsMouseButtonPressed(MouseButton button);
|
||||
static float GetMouseX();
|
||||
static float GetMouseY();
|
||||
static std::pair<float, float> GetMousePosition();
|
||||
|
||||
@ -7,6 +7,32 @@
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
enum class CursorMode
|
||||
{
|
||||
Normal = 0,
|
||||
Hidden = 1,
|
||||
Locked = 2
|
||||
};
|
||||
|
||||
typedef enum class MouseButton : uint16_t
|
||||
{
|
||||
Button0 = 0,
|
||||
Button1 = 1,
|
||||
Button2 = 2,
|
||||
Button3 = 3,
|
||||
Button4 = 4,
|
||||
Button5 = 5,
|
||||
Left = Button0,
|
||||
Right = Button1,
|
||||
Middle = Button2
|
||||
} Button;
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, MouseButton button)
|
||||
{
|
||||
os << static_cast<int32_t>(button);
|
||||
return os;
|
||||
}
|
||||
|
||||
typedef enum class KeyCode : uint16_t
|
||||
{
|
||||
SPACE = 32,
|
||||
|
||||
@ -45,11 +45,11 @@ namespace Prism
|
||||
const glm::vec2 delta = (mouse - m_InitialMousePosition) * 0.003f;
|
||||
m_InitialMousePosition = mouse;
|
||||
|
||||
if (Input::IsMouseButtonPressed(GLFW_MOUSE_BUTTON_MIDDLE))
|
||||
if (Input::IsMouseButtonPressed(MouseButton::Middle))
|
||||
MousePan(delta);
|
||||
else if (Input::IsMouseButtonPressed(GLFW_MOUSE_BUTTON_LEFT))
|
||||
else if (Input::IsMouseButtonPressed(MouseButton::Left))
|
||||
MouseRotate(delta);
|
||||
else if (Input::IsMouseButtonPressed(GLFW_MOUSE_BUTTON_RIGHT))
|
||||
else if (Input::IsMouseButtonPressed(MouseButton::Right))
|
||||
MouseZoom(delta.y);
|
||||
}
|
||||
|
||||
|
||||
109
Prism/src/Prism/Editor/PhysicsSettingsWindow.cpp
Normal file
109
Prism/src/Prism/Editor/PhysicsSettingsWindow.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
//
|
||||
// Created by sfd on 25-12-25.
|
||||
//
|
||||
|
||||
#include "PhysicsSettingsWindow.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include "Prism/Physics/PhysicsLayer.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
static int32_t s_SelectedLayer = -1;
|
||||
static char s_NewLayerNameBuffer[50];
|
||||
|
||||
void PhysicsSettingsWindow::OnImGuiRender(bool* show)
|
||||
{
|
||||
if (!(*show))
|
||||
return;
|
||||
|
||||
ImGui::Begin("Physics", show);
|
||||
ImGui::PushID(0);
|
||||
ImGui::Columns(2);
|
||||
|
||||
RenderLayerList();
|
||||
ImGui::NextColumn();
|
||||
RenderSelectedLayer();
|
||||
|
||||
ImGui::PopID();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void PhysicsSettingsWindow::RenderLayerList()
|
||||
{
|
||||
if (ImGui::Button("New Layer"))
|
||||
{
|
||||
ImGui::OpenPopup("NewLayerNamePopup");
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("NewLayerNamePopup"))
|
||||
{
|
||||
ImGui::InputText("##LayerNameID", s_NewLayerNameBuffer, 50);
|
||||
|
||||
if (ImGui::Button("Add"))
|
||||
{
|
||||
PhysicsLayerManager::AddLayer(std::string(s_NewLayerNameBuffer));
|
||||
memset(s_NewLayerNameBuffer, 0, 50);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
uint32_t buttonId = 1;
|
||||
|
||||
for (const auto& layer : PhysicsLayerManager::GetLayers())
|
||||
{
|
||||
if (ImGui::Button(layer.Name.c_str()))
|
||||
{
|
||||
s_SelectedLayer = layer.LayerID;
|
||||
}
|
||||
|
||||
if (layer.Name != "Default")
|
||||
{
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(buttonId++);
|
||||
if (ImGui::Button("X"))
|
||||
{
|
||||
PhysicsLayerManager::RemoveLayer(layer.LayerID);
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PhysicsSettingsWindow::RenderSelectedLayer()
|
||||
{
|
||||
if (s_SelectedLayer == -1)
|
||||
return;
|
||||
|
||||
const PhysicsLayer& layerInfo = PhysicsLayerManager::GetLayer(s_SelectedLayer);
|
||||
|
||||
for (const auto& layer : PhysicsLayerManager::GetLayers())
|
||||
{
|
||||
if (layer.LayerID == s_SelectedLayer)
|
||||
continue;
|
||||
|
||||
const PhysicsLayer& otherLayerInfo = PhysicsLayerManager::GetLayer(layer.LayerID);
|
||||
bool shouldCollide;
|
||||
|
||||
if (layerInfo.CollidesWith == 0 || otherLayerInfo.CollidesWith == 0)
|
||||
{
|
||||
shouldCollide = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
shouldCollide = layerInfo.CollidesWith & otherLayerInfo.BitValue;
|
||||
}
|
||||
|
||||
ImGui::TextUnformatted(otherLayerInfo.Name.c_str());
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox(("##" + otherLayerInfo.Name).c_str(), &shouldCollide))
|
||||
{
|
||||
PhysicsLayerManager::SetLayerCollision(s_SelectedLayer, layer.LayerID, shouldCollide);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
20
Prism/src/Prism/Editor/PhysicsSettingsWindow.h
Normal file
20
Prism/src/Prism/Editor/PhysicsSettingsWindow.h
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by sfd on 25-12-25.
|
||||
//
|
||||
|
||||
#ifndef PHYSICSSETTINGSWINDOW_H
|
||||
#define PHYSICSSETTINGSWINDOW_H
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class PRISM_API PhysicsSettingsWindow
|
||||
{
|
||||
public:
|
||||
static void OnImGuiRender(bool* show);
|
||||
static void RenderLayerList();
|
||||
static void RenderSelectedLayer();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PHYSICSSETTINGSWINDOW_H
|
||||
@ -12,7 +12,8 @@
|
||||
#include "glm/gtx/matrix_decompose.hpp"
|
||||
#include "glm/gtx/quaternion.hpp"
|
||||
#include "Prism/Core/Application.h"
|
||||
#include "Prism/Physics/PxPhysicsWrappers.h"
|
||||
#include "Prism/Physics/PhysicsLayer.h"
|
||||
#include "Prism/Physics/PhysicsWrappers.h"
|
||||
#include "Prism/Renderer/Meshfactory.h"
|
||||
#include "Prism/Script/ScriptEngine.h"
|
||||
|
||||
@ -951,7 +952,10 @@ namespace Prism
|
||||
// Rigidbody Type
|
||||
const char* rbTypeStrings[] = { "Static", "Dynamic"};
|
||||
const char* currentType = rbTypeStrings[(int)rbc.BodyType];
|
||||
if (ImGui::BeginCombo("Type", currentType))
|
||||
|
||||
ImGui::TextUnformatted("Type");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::BeginCombo("##TypeSelection", currentType))
|
||||
{
|
||||
for (int type = 0; type < 2; type++)
|
||||
{
|
||||
@ -967,6 +971,32 @@ namespace Prism
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
|
||||
// Layer has been removed, set to Default layer
|
||||
if (!PhysicsLayerManager::IsLayerValid(rbc.Layer))
|
||||
rbc.Layer = 0;
|
||||
|
||||
uint32_t currentLayer = rbc.Layer;
|
||||
const PhysicsLayer& layerInfo = PhysicsLayerManager::GetLayer(currentLayer);
|
||||
ImGui::TextUnformatted("Layer");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::BeginCombo("##LayerSelection", layerInfo.Name.c_str()))
|
||||
{
|
||||
for (const auto& layer : PhysicsLayerManager::GetLayers())
|
||||
{
|
||||
const bool is_selected = (currentLayer == layer.LayerID);
|
||||
if (ImGui::Selectable(layer.Name.c_str(), is_selected))
|
||||
{
|
||||
currentLayer = layer.LayerID;
|
||||
rbc.Layer = layer.LayerID;
|
||||
}
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
|
||||
if (rbc.BodyType == RigidBodyComponent::Type::Dynamic)
|
||||
{
|
||||
BeginPropertyGrid();
|
||||
@ -1071,7 +1101,7 @@ namespace Prism
|
||||
if (!file.empty())
|
||||
{
|
||||
mcc.CollisionMesh = Ref<Mesh>::Create(file);
|
||||
PxPhysicsWrappers::CreateConvexMesh(mcc);
|
||||
PhysicsWrappers::CreateConvexMesh(mcc);
|
||||
}
|
||||
}
|
||||
ImGui::EndColumns();
|
||||
|
||||
@ -12,16 +12,12 @@
|
||||
#define PX_PHYSX_STATIC_LIB
|
||||
#include <PxPhysicsAPI.h>
|
||||
|
||||
#include "PxPhysicsWrappers.h"
|
||||
#include "PhysicsLayer.h"
|
||||
#include "PhysicsWrappers.h"
|
||||
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
static physx::PxScene* s_Scene = nullptr;
|
||||
static std::vector<Entity> s_SimulatedEntities;
|
||||
static Entity* s_EntityStorageBuffer = nullptr;
|
||||
static int s_EntityStorageBufferPosition = 0;
|
||||
|
||||
static std::tuple<glm::vec3, glm::quat, glm::vec3> GetTransformDecomposition(const glm::mat4& transform)
|
||||
{
|
||||
glm::vec3 scale, translation, skew;
|
||||
@ -32,20 +28,26 @@ namespace Prism
|
||||
return { translation, orientation, scale };
|
||||
}
|
||||
|
||||
static physx::PxScene* s_Scene;
|
||||
static std::vector<Entity> s_SimulatedEntities;
|
||||
static Entity* s_EntityStorageBuffer;
|
||||
static int s_EntityStorageBufferPosition;
|
||||
|
||||
void Physics3D::Init()
|
||||
{
|
||||
PxPhysicsWrappers::Initialize();
|
||||
PhysicsWrappers::Initialize();
|
||||
PhysicsLayerManager::AddLayer("Default");
|
||||
}
|
||||
|
||||
void Physics3D::Shutdown()
|
||||
{
|
||||
PxPhysicsWrappers::Shutdown();
|
||||
PhysicsWrappers::Shutdown();
|
||||
}
|
||||
|
||||
void Physics3D::CreateScene(const SceneParams& params)
|
||||
{
|
||||
PM_CORE_ASSERT(s_Scene == nullptr, "Scene already has a Physics Scene!");
|
||||
s_Scene = PxPhysicsWrappers::CreateScene(params);
|
||||
s_Scene = PhysicsWrappers::CreateScene(params);
|
||||
}
|
||||
|
||||
void Physics3D::CreateActor(Entity e, int entityCount)
|
||||
@ -67,53 +69,48 @@ namespace Prism
|
||||
if (s_EntityStorageBuffer == nullptr)
|
||||
s_EntityStorageBuffer = new Entity[entityCount];
|
||||
|
||||
// Create Actor Body
|
||||
physx::PxRigidActor* actor = PxPhysicsWrappers::CreateActor(rigidbody, e.Transform());
|
||||
physx::PxRigidActor* actor = PhysicsWrappers::CreateActor(rigidbody, e.Transform());
|
||||
s_SimulatedEntities.push_back(e);
|
||||
Entity* entityStorage = &s_EntityStorageBuffer[s_EntityStorageBufferPosition++];
|
||||
*entityStorage = e;
|
||||
actor->userData = (void*)entityStorage;
|
||||
rigidbody.RuntimeActor = actor;
|
||||
|
||||
// Physics Material
|
||||
const physx::PxMaterial* material = PxPhysicsWrappers::CreateMaterial(e.GetComponent<PhysicsMaterialComponent>());
|
||||
const physx::PxMaterial* material = PhysicsWrappers::CreateMaterial(e.GetComponent<PhysicsMaterialComponent>());
|
||||
|
||||
const auto& transform = e.Transform();
|
||||
auto [translation, rotation, scale] = GetTransformDecomposition(transform);
|
||||
|
||||
auto [translation, rotationQuat, scale] = GetTransformDecomposition(e.Transform());
|
||||
|
||||
// Add all colliders
|
||||
if (e.HasComponent<BoxColliderComponent>())
|
||||
{
|
||||
const BoxColliderComponent& collider = e.GetComponent<BoxColliderComponent>();
|
||||
PxPhysicsWrappers::AddBoxCollider(*actor, *material, collider, scale);
|
||||
PhysicsWrappers::AddBoxCollider(*actor, *material, collider, scale);
|
||||
}
|
||||
|
||||
if (e.HasComponent<SphereColliderComponent>())
|
||||
{
|
||||
const SphereColliderComponent& collider = e.GetComponent<SphereColliderComponent>();
|
||||
PxPhysicsWrappers::AddSphereCollider(*actor, *material, collider, scale);
|
||||
PhysicsWrappers::AddSphereCollider(*actor, *material, collider, scale);
|
||||
}
|
||||
|
||||
if (e.HasComponent<CapsuleColliderComponent>())
|
||||
{
|
||||
const CapsuleColliderComponent& collider = e.GetComponent<CapsuleColliderComponent>();
|
||||
PxPhysicsWrappers::AddCapsuleCollider(*actor, *material, collider, scale);
|
||||
PhysicsWrappers::AddCapsuleCollider(*actor, *material, collider, scale);
|
||||
}
|
||||
|
||||
if (e.HasComponent<MeshColliderComponent>())
|
||||
{
|
||||
MeshColliderComponent& collider = e.GetComponent<MeshColliderComponent>();
|
||||
PxPhysicsWrappers::AddMeshCollider(*actor, *material, collider, scale);
|
||||
auto& collider = e.GetComponent<MeshColliderComponent>();
|
||||
PhysicsWrappers::AddMeshCollider(*actor, *material, collider, scale);
|
||||
}
|
||||
|
||||
// Set collision filters
|
||||
if (rigidbody.BodyType == RigidBodyComponent::Type::Static)
|
||||
{
|
||||
PxPhysicsWrappers::SetCollisionFilters(*actor, (uint32_t)FilterGroup::Static, (uint32_t)FilterGroup::All);
|
||||
}
|
||||
else if (rigidbody.BodyType == RigidBodyComponent::Type::Dynamic)
|
||||
{
|
||||
PxPhysicsWrappers::SetCollisionFilters(*actor, (uint32_t)FilterGroup::Dynamic, (uint32_t)FilterGroup::All);
|
||||
}
|
||||
if (!PhysicsLayerManager::IsLayerValid(rigidbody.Layer))
|
||||
rigidbody.Layer = 0;
|
||||
|
||||
PhysicsWrappers::SetCollisionFilters(*actor, rigidbody.Layer);
|
||||
|
||||
s_Scene->addActor(*actor);
|
||||
}
|
||||
@ -127,7 +124,7 @@ namespace Prism
|
||||
{
|
||||
auto& transform = e.Transform();
|
||||
// TODO: Come up with a better solution for scale
|
||||
auto [p, r, scale] = GetTransformDecomposition(transform);
|
||||
auto [position, rotation, scale] = GetTransformDecomposition(transform);
|
||||
const auto& rb = e.GetComponent<RigidBodyComponent>();
|
||||
const auto actor = static_cast<physx::PxRigidActor*>(rb.RuntimeActor);
|
||||
|
||||
@ -153,10 +150,15 @@ namespace Prism
|
||||
s_Scene = nullptr;
|
||||
}
|
||||
|
||||
void* Physics3D::GetPhysicsScene()
|
||||
{
|
||||
return s_Scene;
|
||||
}
|
||||
|
||||
bool Physics3D::ConnectPVD()
|
||||
{
|
||||
PM_CORE_INFO("Trying to connect PVD");
|
||||
const bool isconnect = PxPhysicsWrappers::ConnectPVD();
|
||||
const bool isconnect = PhysicsWrappers::ConnectPVD();
|
||||
if (isconnect)
|
||||
PM_CORE_INFO("PVD Connected");
|
||||
else
|
||||
@ -164,11 +166,11 @@ namespace Prism
|
||||
return isconnect;
|
||||
}
|
||||
|
||||
bool Physics3D::IsPVDConnected() {return PxPhysicsWrappers::IsPVDConnected();}
|
||||
bool Physics3D::IsPVDConnected() {return PhysicsWrappers::IsPVDConnected();}
|
||||
|
||||
void Physics3D::DisconnectPVD()
|
||||
{
|
||||
PxPhysicsWrappers::DisconnectPVD();
|
||||
PhysicsWrappers::DisconnectPVD();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -27,6 +27,14 @@ namespace Prism
|
||||
All = Static | Dynamic | Kinematic
|
||||
};
|
||||
|
||||
struct RaycastHit
|
||||
{
|
||||
uint64_t EntityID;
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Normal;
|
||||
float Distance;
|
||||
};
|
||||
|
||||
struct SceneParams
|
||||
{
|
||||
glm::vec3 Gravity = { 0.0F, -9.81F, 0.0F };
|
||||
@ -45,6 +53,8 @@ namespace Prism
|
||||
|
||||
static void DestroyScene();
|
||||
|
||||
static void* GetPhysicsScene();
|
||||
|
||||
static bool ConnectPVD();
|
||||
static bool IsPVDConnected();
|
||||
static void DisconnectPVD();
|
||||
|
||||
168
Prism/src/Prism/Physics/PhysicsLayer.cpp
Normal file
168
Prism/src/Prism/Physics/PhysicsLayer.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
//
|
||||
// Created by sfd on 25-12-25.
|
||||
//
|
||||
|
||||
#include "PhysicsLayer.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
template<typename T, typename ConditionFunction>
|
||||
static bool RemoveIfExists(std::vector<T>& vector, ConditionFunction condition)
|
||||
{
|
||||
for (std::vector<T>::iterator it = vector.begin(); it != vector.end(); ++it)
|
||||
{
|
||||
if (condition(*it))
|
||||
{
|
||||
vector.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t PhysicsLayerManager::AddLayer(const std::string& name, bool setCollisions)
|
||||
{
|
||||
const uint32_t layerId = GetNextLayerID();
|
||||
const PhysicsLayer layer = { layerId, name, static_cast<uint32_t>(BIT(layerId)) };
|
||||
s_Layers.push_back(layer);
|
||||
|
||||
if (setCollisions)
|
||||
{
|
||||
for (const auto& layer2 : s_Layers)
|
||||
{
|
||||
SetLayerCollision(layer.LayerID, layer2.LayerID, true);
|
||||
}
|
||||
}
|
||||
|
||||
return layer.LayerID;
|
||||
}
|
||||
|
||||
void PhysicsLayerManager::RemoveLayer(uint32_t layerId)
|
||||
{
|
||||
if (!IsLayerValid(layerId))
|
||||
return;
|
||||
|
||||
const PhysicsLayer& layerInfo = GetLayer(layerId);
|
||||
|
||||
for (auto& otherLayer : s_Layers)
|
||||
{
|
||||
if (otherLayer.LayerID == layerId)
|
||||
continue;
|
||||
|
||||
if (otherLayer.CollidesWith & layerInfo.BitValue)
|
||||
{
|
||||
otherLayer.CollidesWith &= ~layerInfo.BitValue;
|
||||
}
|
||||
}
|
||||
|
||||
RemoveIfExists<PhysicsLayer>(s_Layers, [&](const PhysicsLayer& layer) { return layer.LayerID == layerId; });
|
||||
}
|
||||
|
||||
void PhysicsLayerManager::SetLayerCollision(uint32_t layerId, uint32_t otherLayer, bool collides)
|
||||
{
|
||||
if (ShouldCollide(layerId, otherLayer) && collides)
|
||||
return;
|
||||
|
||||
PhysicsLayer& layerInfo = GetLayer(layerId);
|
||||
PhysicsLayer& otherLayerInfo = GetLayer(otherLayer);
|
||||
|
||||
if (collides)
|
||||
{
|
||||
layerInfo.CollidesWith |= otherLayerInfo.BitValue;
|
||||
otherLayerInfo.CollidesWith |= layerInfo.BitValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
layerInfo.CollidesWith &= ~otherLayerInfo.BitValue;
|
||||
otherLayerInfo.CollidesWith &= ~layerInfo.BitValue;
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<PhysicsLayer>& PhysicsLayerManager::GetLayerCollisions(uint32_t layerId)
|
||||
{
|
||||
const PhysicsLayer& layer = GetLayer(layerId);
|
||||
|
||||
std::vector<PhysicsLayer> layers;
|
||||
for (const auto& otherLayer : s_Layers)
|
||||
{
|
||||
if (otherLayer.LayerID == layerId)
|
||||
continue;
|
||||
|
||||
if (layer.CollidesWith & otherLayer.BitValue)
|
||||
layers.push_back(otherLayer);
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
PhysicsLayer& PhysicsLayerManager::GetLayer(uint32_t layerId)
|
||||
{
|
||||
for (auto& layer : s_Layers)
|
||||
{
|
||||
if (layer.LayerID == layerId)
|
||||
{
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
|
||||
return s_NullLayer;
|
||||
}
|
||||
|
||||
PhysicsLayer& PhysicsLayerManager::GetLayer(const std::string& layerName)
|
||||
{
|
||||
for (auto& layer : s_Layers)
|
||||
{
|
||||
if (layer.Name == layerName)
|
||||
{
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
|
||||
return s_NullLayer;
|
||||
}
|
||||
|
||||
bool PhysicsLayerManager::ShouldCollide(uint32_t layer1, uint32_t layer2)
|
||||
{
|
||||
return GetLayer(layer1).CollidesWith & GetLayer(layer2).BitValue;
|
||||
}
|
||||
|
||||
bool PhysicsLayerManager::IsLayerValid(uint32_t layerId)
|
||||
{
|
||||
for (const auto& layer : s_Layers)
|
||||
{
|
||||
if (layer.LayerID == layerId)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PhysicsLayerManager::ClearLayers()
|
||||
{
|
||||
s_Layers.clear();
|
||||
}
|
||||
|
||||
uint32_t PhysicsLayerManager::GetNextLayerID()
|
||||
{
|
||||
int32_t lastId = -1;
|
||||
|
||||
for (const auto& layer : s_Layers)
|
||||
{
|
||||
if (lastId != -1)
|
||||
{
|
||||
if (layer.LayerID != lastId + 1)
|
||||
{
|
||||
return lastId + 1;
|
||||
}
|
||||
}
|
||||
|
||||
lastId = layer.LayerID;
|
||||
}
|
||||
|
||||
return s_Layers.size();
|
||||
}
|
||||
|
||||
std::vector<PhysicsLayer> PhysicsLayerManager::s_Layers;
|
||||
PhysicsLayer PhysicsLayerManager::s_NullLayer = { 0, "NULL", 0, -1 };
|
||||
}
|
||||
51
Prism/src/Prism/Physics/PhysicsLayer.h
Normal file
51
Prism/src/Prism/Physics/PhysicsLayer.h
Normal file
@ -0,0 +1,51 @@
|
||||
//
|
||||
// Created by sfd on 25-12-25.
|
||||
//
|
||||
|
||||
#ifndef PHYSICSLAYER_H
|
||||
#define PHYSICSLAYER_H
|
||||
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
|
||||
struct PhysicsLayer
|
||||
{
|
||||
uint32_t LayerID;
|
||||
std::string Name;
|
||||
uint32_t BitValue;
|
||||
int32_t CollidesWith = 0;
|
||||
};
|
||||
|
||||
class PhysicsLayerManager
|
||||
{
|
||||
public:
|
||||
static uint32_t AddLayer(const std::string& name, bool setCollisions = true);
|
||||
static void RemoveLayer(uint32_t layerId);
|
||||
|
||||
static void SetLayerCollision(uint32_t layerId, uint32_t otherLayer, bool collides);
|
||||
static const std::vector<PhysicsLayer>& GetLayerCollisions(uint32_t layerId);
|
||||
|
||||
static const std::vector<PhysicsLayer>& GetLayers() { return s_Layers; }
|
||||
|
||||
static PhysicsLayer& GetLayer(uint32_t layerId);
|
||||
static PhysicsLayer& GetLayer(const std::string& layerName);
|
||||
static uint32_t GetLayerCount() { return static_cast<uint32_t>(s_Layers.size()); }
|
||||
|
||||
static bool ShouldCollide(uint32_t layer1, uint32_t layer2);
|
||||
static bool IsLayerValid(uint32_t layerId);
|
||||
|
||||
static void ClearLayers();
|
||||
|
||||
private:
|
||||
static uint32_t GetNextLayerID();
|
||||
|
||||
private:
|
||||
static std::vector<PhysicsLayer> s_Layers;
|
||||
static PhysicsLayer s_NullLayer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //PHYSICSLAYER_H
|
||||
@ -25,23 +25,23 @@ namespace Prism
|
||||
|
||||
physx::PxVec3 ToPhysXVector(const glm::vec3& vector)
|
||||
{
|
||||
return {vector.x, vector.y, vector.z};
|
||||
return *(physx::PxVec3*)&vector;
|
||||
}
|
||||
|
||||
physx::PxVec4 ToPhysXVector(const glm::vec4& vector)
|
||||
{
|
||||
return {vector.x, vector.y, vector.z, vector.w};
|
||||
return *(physx::PxVec4*)&vector;
|
||||
}
|
||||
|
||||
physx::PxQuat ToPhysXQuat(const glm::quat& quat)
|
||||
{
|
||||
return {quat.x, quat.y, quat.z, quat.w};
|
||||
return *(physx::PxQuat*)&quat;
|
||||
}
|
||||
|
||||
glm::mat4 FromPhysXTransform(const physx::PxTransform& transform)
|
||||
{
|
||||
glm::quat rotation = FromPhysXQuat(transform.q);
|
||||
glm::vec3 position = FromPhysXVector(transform.p);
|
||||
const glm::quat rotation = FromPhysXQuat(transform.q);
|
||||
const glm::vec3 position = FromPhysXVector(transform.p);
|
||||
return glm::translate(glm::mat4(1.0F), position) * glm::toMat4(rotation);
|
||||
}
|
||||
|
||||
@ -52,20 +52,20 @@ namespace Prism
|
||||
|
||||
glm::vec3 FromPhysXVector(const physx::PxVec3& vector)
|
||||
{
|
||||
return {vector.x, vector.y, vector.z};
|
||||
return *(glm::vec3*)&vector;
|
||||
}
|
||||
|
||||
glm::vec4 FromPhysXVector(const physx::PxVec4& vector)
|
||||
{
|
||||
return {vector.x, vector.y, vector.z, vector.w};
|
||||
return *(glm::vec4*)&vector;
|
||||
}
|
||||
|
||||
glm::quat FromPhysXQuat(const physx::PxQuat& quat)
|
||||
{
|
||||
return {quat.w, quat.x, quat.y, quat.z};
|
||||
return *(glm::quat*)&quat;
|
||||
}
|
||||
|
||||
physx::PxFilterFlags HazelFilterShader(physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1, physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize)
|
||||
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))
|
||||
{
|
||||
@ -79,9 +79,10 @@ namespace Prism
|
||||
{
|
||||
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_FOUND;
|
||||
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_LOST;
|
||||
return physx::PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
return physx::PxFilterFlag::eDEFAULT;
|
||||
return physx::PxFilterFlag::eSUPPRESS;
|
||||
}
|
||||
|
||||
void ContactListener::onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count)
|
||||
@ -92,14 +93,24 @@ namespace Prism
|
||||
|
||||
void ContactListener::onWake(physx::PxActor** actors, physx::PxU32 count)
|
||||
{
|
||||
PX_UNUSED(actors);
|
||||
PX_UNUSED(count);
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
physx::PxActor& actor = *actors[i];
|
||||
Entity& entity = *(Entity*)actor.userData;
|
||||
|
||||
PM_CORE_INFO("PhysX Actor waking up: ID: {0}, Name: {1}", static_cast<uint64_t>(entity.GetUUID()), entity.GetComponent<TagComponent>().Tag);
|
||||
}
|
||||
}
|
||||
|
||||
void ContactListener::onSleep(physx::PxActor** actors, physx::PxU32 count)
|
||||
{
|
||||
PX_UNUSED(actors);
|
||||
PX_UNUSED(count);
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
physx::PxActor& actor = *actors[i];
|
||||
Entity& entity = *(Entity*)actor.userData;
|
||||
|
||||
PM_CORE_INFO("PhysX Actor going to sleep: ID: {0}, Name: {1}", static_cast<uint64_t>(entity.GetUUID()), entity.GetComponent<TagComponent>().Tag);
|
||||
}
|
||||
}
|
||||
|
||||
void ContactListener::onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs)
|
||||
|
||||
@ -25,7 +25,7 @@ namespace Prism
|
||||
glm::vec4 FromPhysXVector(const physx::PxVec4& vector);
|
||||
glm::quat FromPhysXQuat(const physx::PxQuat& quat);
|
||||
|
||||
physx::PxFilterFlags HazelFilterShader(physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, physx::PxFilterObjectAttributes attributes1,
|
||||
physx::PxFilterFlags PrismFilterShader(physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, physx::PxFilterObjectAttributes attributes1,
|
||||
physx::PxFilterData filterData1, physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize);
|
||||
|
||||
class ContactListener final : public physx::PxSimulationEventCallback
|
||||
|
||||
@ -2,41 +2,94 @@
|
||||
// Created by sfd on 25-12-20.
|
||||
//
|
||||
|
||||
#include "PxPhysicsWrappers.h"
|
||||
#include "PhysicsWrappers.h"
|
||||
#include "Physics3D.h"
|
||||
#include <cooking/PxCooking.h>
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/rotate_vector.hpp>
|
||||
|
||||
#define PHYSX_DEBUGGER 1
|
||||
#include "PhysicsLayer.h"
|
||||
#define PHYSX_DEBUGGER
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
static physx::PxDefaultErrorCallback s_ErrorCallback;
|
||||
static PhysicsErrorCallback s_ErrorCallback;
|
||||
static physx::PxDefaultAllocator s_Allocator;
|
||||
static physx::PxFoundation* s_Foundation;
|
||||
static physx::PxPhysics* s_Physics;
|
||||
static physx::PxPvd* s_VisualDebugger;
|
||||
static physx::PxFoundation* s_Foundation = nullptr;
|
||||
static physx::PxPhysics* s_Physics = nullptr;
|
||||
static physx::PxPvd* s_VisualDebugger = nullptr;
|
||||
static physx::PxOverlapHit s_OverlapBuffer[OVERLAP_MAX_COLLIDERS];
|
||||
|
||||
|
||||
static physx::PxSimulationFilterShader s_FilterShader = physx::PxDefaultSimulationFilterShader;
|
||||
|
||||
static ContactListener s_ContactListener;
|
||||
|
||||
physx::PxScene* PxPhysicsWrappers::CreateScene(const SceneParams& sceneParams)
|
||||
void PhysicsErrorCallback::reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line)
|
||||
{
|
||||
const char* errorMessage = NULL;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case physx::PxErrorCode::eNO_ERROR: errorMessage = "No Error"; break;
|
||||
case physx::PxErrorCode::eDEBUG_INFO: errorMessage = "Info"; break;
|
||||
case physx::PxErrorCode::eDEBUG_WARNING: errorMessage = "Warning"; break;
|
||||
case physx::PxErrorCode::eINVALID_PARAMETER: errorMessage = "Invalid Parameter"; break;
|
||||
case physx::PxErrorCode::eINVALID_OPERATION: errorMessage = "Invalid Operation"; break;
|
||||
case physx::PxErrorCode::eOUT_OF_MEMORY: errorMessage = "Out Of Memory"; break;
|
||||
case physx::PxErrorCode::eINTERNAL_ERROR: errorMessage = "Internal Error"; break;
|
||||
case physx::PxErrorCode::eABORT: errorMessage = "Abort"; break;
|
||||
case physx::PxErrorCode::ePERF_WARNING: errorMessage = "Performance Warning"; break;
|
||||
case physx::PxErrorCode::eMASK_ALL: errorMessage = "Unknown Error"; break;
|
||||
}
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case physx::PxErrorCode::eNO_ERROR:
|
||||
case physx::PxErrorCode::eDEBUG_INFO:
|
||||
PM_CORE_INFO("[PhysX]: {0}: {1} at {2} ({3})", errorMessage, message, file, line);
|
||||
break;
|
||||
case physx::PxErrorCode::eDEBUG_WARNING:
|
||||
case physx::PxErrorCode::ePERF_WARNING:
|
||||
PM_CORE_WARN("[PhysX]: {0}: {1} at {2} ({3})", errorMessage, message, file, line);
|
||||
break;
|
||||
case physx::PxErrorCode::eINVALID_PARAMETER:
|
||||
case physx::PxErrorCode::eINVALID_OPERATION:
|
||||
case physx::PxErrorCode::eOUT_OF_MEMORY:
|
||||
case physx::PxErrorCode::eINTERNAL_ERROR:
|
||||
PM_CORE_ERROR("[PhysX]: {0}: {1} at {2} ({3})", errorMessage, message, file, line);
|
||||
break;
|
||||
case physx::PxErrorCode::eABORT:
|
||||
case physx::PxErrorCode::eMASK_ALL:
|
||||
PM_CORE_FATAL("[PhysX]: {0}: {1} at {2} ({3})", errorMessage, message, file, line);
|
||||
PM_CORE_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
physx::PxScene* PhysicsWrappers::CreateScene(const SceneParams& sceneParams)
|
||||
{
|
||||
physx::PxSceneDesc sceneDesc(s_Physics->getTolerancesScale());
|
||||
|
||||
sceneDesc.gravity = ToPhysXVector(sceneParams.Gravity);
|
||||
sceneDesc.cpuDispatcher = physx::PxDefaultCpuDispatcherCreate(1);
|
||||
sceneDesc.filterShader = HazelFilterShader;
|
||||
sceneDesc.filterShader = PrismFilterShader;
|
||||
sceneDesc.simulationEventCallback = &s_ContactListener;
|
||||
|
||||
sceneDesc.wakeCounterResetValue = 0.5f;
|
||||
sceneDesc.bounceThresholdVelocity = 0.1f;
|
||||
sceneDesc.frictionOffsetThreshold = 0.1f;
|
||||
sceneDesc.frictionCorrelationDistance = 0.1f;
|
||||
|
||||
sceneDesc.flags |= physx::PxSceneFlag::eENABLE_ACTIVE_ACTORS;
|
||||
|
||||
PM_CORE_ASSERT(sceneDesc.isValid());
|
||||
return s_Physics->createScene(sceneDesc);
|
||||
}
|
||||
|
||||
physx::PxRigidActor* PxPhysicsWrappers::CreateActor(const RigidBodyComponent& rigidbody, const glm::mat4& transform)
|
||||
physx::PxRigidActor* PhysicsWrappers::CreateActor(const RigidBodyComponent& rigidbody, const glm::mat4& transform)
|
||||
{
|
||||
physx::PxRigidActor* actor = nullptr;
|
||||
|
||||
@ -57,6 +110,14 @@ namespace Prism
|
||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, rigidbody.LockRotationY);
|
||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, rigidbody.LockRotationZ);
|
||||
|
||||
dynamicActor->setSleepThreshold(0.1f);
|
||||
dynamicActor->setAngularVelocity({1,1,1});
|
||||
dynamicActor->setActorFlag(physx::PxActorFlag::eDISABLE_SIMULATION, false);
|
||||
|
||||
// using OnWake and OnSleep callback should enable eSEND_SLEEP_NOTIFIES
|
||||
// https://nvidia-omniverse.github.io/PhysX/physx/5.6.1/_api_build/classPxSimulationEventCallback.html#_CPPv4N25PxSimulationEventCallback6onWakeEPP7PxActor5PxU32
|
||||
dynamicActor->setActorFlag(physx::PxActorFlag::eSEND_SLEEP_NOTIFIES, true);
|
||||
|
||||
physx::PxRigidBodyExt::updateMassAndInertia(*dynamicActor, rigidbody.Mass);
|
||||
actor = dynamicActor;
|
||||
}
|
||||
@ -64,11 +125,16 @@ namespace Prism
|
||||
return actor;
|
||||
}
|
||||
|
||||
void PxPhysicsWrappers::SetCollisionFilters(const physx::PxRigidActor& actor, const uint32_t actorGroup, const uint32_t filters)
|
||||
void PhysicsWrappers::SetCollisionFilters(const physx::PxRigidActor& actor, uint32_t physicsLayer)
|
||||
{
|
||||
const PhysicsLayer& layerInfo = PhysicsLayerManager::GetLayer(physicsLayer);
|
||||
|
||||
if (layerInfo.CollidesWith == 0)
|
||||
return;
|
||||
|
||||
physx::PxFilterData filterData;
|
||||
filterData.word0 = actorGroup;
|
||||
filterData.word1 = filters;
|
||||
filterData.word0 = layerInfo.BitValue;
|
||||
filterData.word1 = layerInfo.CollidesWith;
|
||||
|
||||
const physx::PxU32 numShapes = actor.getNbShapes();
|
||||
|
||||
@ -81,7 +147,7 @@ namespace Prism
|
||||
s_Allocator.deallocate(shapes);
|
||||
}
|
||||
|
||||
void PxPhysicsWrappers::AddBoxCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const BoxColliderComponent& collider, const glm::vec3& scale)
|
||||
void PhysicsWrappers::AddBoxCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const BoxColliderComponent& collider, const glm::vec3& scale)
|
||||
{
|
||||
glm::vec3 colliderSize = collider.Size;
|
||||
|
||||
@ -98,7 +164,7 @@ namespace Prism
|
||||
shape->setLocalPose(ToPhysXTransform(glm::translate(glm::mat4(1.0F), collider.Offset)));
|
||||
}
|
||||
|
||||
void PxPhysicsWrappers::AddSphereCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const SphereColliderComponent& collider, const glm::vec3& scale)
|
||||
void PhysicsWrappers::AddSphereCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const SphereColliderComponent& collider, const glm::vec3& scale)
|
||||
{
|
||||
float colliderRadius = collider.Radius;
|
||||
|
||||
@ -111,16 +177,16 @@ namespace Prism
|
||||
shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger);
|
||||
}
|
||||
|
||||
void PxPhysicsWrappers::AddCapsuleCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material,const CapsuleColliderComponent& collider, const glm::vec3& scale)
|
||||
void PhysicsWrappers::AddCapsuleCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material,const CapsuleColliderComponent& collider, const glm::vec3& scale)
|
||||
{
|
||||
float colliderRadius = collider.Radius;
|
||||
float colliderHeight = collider.Height;
|
||||
|
||||
if (scale.x != 0.0F) colliderRadius *= scale.x * 0.5f;
|
||||
if (scale.x != 0.0F) colliderRadius *= scale.x;
|
||||
if (scale.y != 0.0F) colliderHeight *= scale.y ;
|
||||
|
||||
|
||||
const auto capsuleGeometry = physx::PxCapsuleGeometry(colliderRadius, colliderHeight / 2.0F);
|
||||
const auto capsuleGeometry = physx::PxCapsuleGeometry(colliderRadius, colliderHeight * 0.5f);
|
||||
|
||||
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, capsuleGeometry, material);
|
||||
shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger);
|
||||
@ -130,21 +196,16 @@ namespace Prism
|
||||
}
|
||||
|
||||
|
||||
void PxPhysicsWrappers::AddMeshCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material,MeshColliderComponent& collider, const glm::vec3& scale)
|
||||
void PhysicsWrappers::AddMeshCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material,MeshColliderComponent& collider, const glm::vec3& scale)
|
||||
{
|
||||
// TODO: Possibly take a look at https://github.com/kmammou/v-hacd for computing convex meshes from triangle meshes...
|
||||
physx::PxConvexMeshGeometry triangleGeometry = physx::PxConvexMeshGeometry(CreateConvexMesh(collider));
|
||||
triangleGeometry.meshFlags = physx::PxConvexMeshGeometryFlag::eTIGHT_BOUNDS;
|
||||
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, triangleGeometry, material);
|
||||
physx::PxConvexMeshGeometry convexGeometry = physx::PxConvexMeshGeometry(CreateConvexMesh(collider));
|
||||
convexGeometry.meshFlags = physx::PxConvexMeshGeometryFlag::eTIGHT_BOUNDS;
|
||||
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, convexGeometry, material);
|
||||
shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger);
|
||||
shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger);
|
||||
|
||||
// TODO: temp solve
|
||||
// physx::PxQuat rotation(physx::PxPi / 2.0f, physx::PxVec3(1.0f, 0.0f, 0.0f));
|
||||
// shape->setLocalPose(physx::PxTransform(physx::PxVec3(0.0f), rotation));
|
||||
}
|
||||
|
||||
physx::PxConvexMesh* PxPhysicsWrappers::CreateConvexMesh(MeshColliderComponent& collider)
|
||||
physx::PxConvexMesh* PhysicsWrappers::CreateConvexMesh(MeshColliderComponent& collider)
|
||||
{
|
||||
const auto& vertices = collider.CollisionMesh->GetStaticVertices();
|
||||
|
||||
@ -177,7 +238,7 @@ namespace Prism
|
||||
|
||||
for (uint32_t i = 0; i < nbPolygons; i++)
|
||||
{
|
||||
physx::PxHullPolygon polygon;
|
||||
physx::PxHullPolygon polygon{};
|
||||
mesh->getPolygonData(i, polygon);
|
||||
nbVertices += polygon.mNbVerts;
|
||||
nbFaces += (polygon.mNbVerts - 2) * 3;
|
||||
@ -193,7 +254,7 @@ namespace Prism
|
||||
uint32_t indexCounter = 0;
|
||||
for (uint32_t i = 0; i < nbPolygons; i++)
|
||||
{
|
||||
physx::PxHullPolygon polygon;
|
||||
physx::PxHullPolygon polygon{};
|
||||
mesh->getPolygonData(i, polygon);
|
||||
|
||||
const uint32_t vI0 = vertCounter;
|
||||
@ -221,19 +282,102 @@ namespace Prism
|
||||
return mesh;
|
||||
}
|
||||
|
||||
physx::PxMaterial* PxPhysicsWrappers::CreateMaterial(const PhysicsMaterialComponent& material)
|
||||
physx::PxMaterial* PhysicsWrappers::CreateMaterial(const PhysicsMaterialComponent& material)
|
||||
{
|
||||
return s_Physics->createMaterial(material.StaticFriction, material.DynamicFriction, material.Bounciness);
|
||||
}
|
||||
|
||||
void PxPhysicsWrappers::Initialize()
|
||||
bool PhysicsWrappers::Raycast(const glm::vec3& origin, const glm::vec3& direction, float maxDistance, RaycastHit* hit)
|
||||
{
|
||||
const auto* scene = static_cast<physx::PxScene*>(Physics3D::GetPhysicsScene());
|
||||
physx::PxRaycastBuffer hitInfo;
|
||||
const bool result = scene->raycast(ToPhysXVector(origin), ToPhysXVector(glm::normalize(direction)), maxDistance, hitInfo);
|
||||
|
||||
if (result)
|
||||
{
|
||||
Entity& entity = *static_cast<Entity*>(hitInfo.block.actor->userData);
|
||||
|
||||
hit->EntityID = entity.GetUUID();
|
||||
hit->Position = FromPhysXVector(hitInfo.block.position);
|
||||
hit->Normal = FromPhysXVector(hitInfo.block.normal);
|
||||
hit->Distance = hitInfo.block.distance;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PhysicsWrappers::OverlapBox(const glm::vec3& origin, const glm::vec3& halfSize, std::array<physx::PxOverlapHit, OVERLAP_MAX_COLLIDERS>& buffer, uint32_t* count)
|
||||
{
|
||||
const physx::PxScene* scene = static_cast<physx::PxScene*>(Physics3D::GetPhysicsScene());
|
||||
|
||||
memset(s_OverlapBuffer, 0, sizeof(s_OverlapBuffer));
|
||||
physx::PxOverlapBuffer buf(s_OverlapBuffer, OVERLAP_MAX_COLLIDERS);
|
||||
|
||||
const auto geometry = physx::PxBoxGeometry(halfSize.x, halfSize.y, halfSize.z);
|
||||
const physx::PxTransform pose = ToPhysXTransform(glm::translate(glm::mat4(1.0F), origin));
|
||||
|
||||
const bool result = scene->overlap(geometry, pose, buf);
|
||||
|
||||
if (result)
|
||||
{
|
||||
const uint32_t bodyCount = buf.nbTouches >= OVERLAP_MAX_COLLIDERS ? OVERLAP_MAX_COLLIDERS : buf.nbTouches;
|
||||
memcpy(buffer.data(), buf.touches, bodyCount * sizeof(physx::PxOverlapHit));
|
||||
*count = bodyCount;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PhysicsWrappers::OverlapSphere(const glm::vec3& origin, float radius, std::array<physx::PxOverlapHit, OVERLAP_MAX_COLLIDERS>& buffer, uint32_t* count)
|
||||
{
|
||||
const physx::PxScene* scene = static_cast<physx::PxScene*>(Physics3D::GetPhysicsScene());
|
||||
|
||||
memset(s_OverlapBuffer, 0, sizeof(s_OverlapBuffer));
|
||||
physx::PxOverlapBuffer buf(s_OverlapBuffer, OVERLAP_MAX_COLLIDERS);
|
||||
const auto geometry = physx::PxSphereGeometry(radius);
|
||||
const physx::PxTransform pose = ToPhysXTransform(glm::translate(glm::mat4(1.0F), origin));
|
||||
|
||||
const bool result = scene->overlap(geometry, pose, buf);
|
||||
|
||||
if (result)
|
||||
{
|
||||
const uint32_t bodyCount = buf.nbTouches >= OVERLAP_MAX_COLLIDERS ? OVERLAP_MAX_COLLIDERS : buf.nbTouches;
|
||||
memcpy(buffer.data(), buf.touches, bodyCount * sizeof(physx::PxOverlapHit));
|
||||
*count = bodyCount;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PhysicsWrappers::OverlapCapsule(const glm::vec3& origin, float radius, float halfHeight, std::array<physx::PxOverlapHit, OVERLAP_MAX_COLLIDERS>& buffer, uint32_t* count)
|
||||
{
|
||||
const physx::PxScene* scene = static_cast<physx::PxScene*>(Physics3D::GetPhysicsScene());
|
||||
|
||||
memset(s_OverlapBuffer, 0, sizeof(s_OverlapBuffer));
|
||||
physx::PxOverlapBuffer buf(s_OverlapBuffer, OVERLAP_MAX_COLLIDERS);
|
||||
const auto geometry = physx::PxCapsuleGeometry(radius, halfHeight);
|
||||
const physx::PxTransform pose = ToPhysXTransform(glm::translate(glm::mat4(1.0F), origin));
|
||||
|
||||
const bool result = scene->overlap(geometry, pose, buf);
|
||||
|
||||
if (result)
|
||||
{
|
||||
const uint32_t bodyCount = buf.nbTouches >= OVERLAP_MAX_COLLIDERS ? OVERLAP_MAX_COLLIDERS : buf.nbTouches;
|
||||
memcpy(buffer.data(), buf.touches, bodyCount * sizeof(physx::PxOverlapHit));
|
||||
*count = bodyCount;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PhysicsWrappers::Initialize()
|
||||
{
|
||||
PM_CORE_ASSERT(!s_Foundation, "PXPhysicsWrappers::Initializer shouldn't be called more than once!");
|
||||
|
||||
s_Foundation = PxCreateFoundation(PX_PHYSICS_VERSION, s_Allocator, s_ErrorCallback);
|
||||
PM_CORE_ASSERT(s_Foundation, "PxCreateFoundation Failed!");
|
||||
|
||||
#if PHYSX_DEBUGGER
|
||||
#ifdef PHYSX_DEBUGGER
|
||||
s_VisualDebugger = PxCreatePvd(*s_Foundation);
|
||||
ConnectPVD();
|
||||
#endif
|
||||
@ -242,16 +386,16 @@ namespace Prism
|
||||
PM_CORE_ASSERT(s_Physics, "PxCreatePhysics Failed!");
|
||||
}
|
||||
|
||||
void PxPhysicsWrappers::Shutdown()
|
||||
void PhysicsWrappers::Shutdown()
|
||||
{
|
||||
s_Physics->release();
|
||||
s_Foundation->release();
|
||||
}
|
||||
|
||||
bool PxPhysicsWrappers::ConnectPVD()
|
||||
bool PhysicsWrappers::ConnectPVD()
|
||||
{
|
||||
bool isConnect = false;
|
||||
#if PHYSX_DEBUGGER
|
||||
#ifdef PHYSX_DEBUGGER
|
||||
physx::PxPvdTransport* transport = physx::PxDefaultPvdSocketTransportCreate("localhost", 5425, 10);
|
||||
if (s_VisualDebugger->isConnected())
|
||||
{
|
||||
@ -263,14 +407,14 @@ namespace Prism
|
||||
return isConnect;
|
||||
}
|
||||
|
||||
bool PxPhysicsWrappers::IsPVDConnected()
|
||||
bool PhysicsWrappers::IsPVDConnected()
|
||||
{
|
||||
return s_VisualDebugger->isConnected();
|
||||
}
|
||||
|
||||
void PxPhysicsWrappers::DisconnectPVD()
|
||||
void PhysicsWrappers::DisconnectPVD()
|
||||
{
|
||||
#if PHYSX_DEBUGGER
|
||||
#ifdef PHYSX_DEBUGGER
|
||||
if (s_VisualDebugger->isConnected(false))
|
||||
{
|
||||
s_VisualDebugger->disconnect();
|
||||
@ -2,37 +2,56 @@
|
||||
// Created by sfd on 25-12-20.
|
||||
//
|
||||
|
||||
#ifndef PXPHYSICSWRAPPERS_H
|
||||
#define PXPHYSICSWRAPPERS_H
|
||||
#ifndef PHYSICSWRAPPERS_H
|
||||
#define PHYSICSWRAPPERS_H
|
||||
|
||||
#include "PhysicsUtils.h"
|
||||
#include "Prism/Scene/Components.h"
|
||||
|
||||
#define OVERLAP_MAX_COLLIDERS 10
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
struct RaycastHit;
|
||||
struct SceneParams;
|
||||
|
||||
class PxPhysicsWrappers
|
||||
class PhysicsErrorCallback final : public physx::PxErrorCallback
|
||||
{
|
||||
public:
|
||||
void reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line) override;
|
||||
};
|
||||
|
||||
class PhysicsWrappers
|
||||
{
|
||||
public:
|
||||
static physx::PxScene* CreateScene(const SceneParams& sceneParams);
|
||||
static physx::PxRigidActor* CreateActor(const RigidBodyComponent& rigidbody, const glm::mat4& transform);
|
||||
static void SetCollisionFilters(const physx::PxRigidActor& actor, uint32_t actorGroup, uint32_t filters);
|
||||
static void SetCollisionFilters(const physx::PxRigidActor& actor, uint32_t physicsLayer);
|
||||
|
||||
static void AddBoxCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const BoxColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
|
||||
static void AddSphereCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const SphereColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
|
||||
static void AddCapsuleCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const CapsuleColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
|
||||
static void AddMeshCollider(::physx::PxRigidActor& actor, const ::physx::PxMaterial& material, ::Prism::MeshColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
|
||||
|
||||
|
||||
static physx::PxConvexMesh* CreateConvexMesh(MeshColliderComponent& collider);
|
||||
|
||||
|
||||
static physx::PxMaterial* CreateMaterial(const PhysicsMaterialComponent& material);
|
||||
static bool Raycast(const glm::vec3& origin, const glm::vec3& direction, float maxDistance, RaycastHit* hit);
|
||||
/*
|
||||
static bool OverlapBox(const glm::vec3& origin, const glm::vec3& halfSize, std::vector<physx::PxOverlapHit>& buffer);
|
||||
static bool OverlapSphere(const glm::vec3& origin, float radius, std::vector<physx::PxOverlapHit>& buffer);
|
||||
*/
|
||||
static bool OverlapBox(const glm::vec3& origin, const glm::vec3& halfSize, std::array<physx::PxOverlapHit, OVERLAP_MAX_COLLIDERS>& buffer, uint32_t* count);
|
||||
static bool OverlapCapsule(const glm::vec3& origin, float radius, float halfHeight, std::array<physx::PxOverlapHit, OVERLAP_MAX_COLLIDERS>& buffer, uint32_t* count);
|
||||
static bool OverlapSphere(const glm::vec3& origin, float radius, std::array<physx::PxOverlapHit, OVERLAP_MAX_COLLIDERS>& buffer, uint32_t* count);
|
||||
|
||||
private:
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
|
||||
|
||||
static bool ConnectPVD();
|
||||
static bool IsPVDConnected();
|
||||
static void DisconnectPVD();
|
||||
@ -43,4 +62,4 @@ namespace Prism
|
||||
}
|
||||
|
||||
|
||||
#endif //PXPHYSICSWRAPPERS_H
|
||||
#endif //PHYSICSWRAPPERS_H
|
||||
@ -17,11 +17,12 @@ namespace Prism
|
||||
const auto state = glfwGetKey(static_cast<GLFWwindow*>(window.GetNativeWindow()), static_cast<uint32_t>(keycode));
|
||||
return state == GLFW_PRESS || state == GLFW_REPEAT;
|
||||
}
|
||||
bool Input::IsMouseButtonPressed(int button)
|
||||
|
||||
bool Input::IsMouseButtonPressed(MouseButton button)
|
||||
{
|
||||
const auto& window = dynamic_cast<WindowsWindow&>(Application::Get().GetWindow());
|
||||
|
||||
const auto state = glfwGetMouseButton(static_cast<GLFWwindow*>(window.GetNativeWindow()), button);
|
||||
const auto state = glfwGetMouseButton(static_cast<GLFWwindow*>(window.GetNativeWindow()), static_cast<int>(button));
|
||||
return state == GLFW_PRESS;
|
||||
}
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ namespace Prism
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<Index> indices;
|
||||
|
||||
constexpr float latitudeBands = 30;
|
||||
constexpr uint32_t latitudeBands = 30;
|
||||
constexpr float longitudeBands = 30;
|
||||
|
||||
for (float latitude = 0.0f; latitude <= latitudeBands; latitude++)
|
||||
@ -77,10 +77,10 @@ namespace Prism
|
||||
|
||||
for (uint32_t latitude = 0; latitude < latitudeBands; latitude++)
|
||||
{
|
||||
for (uint32_t longitude = 0; longitude < longitudeBands; longitude++)
|
||||
for (uint32_t longitude = 0; longitude < static_cast<uint32_t>(longitudeBands); longitude++)
|
||||
{
|
||||
const uint32_t first = (latitude * (longitudeBands + 1)) + longitude;
|
||||
const uint32_t second = first + longitudeBands + 1;
|
||||
const uint32_t first = (latitude * (static_cast<uint32_t>(longitudeBands) + 1)) + longitude;
|
||||
const uint32_t second = first + static_cast<uint32_t>(longitudeBands) + 1;
|
||||
|
||||
indices.push_back({ first, second, first + 1 });
|
||||
indices.push_back({ second, second + 1, first + 1 });
|
||||
@ -120,11 +120,11 @@ namespace Prism
|
||||
calcV += 180.0f / (float)segments;
|
||||
}
|
||||
|
||||
float yOffset = (height - (radius * 2.0f)) * 0.5f;
|
||||
float yOffset = height * 0.5f;
|
||||
if (yOffset < 0.0f)
|
||||
yOffset = 0.0f;
|
||||
|
||||
int top = glm::ceil(pointCount * 0.5f);
|
||||
int top = static_cast<int32_t>(glm::ceil(pointCount * 0.5f));
|
||||
|
||||
for (int y = 0; y < top; y++)
|
||||
{
|
||||
@ -136,7 +136,7 @@ namespace Prism
|
||||
}
|
||||
}
|
||||
|
||||
int bottom = glm::floor(pointCount * 0.5f);
|
||||
int bottom = static_cast<int32_t>(glm::floor(pointCount * 0.5f));
|
||||
|
||||
for (int y = bottom; y < pointCount; y++)
|
||||
{
|
||||
|
||||
@ -156,6 +156,7 @@ namespace Prism
|
||||
Type BodyType;
|
||||
float Mass = 1.0f;
|
||||
bool IsKinematic = false;
|
||||
uint32_t Layer = 0;
|
||||
|
||||
bool LockPositionX = false;
|
||||
bool LockPositionY = false;
|
||||
|
||||
@ -49,6 +49,7 @@ namespace Prism
|
||||
m_Scene->m_Registry.remove<T>(m_EntityHandle);
|
||||
}
|
||||
|
||||
const std::string& Tag() const { return m_Scene->m_Registry.get<TagComponent>(m_EntityHandle).Tag; }
|
||||
glm::mat4& Transform() { return m_Scene->m_Registry.get<TransformComponent>(m_EntityHandle); }
|
||||
const glm::mat4& Transform() const { return m_Scene->m_Registry.get<TransformComponent>(m_EntityHandle); }
|
||||
|
||||
|
||||
@ -19,7 +19,8 @@
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "Prism/Physics/PxPhysicsWrappers.h"
|
||||
#include "Prism/Physics/PhysicsLayer.h"
|
||||
#include "Prism/Physics/PhysicsWrappers.h"
|
||||
#include "Prism/Renderer/Meshfactory.h"
|
||||
|
||||
namespace YAML
|
||||
@ -340,6 +341,7 @@ namespace Prism
|
||||
out << YAML::Key << "BodyType" << YAML::Value << (int)rigidbodyComponent.BodyType;
|
||||
out << YAML::Key << "Mass" << YAML::Value << rigidbodyComponent.Mass;
|
||||
out << YAML::Key << "IsKinematic" << YAML::Value << rigidbodyComponent.IsKinematic;
|
||||
out << YAML::Key << "Layer" << YAML::Value << rigidbodyComponent.Layer;
|
||||
|
||||
out << YAML::Key << "Constraints";
|
||||
out << YAML::BeginMap; // Constraints
|
||||
@ -456,6 +458,29 @@ namespace Prism
|
||||
SerializeEntity(out, entity);
|
||||
});
|
||||
out << YAML::EndSeq;
|
||||
|
||||
out << YAML::Key << "PhysicsLayers";
|
||||
out << YAML::Value << YAML::BeginSeq;
|
||||
for (uint32_t i = 0; i < PhysicsLayerManager::GetLayerCount(); i++)
|
||||
{
|
||||
const PhysicsLayer& layer = PhysicsLayerManager::GetLayer(i);
|
||||
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "Name" << YAML::Value << layer.Name;
|
||||
|
||||
out << YAML::Key << "CollidesWith" << YAML::Value;
|
||||
out << YAML::BeginSeq;
|
||||
for (const auto& collidingLayer : PhysicsLayerManager::GetLayerCollisions(layer.LayerID))
|
||||
{
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "Name" << YAML::Value << collidingLayer.Name;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
out << YAML::EndSeq;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
out << YAML::EndSeq;
|
||||
|
||||
out << YAML::EndMap;
|
||||
|
||||
std::ofstream fout(filepath);
|
||||
@ -661,6 +686,7 @@ namespace Prism
|
||||
component.BodyType = (RigidBodyComponent::Type)rigidBodyComponent["BodyType"].as<int>();
|
||||
component.Mass = rigidBodyComponent["Mass"].as<float>();
|
||||
component.IsKinematic = rigidBodyComponent["IsKinematic"] ? rigidBodyComponent["IsKinematic"].as<bool>() : false;
|
||||
component.Layer = rigidBodyComponent["Layer"] ? rigidBodyComponent["Layer"].as<uint32_t>() : 0;
|
||||
|
||||
component.LockPositionX = rigidBodyComponent["Constraints"]["LockPositionX"].as<bool>();
|
||||
component.LockPositionY = rigidBodyComponent["Constraints"]["LockPositionY"].as<bool>();
|
||||
@ -710,12 +736,37 @@ namespace Prism
|
||||
auto meshPath = meshColliderComponent["AssetPath"].as<std::string>();
|
||||
auto& component = deserializedEntity.AddComponent<MeshColliderComponent>(Ref<Mesh>::Create(meshPath));
|
||||
component.IsTrigger = meshColliderComponent["IsTrigger"] ? meshColliderComponent["IsTrigger"].as<bool>() : false;
|
||||
PxPhysicsWrappers::CreateConvexMesh(component);
|
||||
PhysicsWrappers::CreateConvexMesh(component);
|
||||
|
||||
PM_CORE_INFO(" Mesh Collider Asset Path: {0}", meshPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto physicsLayers = data["PhysicsLayers"])
|
||||
{
|
||||
PhysicsLayerManager::ClearLayers();
|
||||
|
||||
for (auto layer : physicsLayers)
|
||||
{
|
||||
PhysicsLayerManager::AddLayer(layer["Name"].as<std::string>(), false);
|
||||
}
|
||||
|
||||
for (auto layer : physicsLayers)
|
||||
{
|
||||
const PhysicsLayer& layerInfo = PhysicsLayerManager::GetLayer(layer["Name"].as<std::string>());
|
||||
|
||||
if (auto collidesWith = layer["CollidesWith"])
|
||||
{
|
||||
for (auto collisionLayer : collidesWith)
|
||||
{
|
||||
const auto& otherLayer = PhysicsLayerManager::GetLayer(collisionLayer["Name"].as<std::string>());
|
||||
PhysicsLayerManager::SetLayerCollision(layerInfo.LayerID, otherLayer.LayerID, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
#include <mono/metadata/object.h>
|
||||
#include <mono/metadata/reflection.h>
|
||||
#include <mono/metadata/mono-debug.h>
|
||||
#include <mono/metadata/debug-helpers.h>
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
@ -575,6 +574,85 @@ namespace Prism
|
||||
}
|
||||
}
|
||||
|
||||
MonoObject* ScriptEngine::Construct(const std::string& fullName, bool callConstructor, void** parameters)
|
||||
{
|
||||
std::string namespaceName;
|
||||
std::string className;
|
||||
std::string parameterList;
|
||||
|
||||
if (fullName.find('.') != std::string::npos)
|
||||
{
|
||||
namespaceName = fullName.substr(0, fullName.find_first_of('.'));
|
||||
className = fullName.substr(fullName.find_first_of('.') + 1, (fullName.find_first_of(':') - fullName.find_first_of('.')) - 1);
|
||||
|
||||
}
|
||||
|
||||
if (fullName.find(':') != std::string::npos)
|
||||
{
|
||||
parameterList = fullName.substr(fullName.find_first_of(':'));
|
||||
}
|
||||
|
||||
MonoClass* clazz = mono_class_from_name(s_CoreAssemblyImage, namespaceName.c_str(), className.c_str());
|
||||
if (!clazz) {
|
||||
PM_CORE_FATAL("Class not found: {0}.{1}", namespaceName, className);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MonoObject* obj = mono_object_new(mono_domain_get(), clazz);
|
||||
|
||||
|
||||
if (callConstructor)
|
||||
{
|
||||
MonoMethodDesc* desc = mono_method_desc_new(parameterList.c_str(), NULL);
|
||||
MonoMethod* constructor = mono_method_desc_search_in_class(desc, clazz);
|
||||
|
||||
if (!constructor) {
|
||||
PM_CORE_ERROR("Constructor not found: {0}", fullName);
|
||||
|
||||
void* iter = nullptr;
|
||||
MonoMethod* method;
|
||||
while ((method = mono_class_get_methods(clazz, &iter)) != nullptr) {
|
||||
PM_CORE_DEBUG("Found method: {0}",mono_method_full_name(method, true));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
MonoObject* exception = nullptr;
|
||||
mono_runtime_invoke(constructor, obj, parameters, &exception);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string, MonoClass*> s_Classes;
|
||||
|
||||
MonoClass* ScriptEngine::GetCoreClass(const std::string& fullName)
|
||||
{
|
||||
if (s_Classes.find(fullName) != s_Classes.end())
|
||||
return s_Classes[fullName];
|
||||
|
||||
std::string namespaceName;
|
||||
std::string className;
|
||||
|
||||
if (fullName.find('.') != std::string::npos)
|
||||
{
|
||||
namespaceName = fullName.substr(0, fullName.find_last_of('.'));
|
||||
className = fullName.substr(fullName.find_last_of('.') + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
className = fullName;
|
||||
}
|
||||
|
||||
MonoClass* monoClass = mono_class_from_name(s_CoreAssemblyImage, namespaceName.c_str(), className.c_str());
|
||||
if (!monoClass)
|
||||
std::cout << "mono_class_from_name failed" << std::endl;
|
||||
|
||||
s_Classes[fullName] = monoClass;
|
||||
|
||||
return monoClass;
|
||||
}
|
||||
|
||||
bool ScriptEngine::IsEntityModuleValid(Entity entity)
|
||||
{
|
||||
return entity.HasComponent<ScriptComponent>() && ModuleExists(entity.GetComponent<ScriptComponent>().ModuleName);
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
extern "C" {
|
||||
typedef struct _MonoObject MonoObject;
|
||||
typedef struct _MonoClassField MonoClassField;
|
||||
typedef struct _MonoClass MonoClass;
|
||||
}
|
||||
|
||||
namespace Prism
|
||||
@ -126,6 +127,9 @@ namespace Prism
|
||||
static void OnTriggerBegin(Entity entityID);
|
||||
static void OnTriggerEnd(Entity entityID);
|
||||
|
||||
static MonoObject* Construct(const std::string& fullName, bool callConstructor = true, void** parameters = nullptr);
|
||||
static MonoClass* GetCoreClass(const std::string& fullName);
|
||||
|
||||
static bool IsEntityModuleValid(Entity entity);
|
||||
|
||||
static void OnScriptComponentDestroyed(const UUID &sceneID, const UUID &entityID);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
#include "ScriptEngineRegistry.h"
|
||||
|
||||
#include "ScriptWarppers.h"
|
||||
#include "ScriptWrappers.h"
|
||||
#include "Prism/Scene/Entity.h"
|
||||
|
||||
#include "mono/metadata/reflection.h"
|
||||
@ -51,6 +51,15 @@ namespace Prism
|
||||
|
||||
mono_add_internal_call("Prism.Noise::PerlinNoise_Native", (const void*)Prism::Script::Prism_Noise_PerlinNoise);
|
||||
|
||||
mono_add_internal_call("Prism.Physics::Raycast_Native", (const void*)Prism::Script::Prism_Physics_Raycast);
|
||||
mono_add_internal_call("Prism.Physics::OverlapBox_Native", (const void*)Prism::Script::Prism_Physics_OverlapBox);
|
||||
mono_add_internal_call("Prism.Physics::OverlapCapsule_Native", (const void*)Prism::Script::Prism_Physics_OverlapCapsule);
|
||||
mono_add_internal_call("Prism.Physics::OverlapSphere_Native", (const void*)Prism::Script::Prism_Physics_OverlapSphere);
|
||||
mono_add_internal_call("Prism.Physics::OverlapBoxNonAlloc_Native", (const void*)Prism::Script::Prism_Physics_OverlapBoxNonAlloc);
|
||||
mono_add_internal_call("Prism.Physics::OverlapCapsuleNonAlloc_Native", (const void*)Prism::Script::Prism_Physics_OverlapCapsuleNonAlloc);
|
||||
mono_add_internal_call("Prism.Physics::OverlapSphereNonAlloc_Native", (const void*)Prism::Script::Prism_Physics_OverlapSphereNonAlloc);
|
||||
|
||||
|
||||
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.TransformComponent::GetRelativeDirection_Native", (const void*)Prism::Script::Prism_TransformComponent_GetRelativeDirection);
|
||||
@ -77,6 +86,7 @@ namespace Prism
|
||||
|
||||
// Input
|
||||
mono_add_internal_call("Prism.Input::IsKeyPressed_Native", (const void*)Prism::Script::Prism_Input_IsKeyPressed);
|
||||
mono_add_internal_call("Prism.Input::IsMouseButtonPressed_Native", (const void*)Prism::Script::Prism_Input_IsMouseButtonPressed);
|
||||
mono_add_internal_call("Prism.Input::GetMousePosition_Native", (const void*)Prism::Script::Prism_Input_GetMousePosition);
|
||||
mono_add_internal_call("Prism.Input::SetCursorMode_Native", (const void*)Prism::Script::Prism_Input_SetCursorMode);
|
||||
mono_add_internal_call("Prism.Input::GetCursorMode_Native", (const void*)Prism::Script::Prism_Input_GetCursorMode);
|
||||
@ -97,6 +107,9 @@ namespace Prism
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::GetLinearVelocity_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_GetLinearVelocity);
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::SetLinearVelocity_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_SetLinearVelocity);
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::Rotate_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_Rotate);
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::GetLayer_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_GetLayer);
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::GetMass_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_GetMass);
|
||||
mono_add_internal_call("Prism.RigidBodyComponent::SetMass_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_SetMass);
|
||||
|
||||
// Material
|
||||
mono_add_internal_call("Prism.Material::Destructor_Native", (const void*)Prism::Script::Prism_Material_Destructor);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Created by sfd on 25-12-6.
|
||||
//
|
||||
|
||||
#include "ScriptWarppers.h"
|
||||
#include "ScriptWrappers.h"
|
||||
|
||||
#include "ScriptEngine.h"
|
||||
#include "box2d/box2d.h"
|
||||
@ -22,6 +22,8 @@
|
||||
#include "PxRigidDynamic.h"
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
#include "Prism/Physics/PhysicsUtils.h"
|
||||
#include "Prism/Physics/PhysicsWrappers.h"
|
||||
#include <mono/metadata/appdomain.h>
|
||||
|
||||
namespace Prism {
|
||||
extern std::unordered_map<MonoType*, std::function<bool(Entity&)>> s_HasComponentFuncs;
|
||||
@ -71,6 +73,11 @@ namespace Prism { namespace Script {
|
||||
return Input::IsKeyPressed(key);
|
||||
}
|
||||
|
||||
bool Prism_Input_IsMouseButtonPressed(const MouseButton button)
|
||||
{
|
||||
return Input::IsMouseButtonPressed(button);
|
||||
}
|
||||
|
||||
void Prism_Input_GetMousePosition(glm::vec2* outPosition)
|
||||
{
|
||||
auto [x, y] = Input::GetMousePosition();
|
||||
@ -87,10 +94,189 @@ namespace Prism { namespace Script {
|
||||
return Input::GetCursorMode();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
bool Prism_Physics_Raycast(const glm::vec3* origin, const glm::vec3* direction, const float maxDistance, RaycastHit* hit)
|
||||
{
|
||||
return PhysicsWrappers::Raycast(*origin, *direction, maxDistance, hit);
|
||||
}
|
||||
|
||||
// Helper function for the Overlap functions below
|
||||
static void AddCollidersToArray(MonoArray* array, const std::array<physx::PxOverlapHit, OVERLAP_MAX_COLLIDERS>& hits, const uint32_t count)
|
||||
{
|
||||
uint32_t arrayIndex = 0;
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
Entity& entity = *static_cast<Entity*>(hits[i].actor->userData);
|
||||
|
||||
if (entity.HasComponent<BoxColliderComponent>())
|
||||
{
|
||||
auto& boxCollider = entity.GetComponent<BoxColliderComponent>();
|
||||
|
||||
UUID uuid = entity.GetUUID();
|
||||
void* data[] = {
|
||||
&uuid,
|
||||
&boxCollider.IsTrigger,
|
||||
&boxCollider.Size,
|
||||
&boxCollider.Offset
|
||||
};
|
||||
|
||||
MonoObject* obj = ScriptEngine::Construct("Prism.BoxCollider:.ctor(ulong,bool,Vec3,Vec3)", true, data);
|
||||
mono_array_set(array, MonoObject*, arrayIndex++, obj);
|
||||
}
|
||||
|
||||
if (entity.HasComponent<SphereColliderComponent>())
|
||||
{
|
||||
auto& sphereCollider = entity.GetComponent<SphereColliderComponent>();
|
||||
|
||||
UUID uuid = entity.GetUUID();
|
||||
void* data[] = {
|
||||
&uuid,
|
||||
&sphereCollider.IsTrigger,
|
||||
&sphereCollider.Radius
|
||||
};
|
||||
|
||||
MonoObject* obj = ScriptEngine::Construct("Prism.SphereCollider:.ctor(ulong,bool,single)", true, data);
|
||||
mono_array_set(array, MonoObject*, arrayIndex++, obj);
|
||||
}
|
||||
|
||||
if (entity.HasComponent<CapsuleColliderComponent>())
|
||||
{
|
||||
auto& capsuleCollider = entity.GetComponent<CapsuleColliderComponent>();
|
||||
|
||||
UUID uuid = entity.GetUUID();
|
||||
void* data[] = {
|
||||
&uuid,
|
||||
&capsuleCollider.IsTrigger,
|
||||
&capsuleCollider.Radius,
|
||||
&capsuleCollider.Height
|
||||
};
|
||||
|
||||
MonoObject* obj = ScriptEngine::Construct("Prism.CapsuleCollider:.ctor(ulong,bool,single,single)", true, data);
|
||||
mono_array_set(array, MonoObject*, arrayIndex++, obj);
|
||||
}
|
||||
|
||||
if (entity.HasComponent<MeshColliderComponent>())
|
||||
{
|
||||
auto& meshCollider = entity.GetComponent<MeshColliderComponent>();
|
||||
|
||||
auto mesh = new Ref<Mesh>(meshCollider.CollisionMesh);
|
||||
UUID uuid = entity.GetUUID();
|
||||
|
||||
void* data[] = {
|
||||
&uuid,
|
||||
&meshCollider.IsTrigger,
|
||||
&mesh
|
||||
};
|
||||
|
||||
MonoObject* obj = ScriptEngine::Construct("Prism.MeshCollider:.ctor(ulong,bool,intptr)", true, data);
|
||||
mono_array_set(array, MonoObject*, arrayIndex++, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::array<physx::PxOverlapHit, OVERLAP_MAX_COLLIDERS> s_OverlapBuffer;
|
||||
|
||||
MonoArray* Prism_Physics_OverlapBox(const glm::vec3* origin, const glm::vec3* halfSize)
|
||||
{
|
||||
MonoArray* outColliders = nullptr;
|
||||
memset(s_OverlapBuffer.data(), 0, OVERLAP_MAX_COLLIDERS * sizeof(physx::PxOverlapHit));
|
||||
|
||||
uint32_t count;
|
||||
if (PhysicsWrappers::OverlapBox(*origin, *halfSize, s_OverlapBuffer, &count))
|
||||
{
|
||||
outColliders = mono_array_new(mono_domain_get(), ScriptEngine::GetCoreClass("Prism.Collider"), count);
|
||||
AddCollidersToArray(outColliders, s_OverlapBuffer, count);
|
||||
}
|
||||
|
||||
return outColliders;
|
||||
}
|
||||
|
||||
MonoArray* Prism_Physics_OverlapCapsule(const glm::vec3* origin, const float radius, const float halfHeight)
|
||||
{
|
||||
MonoArray* outColliders = nullptr;
|
||||
memset(s_OverlapBuffer.data(), 0, OVERLAP_MAX_COLLIDERS * sizeof(physx::PxOverlapHit));
|
||||
|
||||
uint32_t count;
|
||||
if (PhysicsWrappers::OverlapCapsule(*origin, radius, halfHeight, s_OverlapBuffer, &count))
|
||||
{
|
||||
outColliders = mono_array_new(mono_domain_get(), ScriptEngine::GetCoreClass("Prism.Collider"), count);
|
||||
AddCollidersToArray(outColliders, s_OverlapBuffer, count);
|
||||
}
|
||||
|
||||
return outColliders;
|
||||
}
|
||||
|
||||
MonoArray* Prism_Physics_OverlapSphere(const glm::vec3* origin, const float radius)
|
||||
{
|
||||
MonoArray* outColliders = nullptr;
|
||||
memset(s_OverlapBuffer.data(), 0, OVERLAP_MAX_COLLIDERS * sizeof(physx::PxOverlapHit));
|
||||
|
||||
uint32_t count;
|
||||
if (PhysicsWrappers::OverlapSphere(*origin, radius, s_OverlapBuffer, &count))
|
||||
{
|
||||
outColliders = mono_array_new(mono_domain_get(), ScriptEngine::GetCoreClass("Prism.Collider"), count);
|
||||
AddCollidersToArray(outColliders, s_OverlapBuffer, count);
|
||||
}
|
||||
|
||||
return outColliders;
|
||||
}
|
||||
|
||||
int32_t Prism_Physics_OverlapBoxNonAlloc(const glm::vec3* origin, const glm::vec3* halfSize, MonoArray* outColliders)
|
||||
{
|
||||
memset(s_OverlapBuffer.data(), 0, OVERLAP_MAX_COLLIDERS * sizeof(physx::PxOverlapHit));
|
||||
|
||||
const uint64_t arrayLength = mono_array_length(outColliders);
|
||||
|
||||
uint32_t count = 0;
|
||||
if (PhysicsWrappers::OverlapBox(*origin, *halfSize, s_OverlapBuffer, &count))
|
||||
{
|
||||
if (count > arrayLength)
|
||||
count = static_cast<uint32_t>(arrayLength);
|
||||
|
||||
AddCollidersToArray(outColliders, s_OverlapBuffer, count);
|
||||
}
|
||||
|
||||
return static_cast<int32_t>(count);
|
||||
}
|
||||
|
||||
int32_t Prism_Physics_OverlapCapsuleNonAlloc(const glm::vec3* origin, const float radius, const float halfHeight, MonoArray* outColliders)
|
||||
{
|
||||
memset(s_OverlapBuffer.data(), 0, OVERLAP_MAX_COLLIDERS * sizeof(physx::PxOverlapHit));
|
||||
|
||||
const uint64_t arrayLength = mono_array_length(outColliders);
|
||||
|
||||
uint32_t count = 0;
|
||||
if (PhysicsWrappers::OverlapCapsule(*origin, radius, halfHeight, s_OverlapBuffer, &count))
|
||||
{
|
||||
if (count > arrayLength)
|
||||
count = static_cast<uint32_t>(arrayLength);
|
||||
|
||||
AddCollidersToArray(outColliders, s_OverlapBuffer, count);
|
||||
}
|
||||
|
||||
return static_cast<int32_t>(count);
|
||||
}
|
||||
|
||||
int32_t Prism_Physics_OverlapSphereNonAlloc(const glm::vec3* origin, const float radius, MonoArray* outColliders)
|
||||
{
|
||||
memset(s_OverlapBuffer.data(), 0, OVERLAP_MAX_COLLIDERS * sizeof(physx::PxOverlapHit));
|
||||
|
||||
const uint64_t arrayLength = mono_array_length(outColliders);
|
||||
|
||||
uint32_t count;
|
||||
if (PhysicsWrappers::OverlapSphere(*origin, radius, s_OverlapBuffer, &count))
|
||||
{
|
||||
if (count > arrayLength)
|
||||
count = static_cast<uint32_t>(arrayLength);
|
||||
|
||||
AddCollidersToArray(outColliders, s_OverlapBuffer, count);
|
||||
}
|
||||
|
||||
return static_cast<int32_t>(count);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Entity //////////////////////////////////////////////////////
|
||||
// Entity //
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void Prism_Entity_GetTransform(const uint64_t entityID, glm::mat4* outTransform)
|
||||
@ -117,53 +303,6 @@ namespace Prism { namespace Script {
|
||||
memcpy(glm::value_ptr(transformComponent.Transform), inTransform, sizeof(glm::mat4));
|
||||
}
|
||||
|
||||
/*
|
||||
void Prism_Entity_GetForwardDirection(const uint64_t entityID, glm::vec3* outForward)
|
||||
{
|
||||
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);
|
||||
*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();
|
||||
@ -212,7 +351,7 @@ namespace Prism { namespace Script {
|
||||
const auto& transformComponent = entity.GetComponent<TransformComponent>();
|
||||
|
||||
auto [position, rotation, scale] = GetTransformDecomposition(transformComponent.Transform);
|
||||
*outDirection = glm::rotate(glm::normalize(rotation), *inAbsoluteDirection);
|
||||
*outDirection = glm::rotate(rotation, *inAbsoluteDirection);
|
||||
}
|
||||
|
||||
void Prism_TransformComponent_GetRotation(const uint64_t entityID, glm::vec3* outRotation)
|
||||
@ -438,27 +577,77 @@ namespace Prism { namespace Script {
|
||||
dynamicActor->setGlobalPose(transform);
|
||||
}
|
||||
|
||||
uint32_t Prism_RigidBodyComponent_GetLayer(const uint64_t entityID)
|
||||
{
|
||||
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>();
|
||||
return component.Layer;
|
||||
}
|
||||
|
||||
float Prism_RigidBodyComponent_GetMass(const uint64_t entityID)
|
||||
{
|
||||
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>();
|
||||
|
||||
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
|
||||
const physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||
PM_CORE_ASSERT(dynamicActor);
|
||||
|
||||
return dynamicActor->getMass();
|
||||
}
|
||||
|
||||
void Prism_RigidBodyComponent_SetMass(const uint64_t entityID, const float mass)
|
||||
{
|
||||
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>());
|
||||
auto& component = entity.GetComponent<RigidBodyComponent>();
|
||||
|
||||
auto* actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
|
||||
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||
PM_CORE_ASSERT(dynamicActor);
|
||||
|
||||
component.Mass = mass;
|
||||
physx::PxRigidBodyExt::updateMassAndInertia(*dynamicActor, mass);
|
||||
}
|
||||
|
||||
|
||||
Ref<Mesh>* Prism_Mesh_Constructor(MonoString* filepath)
|
||||
{
|
||||
return new Ref<Mesh>(new Mesh(mono_string_to_utf8(filepath)));
|
||||
}
|
||||
|
||||
void Prism_Mesh_Destructor(Ref<Mesh>* _this)
|
||||
void Prism_Mesh_Destructor(const Ref<Mesh>* _this)
|
||||
{
|
||||
const Ref<Mesh>* instance = (Ref<Mesh>*)_this;
|
||||
const Ref<Mesh>* instance = _this;
|
||||
delete _this;
|
||||
}
|
||||
|
||||
Ref<Material>* Prism_Mesh_GetMaterial(Ref<Mesh>* inMesh)
|
||||
{
|
||||
Ref<Mesh>& mesh = *(Ref<Mesh>*)inMesh;
|
||||
Ref<Mesh>& mesh = *inMesh;
|
||||
return new Ref<Material>(mesh->GetMaterial());
|
||||
}
|
||||
|
||||
Ref<MaterialInstance>* Prism_Mesh_GetMaterialByIndex(Ref<Mesh>* inMesh, const int index)
|
||||
{
|
||||
Ref<Mesh>& mesh = *(Ref<Mesh>*)inMesh;
|
||||
Ref<Mesh>& mesh = *inMesh;
|
||||
const auto& materials = mesh->GetMaterials();
|
||||
|
||||
PM_CORE_ASSERT(index < materials.size());
|
||||
@ -467,7 +656,7 @@ namespace Prism { namespace Script {
|
||||
|
||||
int Prism_Mesh_GetMaterialCount(Ref<Mesh>* inMesh)
|
||||
{
|
||||
Ref<Mesh>& mesh = *(Ref<Mesh>*)inMesh;
|
||||
Ref<Mesh>& mesh = *inMesh;
|
||||
const auto& materials = mesh->GetMaterials();
|
||||
return (int)materials.size();
|
||||
}
|
||||
@ -494,7 +683,7 @@ namespace Prism { namespace Script {
|
||||
PM_CORE_ASSERT(dataSize <= buffer.Size);
|
||||
// Convert RGBA32F color to RGBA8
|
||||
auto pixels = static_cast<uint8_t*>(buffer.Data);
|
||||
uint32_t index = 0;
|
||||
|
||||
for (uint32_t i = 0; i < instance->GetWidth() * instance->GetHeight(); i++)
|
||||
{
|
||||
const glm::vec4& value = mono_array_get(inData, glm::vec4, i);
|
||||
@ -514,13 +703,13 @@ namespace Prism { namespace Script {
|
||||
|
||||
void Prism_Material_SetFloat(Ref<Material>* _this, MonoString* uniform, const float value)
|
||||
{
|
||||
Ref<Material>& instance = *(Ref<Material>*)_this;
|
||||
Ref<Material>& instance = *_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), value);
|
||||
}
|
||||
|
||||
void Prism_Material_SetTexture(Ref<Material>* _this, MonoString* uniform, const Ref<Texture2D>* texture)
|
||||
{
|
||||
Ref<Material>& instance = *(Ref<Material>*)_this;
|
||||
Ref<Material>& instance = *_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), *texture);
|
||||
}
|
||||
|
||||
@ -531,25 +720,25 @@ namespace Prism { namespace Script {
|
||||
|
||||
void Prism_MaterialInstance_SetFloat(Ref<MaterialInstance>* _this, MonoString* uniform, const float value)
|
||||
{
|
||||
Ref<MaterialInstance>& instance = *(Ref<MaterialInstance>*)_this;
|
||||
Ref<MaterialInstance>& instance = *_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), value);
|
||||
}
|
||||
|
||||
void Prism_MaterialInstance_SetVector3(Ref<MaterialInstance>* _this, MonoString* uniform, const glm::vec3* value)
|
||||
{
|
||||
Ref<MaterialInstance>& instance = *(Ref<MaterialInstance>*)_this;
|
||||
Ref<MaterialInstance>& instance = *_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), *value);
|
||||
}
|
||||
|
||||
void Prism_MaterialInstance_SetVector4(Ref<MaterialInstance> *_this, MonoString *uniform, const glm::vec4 *value)
|
||||
{
|
||||
Ref<MaterialInstance>& instance = *(Ref<MaterialInstance>*)_this;
|
||||
Ref<MaterialInstance>& instance = *_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), *value);
|
||||
}
|
||||
|
||||
void Prism_MaterialInstance_SetTexture(Ref<MaterialInstance>* _this, MonoString* uniform, const Ref<Texture2D>* texture)
|
||||
{
|
||||
Ref<MaterialInstance>& instance = *(Ref<MaterialInstance>*)_this;
|
||||
Ref<MaterialInstance>& instance = *_this;
|
||||
instance->Set(mono_string_to_utf8(uniform), *texture);
|
||||
}
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
// Created by sfd on 25-12-6.
|
||||
//
|
||||
|
||||
#ifndef SCRIPTWARPPERS_H
|
||||
#define SCRIPTWARPPERS_H
|
||||
#ifndef SCRIPTWRAPPERS_H
|
||||
#define SCRIPTWRAPPERS_H
|
||||
#include "Prism/Core/Input.h"
|
||||
#include "Prism/Core/KeyCodes.h"
|
||||
#include "Prism/Core/Ref.h"
|
||||
@ -24,21 +24,26 @@ namespace Prism { namespace Script {
|
||||
|
||||
// Input
|
||||
bool Prism_Input_IsKeyPressed(KeyCode key);
|
||||
bool Prism_Input_IsMouseButtonPressed(MouseButton button);
|
||||
void Prism_Input_GetMousePosition(glm::vec2* outPosition);
|
||||
void Prism_Input_SetCursorMode(CursorMode mode);
|
||||
CursorMode Prism_Input_GetCursorMode();
|
||||
|
||||
// Physics
|
||||
bool Prism_Physics_Raycast(const glm::vec3* origin, const glm::vec3* direction, float maxDistance, RaycastHit* hit);
|
||||
MonoArray* Prism_Physics_OverlapBox(const glm::vec3* origin, const glm::vec3* halfSize);
|
||||
MonoArray* Prism_Physics_OverlapCapsule(const glm::vec3* origin, float radius, float halfHeight);
|
||||
MonoArray* Prism_Physics_OverlapSphere(const glm::vec3* origin, float radius);
|
||||
int32_t Prism_Physics_OverlapBoxNonAlloc(const glm::vec3* origin, const glm::vec3* halfSize, MonoArray* outColliders);
|
||||
int32_t Prism_Physics_OverlapCapsuleNonAlloc(const glm::vec3* origin, float radius, float halfHeight, MonoArray* outColliders);
|
||||
int32_t Prism_Physics_OverlapSphereNonAlloc(const glm::vec3* origin, float radius, MonoArray* outColliders);
|
||||
|
||||
// Entity
|
||||
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_Entity_GetTransform(uint64_t entityID, glm::mat4* outTransform);
|
||||
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_TransformComponent_GetRelativeDirection(uint64_t entityID, glm::vec3* outDirection, const glm::vec3* inAbsoluteDirection);
|
||||
void Prism_TransformComponent_GetRotation(uint64_t entityID,glm::vec3* outRotation);
|
||||
@ -55,6 +60,9 @@ namespace Prism { namespace Script {
|
||||
void Prism_RigidBodyComponent_GetLinearVelocity(uint64_t entityID, glm::vec3* outVelocity);
|
||||
void Prism_RigidBodyComponent_SetLinearVelocity(uint64_t entityID, glm::vec3* velocity);
|
||||
void Prism_RigidBodyComponent_Rotate(uint64_t entityID, glm::vec3* rotation);
|
||||
uint32_t Prism_RigidBodyComponent_GetLayer(uint64_t entityID);
|
||||
float Prism_RigidBodyComponent_GetMass(uint64_t entityID);
|
||||
void Prism_RigidBodyComponent_SetMass(uint64_t entityID, float mass);
|
||||
|
||||
// Renderer
|
||||
// Texture2D
|
||||
@ -75,7 +83,7 @@ namespace Prism { namespace Script {
|
||||
|
||||
// Mesh
|
||||
Ref<Mesh>* Prism_Mesh_Constructor(MonoString* filepath);
|
||||
void Prism_Mesh_Destructor(Ref<Mesh>* _this);
|
||||
void Prism_Mesh_Destructor(const Ref<Mesh>* _this);
|
||||
Ref<Material>* Prism_Mesh_GetMaterial(Ref<Mesh>* inMesh);
|
||||
Ref<MaterialInstance>* Prism_Mesh_GetMaterialByIndex(Ref<Mesh>* inMesh, int index);
|
||||
int Prism_Mesh_GetMaterialCount(Ref<Mesh>* inMesh);
|
||||
@ -87,4 +95,4 @@ namespace Prism { namespace Script {
|
||||
} }
|
||||
|
||||
|
||||
#endif //SCRIPTWARPPERS_H
|
||||
#endif //SCRIPTWRAPPERS_H
|
||||
Reference in New Issue
Block a user