add physX colliders ,add trigger, colliders now can visible, some rotation for cs and native cpp connection
This commit is contained in:
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "glm/gtx/matrix_decompose.hpp"
|
#include "glm/gtx/matrix_decompose.hpp"
|
||||||
#include "Prism/Core/Input.h"
|
#include "Prism/Core/Input.h"
|
||||||
|
#include "Prism/Physics/Physics3D.h"
|
||||||
#include "Prism/Renderer/Renderer2D.h"
|
#include "Prism/Renderer/Renderer2D.h"
|
||||||
#include "Prism/Script/ScriptEngine.h"
|
#include "Prism/Script/ScriptEngine.h"
|
||||||
|
|
||||||
@ -172,7 +173,7 @@ namespace Prism
|
|||||||
m_CheckerboardTex = Texture2D::Create("assets/editor/Checkerboard.tga");
|
m_CheckerboardTex = Texture2D::Create("assets/editor/Checkerboard.tga");
|
||||||
m_PlayButtonTex = Texture2D::Create("assets/editor/PlayButton.png");
|
m_PlayButtonTex = Texture2D::Create("assets/editor/PlayButton.png");
|
||||||
|
|
||||||
m_EditorScene = Ref<Scene>::Create();
|
m_EditorScene = Ref<Scene>::Create("untitled Scene", true);
|
||||||
ScriptEngine::SetSceneContext(m_EditorScene);
|
ScriptEngine::SetSceneContext(m_EditorScene);
|
||||||
m_SceneHierarchyPanel = CreateScope<SceneHierarchyPanel>(m_EditorScene);
|
m_SceneHierarchyPanel = CreateScope<SceneHierarchyPanel>(m_EditorScene);
|
||||||
m_SceneHierarchyPanel->SetSelectionChangedCallback(std::bind(&EditorLayer::SelectEntity, this, std::placeholders::_1));
|
m_SceneHierarchyPanel->SetSelectionChangedCallback(std::bind(&EditorLayer::SelectEntity, this, std::placeholders::_1));
|
||||||
@ -199,7 +200,7 @@ namespace Prism
|
|||||||
if (m_DrawOnTopBoundingBoxes)
|
if (m_DrawOnTopBoundingBoxes)
|
||||||
{
|
{
|
||||||
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
|
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
|
||||||
auto viewProj = m_EditorCamera.GetViewProjection();
|
const auto viewProj = m_EditorCamera.GetViewProjection();
|
||||||
Renderer2D::BeginScene(viewProj, false);
|
Renderer2D::BeginScene(viewProj, false);
|
||||||
// TODO: Renderer::DrawAABB(m_MeshEntity.GetComponent<MeshComponent>(), m_MeshEntity.GetComponent<TransformComponent>());
|
// TODO: Renderer::DrawAABB(m_MeshEntity.GetComponent<MeshComponent>(), m_MeshEntity.GetComponent<TransformComponent>());
|
||||||
Renderer2D::EndScene();
|
Renderer2D::EndScene();
|
||||||
@ -233,7 +234,7 @@ namespace Prism
|
|||||||
const glm::vec3 rotation = glm::eulerAngles(rotationQuat);
|
const glm::vec3 rotation = glm::eulerAngles(rotationQuat);
|
||||||
|
|
||||||
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
|
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
|
||||||
auto viewProj = m_EditorCamera.GetViewProjection();
|
const auto viewProj = m_EditorCamera.GetViewProjection();
|
||||||
Renderer2D::BeginScene(viewProj, false);
|
Renderer2D::BeginScene(viewProj, false);
|
||||||
Renderer2D::DrawRotatedQuad({ translation.x, translation.y }, size * 2.0f, glm::degrees(rotation.z), { 1.0f, 0.0f, 1.0f, 1.0f });
|
Renderer2D::DrawRotatedQuad({ translation.x, translation.y }, size * 2.0f, glm::degrees(rotation.z), { 1.0f, 0.0f, 1.0f, 1.0f });
|
||||||
Renderer2D::EndScene();
|
Renderer2D::EndScene();
|
||||||
@ -360,6 +361,21 @@ namespace Prism
|
|||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Tools"))
|
||||||
|
{
|
||||||
|
// PhysX Debugger
|
||||||
|
if (ImGui::MenuItem("Connect to PVD"))
|
||||||
|
{
|
||||||
|
Physics3D::ConnectPVD();
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("Disconnect from PVD", nullptr, nullptr, Physics3D::IsPVDConnected()))
|
||||||
|
{
|
||||||
|
Physics3D::DisconnectPVD();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,8 +930,8 @@ namespace Prism
|
|||||||
glm::inverse(glm::mat3(entity.Transform()) * glm::mat3(submesh.Transform)) * direction
|
glm::inverse(glm::mat3(entity.Transform()) * glm::mat3(submesh.Transform)) * direction
|
||||||
};
|
};
|
||||||
|
|
||||||
float t;
|
float t = 0;
|
||||||
if (bool intersects = ray.IntersectsAABB(submesh.BoundingBox, t))
|
if (ray.IntersectsAABB(submesh.BoundingBox, t))
|
||||||
{
|
{
|
||||||
const auto& triangleCache = mesh->GetTriangleCache(i);
|
const auto& triangleCache = mesh->GetTriangleCache(i);
|
||||||
for (const auto& triangle : triangleCache)
|
for (const auto& triangle : triangleCache)
|
||||||
@ -1029,10 +1045,10 @@ namespace Prism
|
|||||||
void EditorLayer::OpenScene()
|
void EditorLayer::OpenScene()
|
||||||
{
|
{
|
||||||
const auto& app = Application::Get();
|
const auto& app = Application::Get();
|
||||||
const std::string filepath = app.OpenFile("Hazel Scene (*.hsc)\0*.hsc\0");
|
const std::string filepath = app.OpenFile("Prism Scene (*.hsc)\0*.hsc\0");
|
||||||
if (!filepath.empty())
|
if (!filepath.empty())
|
||||||
{
|
{
|
||||||
const Ref<Scene> newScene = Ref<Scene>::Create();
|
const Ref<Scene> newScene = Ref<Scene>::Create("EditorScene", true);
|
||||||
SceneSerializer serializer(newScene);
|
SceneSerializer serializer(newScene);
|
||||||
serializer.Deserialize(filepath);
|
serializer.Deserialize(filepath);
|
||||||
m_EditorScene = newScene;
|
m_EditorScene = newScene;
|
||||||
@ -1057,7 +1073,7 @@ namespace Prism
|
|||||||
void EditorLayer::SaveSceneAs()
|
void EditorLayer::SaveSceneAs()
|
||||||
{
|
{
|
||||||
auto& app = Application::Get();
|
auto& app = Application::Get();
|
||||||
std::string filepath = app.SaveFile("Hazel Scene (*.hsc)\0*.hsc\0");
|
std::string filepath = app.SaveFile("Prism Scene (*.hsc)\0*.hsc\0");
|
||||||
if (!filepath.empty())
|
if (!filepath.empty())
|
||||||
{
|
{
|
||||||
SceneSerializer serializer(m_EditorScene);
|
SceneSerializer serializer(m_EditorScene);
|
||||||
|
|||||||
BIN
Editor/assets/meshes/Capsule.fbx
Normal file
BIN
Editor/assets/meshes/Capsule.fbx
Normal file
Binary file not shown.
167
Editor/assets/scenes/FPSDemo.scene
Normal file
167
Editor/assets/scenes/FPSDemo.scene
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
Scene: Scene Name
|
||||||
|
Environment:
|
||||||
|
AssetPath: assets/env/pink_sunrise_4k.hdr
|
||||||
|
Light:
|
||||||
|
Direction: [-0.787, -0.73299998, 1]
|
||||||
|
Radiance: [1, 1, 1]
|
||||||
|
Multiplier: 0.514999986
|
||||||
|
Entities:
|
||||||
|
- Entity: 3247025703490125974
|
||||||
|
TagComponent:
|
||||||
|
Tag: Player
|
||||||
|
TransformComponent:
|
||||||
|
Position: [2.80803752, 1.5, 0]
|
||||||
|
Rotation: [1, 0, 0, 0]
|
||||||
|
Scale: [2, 2, 2]
|
||||||
|
ScriptComponent:
|
||||||
|
ModuleName: FPSExample.FPSPlayer
|
||||||
|
StoredFields:
|
||||||
|
- Name: WalkingSpeed
|
||||||
|
Type: 1
|
||||||
|
Data: 20
|
||||||
|
- Name: RunSpeed
|
||||||
|
Type: 1
|
||||||
|
Data: 50
|
||||||
|
- Name: JumpForce
|
||||||
|
Type: 1
|
||||||
|
Data: 50
|
||||||
|
MeshComponent:
|
||||||
|
AssetPath: assets/meshes/Capsule.fbx
|
||||||
|
RigidBodyComponent:
|
||||||
|
BodyType: 1
|
||||||
|
Mass: 1
|
||||||
|
IsKinematic: false
|
||||||
|
Constraints:
|
||||||
|
LockPositionX: false
|
||||||
|
LockPositionY: false
|
||||||
|
LockPositionZ: false
|
||||||
|
LockRotationX: true
|
||||||
|
LockRotationY: false
|
||||||
|
LockRotationZ: true
|
||||||
|
PhysicsMaterialComponent:
|
||||||
|
StaticFriction: 0.100000001
|
||||||
|
DynamicFriction: 0.100000001
|
||||||
|
Bounciness: 0.100000001
|
||||||
|
MeshColliderComponent:
|
||||||
|
AssetPath: assets/meshes/Capsule.fbx
|
||||||
|
IsTrigger: false
|
||||||
|
- Entity: 11149966982516343187
|
||||||
|
TagComponent:
|
||||||
|
Tag: Mesh Collider
|
||||||
|
TransformComponent:
|
||||||
|
Position: [-2.60455179, 1, -0.00171399117]
|
||||||
|
Rotation: [1, 0, 0, 0]
|
||||||
|
Scale: [1, 1, 1]
|
||||||
|
MeshComponent:
|
||||||
|
AssetPath: assets/meshes/Sphere1m.fbx
|
||||||
|
RigidBodyComponent:
|
||||||
|
BodyType: 1
|
||||||
|
Mass: 0.100000001
|
||||||
|
IsKinematic: false
|
||||||
|
Constraints:
|
||||||
|
LockPositionX: false
|
||||||
|
LockPositionY: false
|
||||||
|
LockPositionZ: false
|
||||||
|
LockRotationX: false
|
||||||
|
LockRotationY: false
|
||||||
|
LockRotationZ: false
|
||||||
|
PhysicsMaterialComponent:
|
||||||
|
StaticFriction: 1
|
||||||
|
DynamicFriction: 1
|
||||||
|
Bounciness: 0.100000001
|
||||||
|
MeshColliderComponent:
|
||||||
|
AssetPath: assets/meshes/Sphere1m.fbx
|
||||||
|
IsTrigger: false
|
||||||
|
- Entity: 10169503531257462571
|
||||||
|
TagComponent:
|
||||||
|
Tag: Box
|
||||||
|
TransformComponent:
|
||||||
|
Position: [0, 1.5, 0]
|
||||||
|
Rotation: [1, 0, 0, 0]
|
||||||
|
Scale: [2, 2, 2]
|
||||||
|
MeshComponent:
|
||||||
|
AssetPath: assets/meshes/Cube1m.fbx
|
||||||
|
RigidBodyComponent:
|
||||||
|
BodyType: 1
|
||||||
|
Mass: 0.5
|
||||||
|
IsKinematic: false
|
||||||
|
Constraints:
|
||||||
|
LockPositionX: false
|
||||||
|
LockPositionY: false
|
||||||
|
LockPositionZ: false
|
||||||
|
LockRotationX: false
|
||||||
|
LockRotationY: false
|
||||||
|
LockRotationZ: false
|
||||||
|
PhysicsMaterialComponent:
|
||||||
|
StaticFriction: 1
|
||||||
|
DynamicFriction: 1
|
||||||
|
Bounciness: 0
|
||||||
|
BoxColliderComponent:
|
||||||
|
Offset: [0, 0, 0]
|
||||||
|
Size: [1, 1, 1]
|
||||||
|
IsTrigger: false
|
||||||
|
- Entity: 14057422478420564497
|
||||||
|
TagComponent:
|
||||||
|
Tag: Sphere
|
||||||
|
TransformComponent:
|
||||||
|
Position: [-3.98769951, 1, -1.96695328e-06]
|
||||||
|
Rotation: [1, 0, 0, 0]
|
||||||
|
Scale: [1, 1, 1]
|
||||||
|
MeshComponent:
|
||||||
|
AssetPath: assets/meshes/Sphere1m.fbx
|
||||||
|
RigidBodyComponent:
|
||||||
|
BodyType: 1
|
||||||
|
Mass: 1
|
||||||
|
IsKinematic: false
|
||||||
|
Constraints:
|
||||||
|
LockPositionX: false
|
||||||
|
LockPositionY: false
|
||||||
|
LockPositionZ: false
|
||||||
|
LockRotationX: true
|
||||||
|
LockRotationY: true
|
||||||
|
LockRotationZ: true
|
||||||
|
PhysicsMaterialComponent:
|
||||||
|
StaticFriction: 0.100000001
|
||||||
|
DynamicFriction: 0.100000001
|
||||||
|
Bounciness: 0.100000001
|
||||||
|
SphereColliderComponent:
|
||||||
|
Radius: 0.5
|
||||||
|
IsTrigger: false
|
||||||
|
- Entity: 5178862374589434728
|
||||||
|
TagComponent:
|
||||||
|
Tag: Camera
|
||||||
|
TransformComponent:
|
||||||
|
Position: [2.80800009, 2.25, 0]
|
||||||
|
Rotation: [1, 0, 0, 0]
|
||||||
|
Scale: [1, 1, 1]
|
||||||
|
CameraComponent:
|
||||||
|
Camera: some camera data...
|
||||||
|
Primary: true
|
||||||
|
- Entity: 18306113171518048249
|
||||||
|
TagComponent:
|
||||||
|
Tag: Box
|
||||||
|
TransformComponent:
|
||||||
|
Position: [0, 0, 0]
|
||||||
|
Rotation: [1, 0, 0, 0]
|
||||||
|
Scale: [50, 1, 50]
|
||||||
|
MeshComponent:
|
||||||
|
AssetPath: assets/meshes/Cube1m.fbx
|
||||||
|
RigidBodyComponent:
|
||||||
|
BodyType: 0
|
||||||
|
Mass: 1
|
||||||
|
IsKinematic: false
|
||||||
|
Constraints:
|
||||||
|
LockPositionX: false
|
||||||
|
LockPositionY: false
|
||||||
|
LockPositionZ: false
|
||||||
|
LockRotationX: false
|
||||||
|
LockRotationY: false
|
||||||
|
LockRotationZ: false
|
||||||
|
PhysicsMaterialComponent:
|
||||||
|
StaticFriction: 1
|
||||||
|
DynamicFriction: 1
|
||||||
|
Bounciness: 0
|
||||||
|
BoxColliderComponent:
|
||||||
|
Offset: [0, 0, 0]
|
||||||
|
Size: [1, 1, 1]
|
||||||
|
IsTrigger: false
|
||||||
@ -18,6 +18,14 @@ Entities:
|
|||||||
RigidBodyComponent:
|
RigidBodyComponent:
|
||||||
BodyType: 1
|
BodyType: 1
|
||||||
Mass: 0.5
|
Mass: 0.5
|
||||||
|
IsKinematic: false
|
||||||
|
Constraints:
|
||||||
|
LockPositionX: false
|
||||||
|
LockPositionY: false
|
||||||
|
LockPositionZ: false
|
||||||
|
LockRotationX: true
|
||||||
|
LockRotationY: true
|
||||||
|
LockRotationZ: true
|
||||||
PhysicsMaterialComponent:
|
PhysicsMaterialComponent:
|
||||||
StaticFriction: 1
|
StaticFriction: 1
|
||||||
DynamicFriction: 1
|
DynamicFriction: 1
|
||||||
@ -49,6 +57,14 @@ Entities:
|
|||||||
RigidBodyComponent:
|
RigidBodyComponent:
|
||||||
BodyType: 1
|
BodyType: 1
|
||||||
Mass: 1
|
Mass: 1
|
||||||
|
IsKinematic: false
|
||||||
|
Constraints:
|
||||||
|
LockPositionX: false
|
||||||
|
LockPositionY: false
|
||||||
|
LockPositionZ: false
|
||||||
|
LockRotationX: true
|
||||||
|
LockRotationY: true
|
||||||
|
LockRotationZ: true
|
||||||
PhysicsMaterialComponent:
|
PhysicsMaterialComponent:
|
||||||
StaticFriction: 1
|
StaticFriction: 1
|
||||||
DynamicFriction: 1
|
DynamicFriction: 1
|
||||||
@ -86,6 +102,14 @@ Entities:
|
|||||||
RigidBodyComponent:
|
RigidBodyComponent:
|
||||||
BodyType: 0
|
BodyType: 0
|
||||||
Mass: 1
|
Mass: 1
|
||||||
|
IsKinematic: false
|
||||||
|
Constraints:
|
||||||
|
LockPositionX: false
|
||||||
|
LockPositionY: false
|
||||||
|
LockPositionZ: false
|
||||||
|
LockRotationX: true
|
||||||
|
LockRotationY: true
|
||||||
|
LockRotationZ: true
|
||||||
PhysicsMaterialComponent:
|
PhysicsMaterialComponent:
|
||||||
StaticFriction: 1
|
StaticFriction: 1
|
||||||
DynamicFriction: 1
|
DynamicFriction: 1
|
||||||
|
|||||||
24
Editor/assets/shaders/Collider.glsl
Normal file
24
Editor/assets/shaders/Collider.glsl
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Collider Shader
|
||||||
|
|
||||||
|
#type vertex
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 a_Position;
|
||||||
|
|
||||||
|
uniform mat4 u_ViewProjection;
|
||||||
|
uniform mat4 u_Transform;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#type fragment
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
color = vec4(0.1, 1.0, 0.1, 1.0);
|
||||||
|
}
|
||||||
115
ExampleApp/Src/FPSPlayer.cs
Normal file
115
ExampleApp/Src/FPSPlayer.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
using System;
|
||||||
|
using Prism;
|
||||||
|
|
||||||
|
namespace FPSExample
|
||||||
|
{
|
||||||
|
public class FPSPlayer : Entity
|
||||||
|
{
|
||||||
|
public float WalkingSpeed = 10.0F;
|
||||||
|
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);
|
||||||
|
|
||||||
|
private bool m_Colliding = false;
|
||||||
|
private float m_CurrentSpeed;
|
||||||
|
|
||||||
|
private RigidBodyComponent m_RigidBody;
|
||||||
|
private TransformComponent m_Transform;
|
||||||
|
private TransformComponent m_CameraTransform;
|
||||||
|
|
||||||
|
private Entity m_CameraEntity;
|
||||||
|
|
||||||
|
private Vec2 m_LastMousePosition;
|
||||||
|
private float m_CameraRotationX = 0.0f;
|
||||||
|
private float m_RotationY = 0.0f;
|
||||||
|
|
||||||
|
void OnCreate()
|
||||||
|
{
|
||||||
|
m_Transform = GetComponent<TransformComponent>();
|
||||||
|
m_RigidBody = GetComponent<RigidBodyComponent>();
|
||||||
|
|
||||||
|
m_CurrentSpeed = WalkingSpeed;
|
||||||
|
|
||||||
|
AddCollisionBeginCallback((n) => { m_Colliding = true; });
|
||||||
|
AddCollisionEndCallback((n) => { m_Colliding = false; });
|
||||||
|
|
||||||
|
m_CameraEntity = FindEntityByTag("Camera");
|
||||||
|
|
||||||
|
m_CameraTransform = m_CameraEntity.GetComponent<TransformComponent>();
|
||||||
|
m_LastMousePosition = Input.GetMousePosition();
|
||||||
|
|
||||||
|
Input.SetCursorMode(Input.CursorMode.Locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdate(float ts)
|
||||||
|
{
|
||||||
|
Forward = m_Transform.Forward;
|
||||||
|
|
||||||
|
if (Input.IsKeyPressed(KeyCode.Escape) && Input.GetCursorMode() == Input.CursorMode.Locked)
|
||||||
|
{
|
||||||
|
Input.SetCursorMode(Input.CursorMode.Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_CurrentSpeed = Input.IsKeyPressed(KeyCode.LeftControl) ? RunSpeed : WalkingSpeed;
|
||||||
|
|
||||||
|
UpdateRotation(ts);
|
||||||
|
UpdateMovement();
|
||||||
|
UpdateCameraTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRotation(float ts)
|
||||||
|
{
|
||||||
|
Vec2 currentMousePosition = Input.GetMousePosition();
|
||||||
|
Vec2 delta = m_LastMousePosition - currentMousePosition;
|
||||||
|
if (delta.X != 0)
|
||||||
|
{
|
||||||
|
m_RotationY += delta.X * MouseSensitivity * ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_RigidBody.Rotate(new Vec3(0.0F, delta.X * MouseSensitivity, 0.0f) * ts);
|
||||||
|
|
||||||
|
if (delta.Y != 0.0F)
|
||||||
|
{
|
||||||
|
m_CameraRotationX += delta.Y * MouseSensitivity * ts;
|
||||||
|
m_CameraRotationX = Mathf.Clamp(m_CameraRotationX, -80.0f, 80.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LastMousePosition = currentMousePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateMovement()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (Input.IsKeyPressed(KeyCode.W))
|
||||||
|
m_RigidBody.AddForce(m_Transform.Forward * m_CurrentSpeed);
|
||||||
|
else if (Input.IsKeyPressed(KeyCode.S))
|
||||||
|
m_RigidBody.AddForce(m_Transform.Forward * -m_CurrentSpeed);
|
||||||
|
|
||||||
|
if (Input.IsKeyPressed(KeyCode.A))
|
||||||
|
m_RigidBody.AddForce(m_Transform.Right * -m_CurrentSpeed);
|
||||||
|
else if (Input.IsKeyPressed(KeyCode.D))
|
||||||
|
m_RigidBody.AddForce(m_Transform.Right * m_CurrentSpeed);
|
||||||
|
|
||||||
|
if (Input.IsKeyPressed(KeyCode.Space) && m_Colliding)
|
||||||
|
m_RigidBody.AddForce(Vec3.Up * JumpForce);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCameraTransform(){
|
||||||
|
|
||||||
|
// TODO: This workflow needs to be improved. (Will be fixed by object parenting)
|
||||||
|
|
||||||
|
Mat4 cameraTransform = m_CameraTransform.Transform;
|
||||||
|
Vec3 cameraTranslation = cameraTransform.Translation;
|
||||||
|
Vec3 translation = m_Transform.Transform.Translation;
|
||||||
|
cameraTranslation.XZ = translation.XZ;
|
||||||
|
cameraTranslation.Y = translation.Y + 1.5F;
|
||||||
|
cameraTransform.Translation = cameraTranslation;
|
||||||
|
m_CameraTransform.Transform = cameraTransform;
|
||||||
|
|
||||||
|
m_CameraTransform.Rotation = new Vec3(m_CameraRotationX, m_RotationY, 0.0f);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,9 +22,11 @@ namespace Example
|
|||||||
|
|
||||||
private bool Colliding => m_CollisionCounter > 0;
|
private bool Colliding => m_CollisionCounter > 0;
|
||||||
|
|
||||||
|
private TransformComponent m_Transform;
|
||||||
void OnCreate()
|
void OnCreate()
|
||||||
{
|
{
|
||||||
m_PhysicsBody = GetComponent<RigidBodyComponent>();
|
m_PhysicsBody = GetComponent<RigidBodyComponent>();
|
||||||
|
m_Transform = GetComponent<TransformComponent>();
|
||||||
|
|
||||||
MeshComponent meshComponent = GetComponent<MeshComponent>();
|
MeshComponent meshComponent = GetComponent<MeshComponent>();
|
||||||
m_MeshMaterial = meshComponent.Mesh.GetMaterial(0);
|
m_MeshMaterial = meshComponent.Mesh.GetMaterial(0);
|
||||||
@ -32,6 +34,8 @@ namespace Example
|
|||||||
|
|
||||||
AddCollisionBeginCallback(OnPlayerCollisionBegin);
|
AddCollisionBeginCallback(OnPlayerCollisionBegin);
|
||||||
AddCollisionEndCallback(OnPlayerCollisionEnd);
|
AddCollisionEndCallback(OnPlayerCollisionEnd);
|
||||||
|
AddTriggerBeginCallback(OnPlayerTriggerBegin);
|
||||||
|
AddTriggerEndCallback(OnPlayerTriggerEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnPlayerCollisionBegin(float value)
|
void OnPlayerCollisionBegin(float value)
|
||||||
@ -44,6 +48,16 @@ namespace Example
|
|||||||
m_CollisionCounter--;
|
m_CollisionCounter--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnPlayerTriggerBegin(float value)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Player trigger begin");
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnPlayerTriggerEnd(float value)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Player trigger end");
|
||||||
|
}
|
||||||
|
|
||||||
void OnUpdate(float ts)
|
void OnUpdate(float ts)
|
||||||
{
|
{
|
||||||
float movementForce = HorizontalForce;
|
float movementForce = HorizontalForce;
|
||||||
@ -53,22 +67,18 @@ namespace Example
|
|||||||
movementForce *= 0.4f;
|
movementForce *= 0.4f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 forward = GetForwardDirection();
|
|
||||||
Vec3 right = GetRightDirection();
|
|
||||||
Vec3 up = GetUpDirection();
|
|
||||||
|
|
||||||
if (Input.IsKeyPressed(KeyCode.W))
|
if (Input.IsKeyPressed(KeyCode.W))
|
||||||
m_PhysicsBody.AddForce(forward * movementForce);
|
m_PhysicsBody.AddForce(m_Transform.Forward * movementForce);
|
||||||
else if (Input.IsKeyPressed(KeyCode.S))
|
else if (Input.IsKeyPressed(KeyCode.S))
|
||||||
m_PhysicsBody.AddForce(forward * -movementForce);
|
m_PhysicsBody.AddForce(m_Transform.Forward * -movementForce);
|
||||||
|
|
||||||
if (Input.IsKeyPressed(KeyCode.D))
|
if (Input.IsKeyPressed(KeyCode.D))
|
||||||
m_PhysicsBody.AddForce(right * movementForce);
|
m_PhysicsBody.AddForce(m_Transform.Right * movementForce);
|
||||||
else if (Input.IsKeyPressed(KeyCode.A))
|
else if (Input.IsKeyPressed(KeyCode.A))
|
||||||
m_PhysicsBody.AddForce(right * -movementForce);
|
m_PhysicsBody.AddForce(m_Transform.Right * -movementForce);
|
||||||
|
|
||||||
if (Colliding && Input.IsKeyPressed(KeyCode.Space))
|
if (Colliding && Input.IsKeyPressed(KeyCode.Space))
|
||||||
m_PhysicsBody.AddForce(up * JumpForce);
|
m_PhysicsBody.AddForce(m_Transform.Up * JumpForce);
|
||||||
|
|
||||||
if (Colliding)
|
if (Colliding)
|
||||||
m_MeshMaterial.Set("u_AlbedoColor", new Vec3(1.0f, 0.0f, 0.0f));
|
m_MeshMaterial.Set("u_AlbedoColor", new Vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
|||||||
@ -11,10 +11,12 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Action<float>> m_Collision2DBeginCallbacks = new List<Action<float>>();
|
private Action<float>? m_CollisionBeginCallbacks;
|
||||||
private List<Action<float>> m_Collision2DEndCallbacks = new List<Action<float>>();
|
private Action<float>? m_CollisionEndCallbacks;
|
||||||
private Action<float> m_CollisionBeginCallbacks;
|
private Action<float>? m_Collision2DBeginCallbacks;
|
||||||
private Action<float> m_CollisionEndCallbacks;
|
private Action<float>? m_Collision2DEndCallbacks;
|
||||||
|
private Action<float>? m_TriggerBeginCallbacks;
|
||||||
|
private Action<float>? m_TriggerEndCallbacks;
|
||||||
|
|
||||||
protected Entity() { ID = 0; }
|
protected Entity() { ID = 0; }
|
||||||
|
|
||||||
@ -65,32 +67,14 @@ namespace Prism
|
|||||||
SetTransform_Native(ID, ref transform);
|
SetTransform_Native(ID, ref transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3 GetForwardDirection()
|
|
||||||
{
|
|
||||||
GetForwardDirection_Native(ID, out Vec3 forward);
|
|
||||||
return forward;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3 GetRightDirection()
|
|
||||||
{
|
|
||||||
GetRightDirection_Native(ID, out Vec3 right);
|
|
||||||
return right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3 GetUpDirection()
|
|
||||||
{
|
|
||||||
GetUpDirection_Native(ID, out Vec3 up);
|
|
||||||
return up;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddCollision2DBeginCallback(Action<float> callback)
|
public void AddCollision2DBeginCallback(Action<float> callback)
|
||||||
{
|
{
|
||||||
m_Collision2DBeginCallbacks.Add(callback);
|
m_Collision2DBeginCallbacks += callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCollision2DEndCallback(Action<float> callback)
|
public void AddCollision2DEndCallback(Action<float> callback)
|
||||||
{
|
{
|
||||||
m_Collision2DEndCallbacks.Add(callback);
|
m_Collision2DEndCallbacks += callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCollisionBeginCallback(Action<float> callback)
|
public void AddCollisionBeginCallback(Action<float> callback)
|
||||||
@ -103,6 +87,16 @@ namespace Prism
|
|||||||
m_CollisionEndCallbacks += callback;
|
m_CollisionEndCallbacks += callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddTriggerBeginCallback(Action<float> callback)
|
||||||
|
{
|
||||||
|
m_TriggerBeginCallbacks += callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddTriggerEndCallback(Action<float> callback)
|
||||||
|
{
|
||||||
|
m_TriggerEndCallbacks += callback;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnCollisionBegin(float data)
|
private void OnCollisionBegin(float data)
|
||||||
{
|
{
|
||||||
if (m_CollisionBeginCallbacks != null)
|
if (m_CollisionBeginCallbacks != null)
|
||||||
@ -117,16 +111,29 @@ namespace Prism
|
|||||||
|
|
||||||
private void OnCollision2DBegin(float data)
|
private void OnCollision2DBegin(float data)
|
||||||
{
|
{
|
||||||
foreach (var callback in m_Collision2DBeginCallbacks)
|
if(m_Collision2DBeginCallbacks != null)
|
||||||
callback.Invoke(data);
|
m_Collision2DBeginCallbacks.Invoke(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCollision2DEnd(float data)
|
private void OnCollision2DEnd(float data)
|
||||||
{
|
{
|
||||||
foreach (var callback in m_Collision2DEndCallbacks)
|
if(m_Collision2DEndCallbacks != null)
|
||||||
callback.Invoke(data);
|
m_Collision2DEndCallbacks.Invoke(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnTriggerBegin(float data)
|
||||||
|
{
|
||||||
|
if (m_TriggerBeginCallbacks != null)
|
||||||
|
m_TriggerBeginCallbacks.Invoke(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTriggerEnd(float data)
|
||||||
|
{
|
||||||
|
if (m_TriggerEndCallbacks != null)
|
||||||
|
m_TriggerEndCallbacks.Invoke(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
private static extern void CreateComponent_Native(ulong entityID, Type type);
|
private static extern void CreateComponent_Native(ulong entityID, Type type);
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
@ -137,12 +144,5 @@ namespace Prism
|
|||||||
private static extern void SetTransform_Native(ulong entityID, ref Mat4 matrix);
|
private static extern void SetTransform_Native(ulong entityID, ref Mat4 matrix);
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
private static extern ulong FindEntityByTag_Native(string tag);
|
private static extern ulong FindEntityByTag_Native(string tag);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
private static extern void GetForwardDirection_Native(ulong entityID, out Vec3 forward);
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
private static extern void GetRightDirection_Native(ulong entityID, out Vec3 right);
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
private static extern void GetUpDirection_Native(ulong entityID, out Vec3 up);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,14 +4,39 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
public class Input
|
public class Input
|
||||||
{
|
{
|
||||||
|
public enum CursorMode
|
||||||
|
{
|
||||||
|
Normal = 0,
|
||||||
|
Hidden = 1,
|
||||||
|
Locked = 2,
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsKeyPressed(KeyCode keycode)
|
public static bool IsKeyPressed(KeyCode keycode)
|
||||||
{
|
{
|
||||||
return IsKeyPressed_Native(keycode);
|
return IsKeyPressed_Native(keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vec2 GetMousePosition()
|
||||||
|
{
|
||||||
|
GetMousePosition_Native(out Vec2 position);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetCursorMode(CursorMode mode) => SetCursorMode_Native(mode);
|
||||||
|
public static CursorMode GetCursorMode() => GetCursorMode_Native();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
private static extern bool IsKeyPressed_Native(KeyCode keycode);
|
private static extern bool IsKeyPressed_Native(KeyCode keycode);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
private static extern void GetMousePosition_Native(out Vec2 position);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
private static extern void SetCursorMode_Native(CursorMode mode);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
private static extern CursorMode GetCursorMode_Native();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
56
Prism-ScriptCore/Src/Prism/Math/Queternion.cs
Normal file
56
Prism-ScriptCore/Src/Prism/Math/Queternion.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct Quaternion
|
||||||
|
{
|
||||||
|
public float X;
|
||||||
|
public float Y;
|
||||||
|
public float Z;
|
||||||
|
public float W;
|
||||||
|
|
||||||
|
public Quaternion(float x, float y, float z, float w)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = z;
|
||||||
|
W = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Quaternion(float w, Vec3 xyz)
|
||||||
|
{
|
||||||
|
X = xyz.X;
|
||||||
|
Y = xyz.Y;
|
||||||
|
Z = xyz.Z;
|
||||||
|
W = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Quaternion(Vec3 eulerAngles)
|
||||||
|
{
|
||||||
|
Vec3 c = Vec3.Cos(eulerAngles * 0.5F);
|
||||||
|
Vec3 s = Vec3.Sin(eulerAngles * 0.5F);
|
||||||
|
|
||||||
|
W = c.X * c.Y * c.Z + s.X * s.Y * s.Z;
|
||||||
|
X = s.X * c.Y * c.Z - c.X * s.Y * s.Z;
|
||||||
|
Y = c.X * s.Y * c.Z + s.X * c.Y * s.Z;
|
||||||
|
Z = c.X * c.Y * s.Z - s.X * s.Y * c.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Quaternion AngleAxis(float angle, Vec3 axis)
|
||||||
|
{
|
||||||
|
float s = (float)Math.Sin(angle * 0.5F);
|
||||||
|
return new Quaternion(s, axis * s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Quaternion operator*(Quaternion a, Quaternion b)
|
||||||
|
{
|
||||||
|
float w = a.W * b.W - a.X * b.X - a.Y * b.Y - a.Z * b.Z;
|
||||||
|
float x = a.W * b.X + a.X * b.W + a.Y * b.Z - a.Z * b.Y;
|
||||||
|
float y = a.W * b.Y + a.Y * b.W + a.Z * b.X - a.X * b.Z;
|
||||||
|
float z = a.W * b.Z + a.Z * b.W + a.X * b.Y - a.Y * b.X;
|
||||||
|
return new Quaternion(x, y, z, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,20 +25,23 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Clamp(Vec2 min, Vec2 max) {
|
public void Clamp(Vec2 min, Vec2 max) {
|
||||||
if (X < min.X)
|
X = Mathf.Clamp(X, min.X, max.X);
|
||||||
X = min.X;
|
Y = Mathf.Clamp(Y, min.Y, max.Y);
|
||||||
if (X > max.X)
|
|
||||||
X = max.X;
|
|
||||||
|
|
||||||
if (Y < min.Y)
|
|
||||||
Y = min.Y;
|
|
||||||
if (Y > max.Y)
|
|
||||||
Y = max.Y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vec2 operator -(Vec2 l, Vec2 r)
|
||||||
|
{
|
||||||
|
return new Vec2(l.X - r.X, l.Y - r.Y);
|
||||||
|
}
|
||||||
|
|
||||||
public static Vec2 operator -(Vec2 vector)
|
public static Vec2 operator -(Vec2 vector)
|
||||||
{
|
{
|
||||||
return new Vec2(-vector.X, -vector.Y);
|
return new Vec2(-vector.X, -vector.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"({X}, {Y})";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,6 +5,12 @@ namespace Prism
|
|||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct Vec3
|
public struct Vec3
|
||||||
{
|
{
|
||||||
|
public static Vec3 Zero = new Vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
public static Vec3 Forward = new Vec3(0.0f, 0.0f, -1.0f);
|
||||||
|
public static Vec3 Right = new Vec3(1.0f, 0.0f, 0.0f);
|
||||||
|
public static Vec3 Up = new Vec3(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
public float X;
|
public float X;
|
||||||
public float Y;
|
public float Y;
|
||||||
public float Z;
|
public float Z;
|
||||||
@ -40,15 +46,6 @@ namespace Prism
|
|||||||
Z = Mathf.Clamp(Z, min.Z, max.Z);
|
Z = Mathf.Clamp(Z, min.Z, max.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec3 operator *(Vec3 left, float scalar)
|
|
||||||
{
|
|
||||||
return new Vec3(left.X * scalar, left.Y * scalar, left.Z * scalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vec3 operator *(float scalar, Vec3 right)
|
|
||||||
{
|
|
||||||
return new Vec3(scalar * right.X, scalar * right.Y, scalar * right.Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec2 XY {
|
public Vec2 XY {
|
||||||
get { return new Vec2(X, Y); }
|
get { return new Vec2(X, Y); }
|
||||||
@ -66,5 +63,56 @@ namespace Prism
|
|||||||
set { Y = value.X; Z = value.Y; }
|
set { Y = value.X; Z = value.Y; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Vec3 operator *(Vec3 left, float scalar)
|
||||||
|
{
|
||||||
|
return new Vec3(left.X * scalar, left.Y * scalar, left.Z * scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 operator *(float scalar, Vec3 right)
|
||||||
|
{
|
||||||
|
return new Vec3(scalar * right.X, scalar * right.Y, scalar * right.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 operator +(Vec3 left, Vec3 right)
|
||||||
|
{
|
||||||
|
return new Vec3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 operator -(Vec3 left, Vec3 right)
|
||||||
|
{
|
||||||
|
return new Vec3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 operator /(Vec3 left, Vec3 right)
|
||||||
|
{
|
||||||
|
return new Vec3(left.X / right.X, left.Y / right.Y, left.Z / right.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 operator /(Vec3 left, float scalar)
|
||||||
|
{
|
||||||
|
return new Vec3(left.X / scalar, left.Y / scalar, left.Z / scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 operator-(Vec3 vector)
|
||||||
|
{
|
||||||
|
return new Vec3(-vector.X, -vector.Y, -vector.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 Cos(Vec3 vector)
|
||||||
|
{
|
||||||
|
return new Vec3((float)Math.Cos(vector.X), (float)Math.Cos(vector.Y), (float)Math.Cos(vector.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 Sin(Vec3 vector)
|
||||||
|
{
|
||||||
|
return new Vec3((float)Math.Sin(vector.X), (float)Math.Sin(vector.Y), (float)Math.Sin(vector.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"({X}, {Y}, {Z})";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,13 +2,13 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct Vec4
|
public struct Vec4
|
||||||
{
|
{
|
||||||
[FieldOffset(0)] public float X;
|
public float X;
|
||||||
[FieldOffset(4)] public float Y;
|
public float Y;
|
||||||
[FieldOffset(8)] public float Z;
|
public float Z;
|
||||||
[FieldOffset(12)] public float W;
|
public float W;
|
||||||
|
|
||||||
public Vec4(float scalar)
|
public Vec4(float scalar)
|
||||||
{
|
{
|
||||||
|
|||||||
77
Prism-ScriptCore/Src/Prism/Physics/Colliders.cs
Normal file
77
Prism-ScriptCore/Src/Prism/Physics/Colliders.cs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
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 bool IsTrigger { get; protected set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BoxCollider : Collider
|
||||||
|
{
|
||||||
|
public Vec3 Size { get; private set; }
|
||||||
|
public Vec3 Offset { get; private set; }
|
||||||
|
|
||||||
|
internal BoxCollider(ulong entityID, Vec3 size, Vec3 offset, bool isTrigger)
|
||||||
|
{
|
||||||
|
ColliderEntity = new Entity(entityID);
|
||||||
|
Type = ColliderType.Box;
|
||||||
|
Size = size;
|
||||||
|
Offset = offset;
|
||||||
|
IsTrigger = isTrigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SphereCollider : Collider
|
||||||
|
{
|
||||||
|
public float Radius { get; private set; }
|
||||||
|
|
||||||
|
internal SphereCollider(ulong entityID, float radius, bool isTrigger)
|
||||||
|
{
|
||||||
|
ColliderEntity = new Entity(entityID);
|
||||||
|
Type = ColliderType.Box;
|
||||||
|
Radius = radius;
|
||||||
|
IsTrigger = isTrigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CapsuleCollider : Collider
|
||||||
|
{
|
||||||
|
public float Radius { get; private set; }
|
||||||
|
public float Height { get; private set; }
|
||||||
|
|
||||||
|
internal CapsuleCollider(ulong entityID, float radius, float height, bool isTrigger)
|
||||||
|
{
|
||||||
|
ColliderEntity = new Entity(entityID);
|
||||||
|
Type = ColliderType.Box;
|
||||||
|
Radius = radius;
|
||||||
|
Height = height;
|
||||||
|
IsTrigger = isTrigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MeshCollider : Collider
|
||||||
|
{
|
||||||
|
public Mesh Mesh { get; private set; }
|
||||||
|
|
||||||
|
internal MeshCollider(ulong entityID, Mesh mesh, bool isTrigger)
|
||||||
|
{
|
||||||
|
ColliderEntity = new Entity(entityID);
|
||||||
|
Type = ColliderType.Box;
|
||||||
|
Mesh = mesh;
|
||||||
|
IsTrigger = isTrigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -46,11 +46,62 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vec3 Rotation
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
GetRotation_Native(Entity.ID, out Vec3 rotation);
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetRotation_Native(Entity.ID, ref value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 Forward
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
GetRelativeDirection_Native(Entity.ID, out Vec3 result, ref Vec3.Forward);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 Right
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
GetRelativeDirection_Native(Entity.ID, out Vec3 result, ref Vec3.Right);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 Up
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
GetRelativeDirection_Native(Entity.ID, out Vec3 result, ref Vec3.Up);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public static extern void GetTransform_Native(ulong entityID, out Mat4 result);
|
public static extern void GetTransform_Native(ulong entityID, out Mat4 result);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public static extern void SetTransform_Native(ulong entityID, ref Mat4 result);
|
public static extern void SetTransform_Native(ulong entityID, ref Mat4 result);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
public static extern void GetRelativeDirection_Native(ulong entityID, out Vec3 result, ref Vec3 direction);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
public static extern void GetRotation_Native(ulong entityID, out Vec3 rotation);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
public static extern void SetRotation_Native(ulong entityID, ref Vec3 rotation);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +214,12 @@ namespace Prism
|
|||||||
SetLinearVelocity_Native(Entity.ID, ref velocity);
|
SetLinearVelocity_Native(Entity.ID, ref velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Rotate(Vec3 rotation)
|
||||||
|
{
|
||||||
|
Rotate_Native(Entity.ID, ref rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: Add SetMaxLinearVelocity() as well
|
// TODO: Add SetMaxLinearVelocity() as well
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
@ -174,5 +231,8 @@ namespace Prism
|
|||||||
internal static extern void GetLinearVelocity_Native(ulong entityID, out Vec3 velocity);
|
internal static extern void GetLinearVelocity_Native(ulong entityID, out Vec3 velocity);
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern void SetLinearVelocity_Native(ulong entityID, ref Vec3 velocity);
|
internal static extern void SetLinearVelocity_Native(ulong entityID, ref Vec3 velocity);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
internal static extern void Rotate_Native(ulong entityID, ref Vec3 rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,6 +56,11 @@ namespace Prism
|
|||||||
#define PM_CORE_ASSERT(x, ...)
|
#define PM_CORE_ASSERT(x, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.1415926f
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
using byte = unsigned char;
|
using byte = unsigned char;
|
||||||
|
|||||||
@ -9,6 +9,13 @@
|
|||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
|
enum class CursorMode
|
||||||
|
{
|
||||||
|
Normal = 0,
|
||||||
|
Hidden = 1,
|
||||||
|
Locked = 2
|
||||||
|
};
|
||||||
|
|
||||||
class PRISM_API Input
|
class PRISM_API Input
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -18,6 +25,9 @@ namespace Prism
|
|||||||
static float GetMouseX();
|
static float GetMouseX();
|
||||||
static float GetMouseY();
|
static float GetMouseY();
|
||||||
static std::pair<float, float> GetMousePosition();
|
static std::pair<float, float> GetMousePosition();
|
||||||
|
|
||||||
|
static void SetCursorMode(CursorMode mode);
|
||||||
|
static CursorMode GetCursorMode();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,9 +14,6 @@
|
|||||||
#include "Prism/Core/Input.h"
|
#include "Prism/Core/Input.h"
|
||||||
#include "Prism/Core/Events/MouseEvent.h"
|
#include "Prism/Core/Events/MouseEvent.h"
|
||||||
|
|
||||||
#ifndef M_PI
|
|
||||||
#define M_PI 3.1415926f
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
|
|||||||
@ -7,10 +7,13 @@
|
|||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "assimp/matrix4x4.h"
|
#include "assimp/matrix4x4.h"
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include "imgui_internal.h"
|
||||||
#include "assimp/scene.h"
|
#include "assimp/scene.h"
|
||||||
#include "glm/gtx/matrix_decompose.hpp"
|
#include "glm/gtx/matrix_decompose.hpp"
|
||||||
#include "glm/gtx/quaternion.hpp"
|
#include "glm/gtx/quaternion.hpp"
|
||||||
#include "Prism/Core/Application.h"
|
#include "Prism/Core/Application.h"
|
||||||
|
#include "Prism/Physics/PxPhysicsWrappers.h"
|
||||||
|
#include "Prism/Renderer/Meshfactory.h"
|
||||||
#include "Prism/Script/ScriptEngine.h"
|
#include "Prism/Script/ScriptEngine.h"
|
||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
@ -42,6 +45,19 @@ namespace Prism
|
|||||||
m_SelectionContext = entity;
|
m_SelectionContext = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void SceneHierarchyPanel::AddComponentPopup(const char* componentName)
|
||||||
|
{
|
||||||
|
if (!m_SelectionContext.HasComponent<T>())
|
||||||
|
{
|
||||||
|
if (ImGui::Button(componentName))
|
||||||
|
{
|
||||||
|
m_SelectionContext.AddComponent<T>();
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SceneHierarchyPanel::OnImGuiRender()
|
void SceneHierarchyPanel::OnImGuiRender()
|
||||||
{
|
{
|
||||||
ImGui::Begin("Scene Hierarchy");
|
ImGui::Begin("Scene Hierarchy");
|
||||||
@ -79,6 +95,21 @@ namespace Prism
|
|||||||
|
|
||||||
if (ImGui::BeginPopup("AddComponentPanel"))
|
if (ImGui::BeginPopup("AddComponentPanel"))
|
||||||
{
|
{
|
||||||
|
AddComponentPopup<CameraComponent>("Camera");
|
||||||
|
AddComponentPopup<MeshComponent>("Mesh");
|
||||||
|
AddComponentPopup<ScriptComponent>("Script");
|
||||||
|
AddComponentPopup<SpriteRendererComponent>("SpriteRenderer");
|
||||||
|
AddComponentPopup<RigidBody2DComponent>("RigidBody2D");
|
||||||
|
AddComponentPopup<BoxCollider2DComponent>("BoxCollider2D");
|
||||||
|
AddComponentPopup<CircleCollider2DComponent>("CircleCollider2D");
|
||||||
|
AddComponentPopup<RigidBodyComponent>("RigidBody");
|
||||||
|
AddComponentPopup<PhysicsMaterialComponent>("PhysicsMaterial");
|
||||||
|
AddComponentPopup<BoxColliderComponent>("BoxCollider");
|
||||||
|
AddComponentPopup<SphereColliderComponent>("SphereCollider");
|
||||||
|
AddComponentPopup<CapsuleColliderComponent>("CapsuleCollider");
|
||||||
|
AddComponentPopup<MeshColliderComponent>("MeshCollider");
|
||||||
|
|
||||||
|
/*
|
||||||
if (!m_SelectionContext.HasComponent<CameraComponent>())
|
if (!m_SelectionContext.HasComponent<CameraComponent>())
|
||||||
{
|
{
|
||||||
if (ImGui::Button("Camera"))
|
if (ImGui::Button("Camera"))
|
||||||
@ -168,6 +199,15 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_SelectionContext.HasComponent<CapsuleColliderComponent>())
|
||||||
|
{
|
||||||
|
if (ImGui::Button("Capsule Collider"))
|
||||||
|
{
|
||||||
|
m_SelectionContext.AddComponent<CapsuleColliderComponent>();
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_SelectionContext.HasComponent<MeshColliderComponent>())
|
if (!m_SelectionContext.HasComponent<MeshColliderComponent>())
|
||||||
{
|
{
|
||||||
if (ImGui::Button("Mesh Collider"))
|
if (ImGui::Button("Mesh Collider"))
|
||||||
@ -176,6 +216,7 @@ namespace Prism
|
|||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
@ -334,6 +375,7 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
PushID();
|
PushID();
|
||||||
ImGui::Columns(2);
|
ImGui::Columns(2);
|
||||||
|
ImGui::SetColumnWidth(0, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Property(const char* label, std::string& value, bool error = false)
|
static bool Property(const char* label, std::string& value, bool error = false)
|
||||||
@ -434,7 +476,7 @@ namespace Prism
|
|||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Property(const char* label, float& value, float delta = 0.1f)
|
static bool Property(const char* label, float& value, float delta = 0.1f, float min = 0.0f, float max = 0.0f)
|
||||||
{
|
{
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
@ -448,7 +490,7 @@ namespace Prism
|
|||||||
// itoa(s_Counter++, s_IDBuffer + 2, 16);
|
// itoa(s_Counter++, s_IDBuffer + 2, 16);
|
||||||
snprintf(s_IDBuffer + 2, 14, "%x", s_Counter++);
|
snprintf(s_IDBuffer + 2, 14, "%x", s_Counter++);
|
||||||
|
|
||||||
if (ImGui::DragFloat(s_IDBuffer, &value, delta))
|
if (ImGui::DragFloat(s_IDBuffer, &value, delta, min, max))
|
||||||
modified = true;
|
modified = true;
|
||||||
|
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
@ -640,8 +682,12 @@ namespace Prism
|
|||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
ImGui::PushItemWidth(-1);
|
ImGui::PushItemWidth(-1);
|
||||||
|
|
||||||
if (ImGui::DragFloat3("##scale", glm::value_ptr(scale), 0.25f))
|
if (ImGui::DragFloat3("##scale", glm::value_ptr(scale), 0.05f))
|
||||||
{
|
{
|
||||||
|
if (scale.x == 0) scale.x = 0.01f;
|
||||||
|
if (scale.y == 0) scale.y = 0.01f;
|
||||||
|
if (scale.z == 0) scale.z = 0.01f;
|
||||||
|
|
||||||
updateTransform = true;
|
updateTransform = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -850,13 +896,13 @@ namespace Prism
|
|||||||
DrawComponent<RigidBody2DComponent>("Rigidbody 2D", entity, [](RigidBody2DComponent& rb2dComponent)
|
DrawComponent<RigidBody2DComponent>("Rigidbody 2D", entity, [](RigidBody2DComponent& rb2dComponent)
|
||||||
{
|
{
|
||||||
// Rigidbody2D Type
|
// Rigidbody2D Type
|
||||||
const char* rb2dTypeStrings[] = { "Static", "Dynamic", "Kinematic" };
|
const char* rb2dTypeStrings[] = { "Static", "Dynamic"};
|
||||||
const char* currentType = rb2dTypeStrings[(int)rb2dComponent.BodyType];
|
const char* currentType = rb2dTypeStrings[(int)rb2dComponent.BodyType];
|
||||||
if (ImGui::BeginCombo("Type", currentType))
|
if (ImGui::BeginCombo("Type", currentType))
|
||||||
{
|
{
|
||||||
for (int type = 0; type < 3; type++)
|
for (int type = 0; type < 2; type++)
|
||||||
{
|
{
|
||||||
bool is_selected = (currentType == rb2dTypeStrings[type]);
|
const bool is_selected = (currentType == rb2dTypeStrings[type]);
|
||||||
if (ImGui::Selectable(rb2dTypeStrings[type], is_selected))
|
if (ImGui::Selectable(rb2dTypeStrings[type], is_selected))
|
||||||
{
|
{
|
||||||
currentType = rb2dTypeStrings[type];
|
currentType = rb2dTypeStrings[type];
|
||||||
@ -903,11 +949,11 @@ namespace Prism
|
|||||||
DrawComponent<RigidBodyComponent>("Rigidbody", entity, [](RigidBodyComponent& rbc)
|
DrawComponent<RigidBodyComponent>("Rigidbody", entity, [](RigidBodyComponent& rbc)
|
||||||
{
|
{
|
||||||
// Rigidbody Type
|
// Rigidbody Type
|
||||||
const char* rbTypeStrings[] = { "Static", "Dynamic", "Kinematic" };
|
const char* rbTypeStrings[] = { "Static", "Dynamic"};
|
||||||
const char* currentType = rbTypeStrings[(int)rbc.BodyType];
|
const char* currentType = rbTypeStrings[(int)rbc.BodyType];
|
||||||
if (ImGui::BeginCombo("Type", currentType))
|
if (ImGui::BeginCombo("Type", currentType))
|
||||||
{
|
{
|
||||||
for (int type = 0; type < 3; type++)
|
for (int type = 0; type < 2; type++)
|
||||||
{
|
{
|
||||||
bool is_selected = (currentType == rbTypeStrings[type]);
|
bool is_selected = (currentType == rbTypeStrings[type]);
|
||||||
if (ImGui::Selectable(rbTypeStrings[type], is_selected))
|
if (ImGui::Selectable(rbTypeStrings[type], is_selected))
|
||||||
@ -925,20 +971,23 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
BeginPropertyGrid();
|
BeginPropertyGrid();
|
||||||
Property("Mass", rbc.Mass);
|
Property("Mass", rbc.Mass);
|
||||||
|
Property("Is Kinematic", rbc.IsKinematic);
|
||||||
|
EndPropertyGrid();
|
||||||
|
|
||||||
if (ImGui::TreeNode("RigidBodyConstraints", "Constraints"))
|
if (ImGui::TreeNode("RigidBodyConstraints", "Constraints"))
|
||||||
{
|
{
|
||||||
|
BeginPropertyGrid();
|
||||||
Property("Position: X", rbc.LockPositionX);
|
Property("Position: X", rbc.LockPositionX);
|
||||||
Property("Position: Y", rbc.LockPositionY);
|
Property("Position: Y", rbc.LockPositionY);
|
||||||
Property("Position: Z", rbc.LockPositionZ);
|
Property("Position: Z", rbc.LockPositionZ);
|
||||||
Property("Rotation: X", rbc.LockRotationX);
|
Property("Rotation: X", rbc.LockRotationX);
|
||||||
Property("Rotation: Y", rbc.LockRotationY);
|
Property("Rotation: Y", rbc.LockRotationY);
|
||||||
Property("Rotation: Z", rbc.LockRotationZ);
|
Property("Rotation: Z", rbc.LockRotationZ);
|
||||||
|
EndPropertyGrid();
|
||||||
|
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
EndPropertyGrid();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -946,9 +995,9 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
BeginPropertyGrid();
|
BeginPropertyGrid();
|
||||||
|
|
||||||
Property("Static Friction", pmc.StaticFriction);
|
Property("Static Friction", pmc.StaticFriction, 0.01f, 0.0f, 1.0f);
|
||||||
Property("Dynamic Friction", pmc.DynamicFriction);
|
Property("Dynamic Friction", pmc.DynamicFriction, 0.01f, 0.0f, 1.0f);
|
||||||
Property("Bounciness", pmc.Bounciness);
|
Property("Bounciness", pmc.Bounciness, 0.01f, 0.0f, 1.0f);
|
||||||
|
|
||||||
EndPropertyGrid();
|
EndPropertyGrid();
|
||||||
});
|
});
|
||||||
@ -957,8 +1006,12 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
BeginPropertyGrid();
|
BeginPropertyGrid();
|
||||||
|
|
||||||
Property("Size", bcc.Size);
|
if (Property("Size", bcc.Size))
|
||||||
//Property("Offset", bcc.Offset);
|
{
|
||||||
|
bcc.DebugMesh = MeshFactory::CreateBox(bcc.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Property("IsTrigger", bcc.IsTrigger);
|
||||||
|
|
||||||
EndPropertyGrid();
|
EndPropertyGrid();
|
||||||
});
|
});
|
||||||
@ -967,22 +1020,47 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
BeginPropertyGrid();
|
BeginPropertyGrid();
|
||||||
|
|
||||||
Property("Radius", scc.Radius);
|
if (Property("Radius", scc.Radius))
|
||||||
|
{
|
||||||
|
scc.DebugMesh = MeshFactory::CreateSphere(scc.Radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
Property("IsTrigger", scc.IsTrigger);
|
||||||
|
|
||||||
EndPropertyGrid();
|
EndPropertyGrid();
|
||||||
});
|
});
|
||||||
|
|
||||||
DrawComponent<MeshColliderComponent>("Mesh Collider", entity, [](MeshColliderComponent& mc)
|
DrawComponent<CapsuleColliderComponent>("Capsule Collider", entity, [](CapsuleColliderComponent& ccc)
|
||||||
|
{
|
||||||
|
BeginPropertyGrid();
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (Property("Radius", ccc.Radius)) changed = true;
|
||||||
|
if (Property("Height", ccc.Height)) changed = true;
|
||||||
|
|
||||||
|
Property("Is Trigger", ccc.IsTrigger);
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
ccc.DebugMesh = MeshFactory::CreateCapsule(ccc.Radius, ccc.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndPropertyGrid();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
DrawComponent<MeshColliderComponent>("Mesh Collider", entity, [](MeshColliderComponent& mcc)
|
||||||
{
|
{
|
||||||
ImGui::Columns(3);
|
ImGui::Columns(3);
|
||||||
ImGui::SetColumnWidth(0, 100);
|
ImGui::SetColumnWidth(0, 100);
|
||||||
ImGui::SetColumnWidth(1, 300);
|
ImGui::SetColumnWidth(1, 250);
|
||||||
ImGui::SetColumnWidth(2, 40);
|
ImGui::SetColumnWidth(2, 40);
|
||||||
ImGui::Text("File Path");
|
ImGui::Text("File Path");
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
ImGui::PushItemWidth(-1);
|
ImGui::PushItemWidth(-1);
|
||||||
if (mc.CollisionMesh)
|
if (mcc.CollisionMesh)
|
||||||
ImGui::InputText("##meshfilepath", (char*)mc.CollisionMesh->GetFilePath().c_str(), 256, ImGuiInputTextFlags_ReadOnly);
|
ImGui::InputText("##meshfilepath", (char*)mcc.CollisionMesh->GetFilePath().c_str(), 256, ImGuiInputTextFlags_ReadOnly);
|
||||||
else
|
else
|
||||||
ImGui::InputText("##meshfilepath", (char*)"Null", 256, ImGuiInputTextFlags_ReadOnly);
|
ImGui::InputText("##meshfilepath", (char*)"Null", 256, ImGuiInputTextFlags_ReadOnly);
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
@ -991,8 +1069,16 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
std::string file = Application::Get().OpenFile();
|
std::string file = Application::Get().OpenFile();
|
||||||
if (!file.empty())
|
if (!file.empty())
|
||||||
mc.CollisionMesh = Ref<Mesh>::Create(file);
|
{
|
||||||
|
mcc.CollisionMesh = Ref<Mesh>::Create(file);
|
||||||
|
PxPhysicsWrappers::CreateConvexMesh(mcc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ImGui::EndColumns();
|
||||||
|
|
||||||
|
BeginPropertyGrid();
|
||||||
|
Property("Is Trigger", mcc.IsTrigger);
|
||||||
|
EndPropertyGrid();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,9 @@ namespace Prism
|
|||||||
void DrawMeshNode(const Ref<Mesh>& mesh, uint32_t& imguiMeshID);
|
void DrawMeshNode(const Ref<Mesh>& mesh, uint32_t& imguiMeshID);
|
||||||
void DrawComponents(Entity entity);
|
void DrawComponents(Entity entity);
|
||||||
void MeshNodeHierarchy(const Ref<Mesh>& mesh, aiNode* node, const glm::mat4& parentTransform = glm::mat4(1.0f), uint32_t level = 0);
|
void MeshNodeHierarchy(const Ref<Mesh>& mesh, aiNode* node, const glm::mat4& parentTransform = glm::mat4(1.0f), uint32_t level = 0);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void AddComponentPopup(const char* componentName);
|
||||||
private:
|
private:
|
||||||
Ref<Scene> m_Context;
|
Ref<Scene> m_Context;
|
||||||
Entity m_SelectionContext;
|
Entity m_SelectionContext;
|
||||||
|
|||||||
@ -6,198 +6,170 @@
|
|||||||
|
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
#include <glm/gtx/matrix_decompose.hpp>
|
#include "glm/gtx/matrix_decompose.hpp"
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include "Prism/Scene/Entity.h"
|
||||||
#include <cooking/PxCooking.h>
|
|
||||||
|
#define PX_PHYSX_STATIC_LIB
|
||||||
|
#include <PxPhysicsAPI.h>
|
||||||
|
|
||||||
|
#include "PxPhysicsWrappers.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
// TODO: Kinematic Actors
|
static physx::PxScene* s_Scene = nullptr;
|
||||||
// TODO: Rotation/Position Locking
|
static std::vector<Entity> s_SimulatedEntities;
|
||||||
// TODO: Collision "layers"
|
static Entity* s_EntityStorageBuffer = nullptr;
|
||||||
// TODO: Expose more of the API to scripts
|
static int s_EntityStorageBufferPosition = 0;
|
||||||
// TODO: Connect/Disconnect PVD
|
|
||||||
// TODO: Collider Shape Rendering
|
|
||||||
// TODO: Relative Transformations for scripts
|
|
||||||
|
|
||||||
static physx::PxSimulationFilterShader s_DefaultFilterShader = physx::PxDefaultSimulationFilterShader;
|
static std::tuple<glm::vec3, glm::quat, glm::vec3> GetTransformDecomposition(const glm::mat4& transform)
|
||||||
|
|
||||||
static std::tuple<glm::vec3, glm::quat, glm::vec3> GetTransformDecomposition(const glm::mat4& transform)
|
|
||||||
{
|
|
||||||
glm::vec3 scale, translation, skew;
|
|
||||||
glm::vec4 perspective;
|
|
||||||
glm::quat orientation;
|
|
||||||
glm::decompose(transform, scale, orientation, translation, skew, perspective);
|
|
||||||
|
|
||||||
return { translation, orientation, scale };
|
|
||||||
}
|
|
||||||
|
|
||||||
static physx::PxFilterFlags PrismFilterShader(physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1, physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize)
|
|
||||||
{
|
|
||||||
if (physx::PxFilterObjectIsTrigger(attributes0) || physx::PxFilterObjectIsTrigger(attributes1))
|
|
||||||
{
|
|
||||||
pairFlags = physx::PxPairFlag::eTRIGGER_DEFAULT;
|
|
||||||
return physx::PxFilterFlag::eDEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
pairFlags = physx::PxPairFlag::eCONTACT_DEFAULT;
|
|
||||||
|
|
||||||
if ((filterData0.word0 & filterData1.word1) || (filterData1.word0 & filterData0.word1))
|
|
||||||
{
|
|
||||||
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_FOUND;
|
|
||||||
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_LOST;
|
|
||||||
}
|
|
||||||
|
|
||||||
return physx::PxFilterFlag::eDEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Physics3D::Init()
|
|
||||||
{
|
|
||||||
PM_CORE_ASSERT(!s_PXFoundation, "PhysXManager::Init shouldn't be called more than once!");
|
|
||||||
|
|
||||||
s_PXFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, s_PXAllocator, s_PXErrorCallback);
|
|
||||||
PM_CORE_ASSERT(s_PXFoundation, "PxCreateFoundation Failed!");
|
|
||||||
|
|
||||||
PM_CORE_INFO("Try to connect PVD...");
|
|
||||||
s_PXPvd = PxCreatePvd(*s_PXFoundation);
|
|
||||||
physx::PxPvdTransport* transport = physx::PxDefaultPvdSocketTransportCreate("localhost", 5425, 100000000);
|
|
||||||
const bool isConnect = s_PXPvd->connect(*transport, physx::PxPvdInstrumentationFlag::eALL);
|
|
||||||
if (isConnect)
|
|
||||||
{
|
|
||||||
PM_CORE_INFO("PVD connect success");
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
PM_CORE_ERROR("PVD connect failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
s_PXPhysicsFactory = PxCreatePhysics(PX_PHYSICS_VERSION, *s_PXFoundation, physx::PxTolerancesScale(), true, isConnect ? s_PXPvd : nullptr);
|
|
||||||
PM_CORE_ASSERT(s_PXPhysicsFactory, "PxCreatePhysics Failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Physics3D::Shutdown()
|
|
||||||
{
|
|
||||||
s_PXPhysicsFactory->release();
|
|
||||||
s_PXFoundation->release();
|
|
||||||
}
|
|
||||||
|
|
||||||
physx::PxSceneDesc Physics3D::CreateSceneDesc()
|
|
||||||
{
|
|
||||||
physx::PxSceneDesc sceneDesc(s_PXPhysicsFactory->getTolerancesScale());
|
|
||||||
if (!sceneDesc.cpuDispatcher)
|
|
||||||
{
|
|
||||||
physx::PxDefaultCpuDispatcher* mCpuDispatcher = physx::PxDefaultCpuDispatcherCreate(4);
|
|
||||||
PM_CORE_ASSERT(mCpuDispatcher);
|
|
||||||
sceneDesc.cpuDispatcher = mCpuDispatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sceneDesc.filterShader)
|
|
||||||
sceneDesc.filterShader = PrismFilterShader;
|
|
||||||
|
|
||||||
return sceneDesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
physx::PxScene* Physics3D::CreateScene(const physx::PxSceneDesc& sceneDesc)
|
|
||||||
{
|
|
||||||
return s_PXPhysicsFactory->createScene(sceneDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
physx::PxRigidActor* Physics3D::CreateAndAddActor(physx::PxScene* scene, const RigidBodyComponent& rigidbody, const glm::mat4& transform)
|
|
||||||
{
|
{
|
||||||
physx::PxRigidActor* actor = nullptr;
|
glm::vec3 scale, translation, skew;
|
||||||
|
glm::vec4 perspective;
|
||||||
|
glm::quat orientation;
|
||||||
|
glm::decompose(transform, scale, orientation, translation, skew, perspective);
|
||||||
|
|
||||||
|
return { translation, orientation, scale };
|
||||||
|
}
|
||||||
|
|
||||||
|
void Physics3D::Init()
|
||||||
|
{
|
||||||
|
PxPhysicsWrappers::Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Physics3D::Shutdown()
|
||||||
|
{
|
||||||
|
PxPhysicsWrappers::Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Physics3D::CreateScene(const SceneParams& params)
|
||||||
|
{
|
||||||
|
PM_CORE_ASSERT(s_Scene == nullptr, "Scene already has a Physics Scene!");
|
||||||
|
s_Scene = PxPhysicsWrappers::CreateScene(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Physics3D::CreateActor(Entity e, int entityCount)
|
||||||
|
{
|
||||||
|
if (!e.HasComponent<RigidBodyComponent>())
|
||||||
|
{
|
||||||
|
PM_CORE_WARN("Trying to create PhysX actor from a non-rigidbody actor!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!e.HasComponent<PhysicsMaterialComponent>())
|
||||||
|
{
|
||||||
|
PM_CORE_WARN("Trying to create PhysX actor without a PhysicsMaterialComponent!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RigidBodyComponent& rigidbody = e.GetComponent<RigidBodyComponent>();
|
||||||
|
|
||||||
|
if (s_EntityStorageBuffer == nullptr)
|
||||||
|
s_EntityStorageBuffer = new Entity[entityCount];
|
||||||
|
|
||||||
|
// Create Actor Body
|
||||||
|
physx::PxRigidActor* actor = PxPhysicsWrappers::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>());
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.HasComponent<SphereColliderComponent>())
|
||||||
|
{
|
||||||
|
const SphereColliderComponent& collider = e.GetComponent<SphereColliderComponent>();
|
||||||
|
PxPhysicsWrappers::AddSphereCollider(*actor, *material, collider, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.HasComponent<CapsuleColliderComponent>())
|
||||||
|
{
|
||||||
|
const CapsuleColliderComponent& collider = e.GetComponent<CapsuleColliderComponent>();
|
||||||
|
PxPhysicsWrappers::AddCapsuleCollider(*actor, *material, collider, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.HasComponent<MeshColliderComponent>())
|
||||||
|
{
|
||||||
|
MeshColliderComponent& collider = e.GetComponent<MeshColliderComponent>();
|
||||||
|
PxPhysicsWrappers::AddMeshCollider(*actor, *material, collider, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set collision filters
|
||||||
if (rigidbody.BodyType == RigidBodyComponent::Type::Static)
|
if (rigidbody.BodyType == RigidBodyComponent::Type::Static)
|
||||||
{
|
{
|
||||||
actor = s_PXPhysicsFactory->createRigidStatic(CreatePose(transform));
|
PxPhysicsWrappers::SetCollisionFilters(*actor, (uint32_t)FilterGroup::Static, (uint32_t)FilterGroup::All);
|
||||||
}
|
}
|
||||||
else if (rigidbody.BodyType == RigidBodyComponent::Type::Dynamic)
|
else if (rigidbody.BodyType == RigidBodyComponent::Type::Dynamic)
|
||||||
{
|
{
|
||||||
physx::PxRigidDynamic* dynamicActor = s_PXPhysicsFactory->createRigidDynamic(CreatePose(transform));
|
PxPhysicsWrappers::SetCollisionFilters(*actor, (uint32_t)FilterGroup::Dynamic, (uint32_t)FilterGroup::All);
|
||||||
physx::PxRigidBodyExt::updateMassAndInertia(*dynamicActor, rigidbody.Mass);
|
|
||||||
|
|
||||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X, rigidbody.LockPositionX);
|
|
||||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y, rigidbody.LockPositionY);
|
|
||||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z, rigidbody.LockPositionZ);
|
|
||||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, rigidbody.LockRotationX);
|
|
||||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, rigidbody.LockRotationY);
|
|
||||||
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, rigidbody.LockRotationZ);
|
|
||||||
|
|
||||||
actor = dynamicActor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
actor->setActorFlag(physx::PxActorFlag::eVISUALIZATION, true);
|
s_Scene->addActor(*actor);
|
||||||
|
|
||||||
scene->addActor(*actor);
|
|
||||||
|
|
||||||
return actor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
physx::PxMaterial* Physics3D::CreateMaterial(float staticFriction, float dynamicFriction, float restitution)
|
void Physics3D::Simulate(TimeStep ts)
|
||||||
{
|
{
|
||||||
return s_PXPhysicsFactory->createMaterial(staticFriction, dynamicFriction, restitution);
|
s_Scene->simulate(ts);
|
||||||
}
|
s_Scene->fetchResults(true);
|
||||||
|
|
||||||
physx::PxConvexMesh* Physics3D::CreateMeshCollider(const Ref<Mesh>& mesh)
|
for (Entity& e : s_SimulatedEntities)
|
||||||
{
|
|
||||||
const auto& vertices = mesh->GetStaticVertices();
|
|
||||||
const auto& indices = mesh->GetIndices();
|
|
||||||
const physx::PxCookingParams cookingParams(s_PXPhysicsFactory->getTolerancesScale());
|
|
||||||
|
|
||||||
physx::PxConvexMeshDesc convexDesc;
|
|
||||||
convexDesc.points.count = (physx::PxU32)vertices.size();
|
|
||||||
convexDesc.points.stride = sizeof(Vertex);
|
|
||||||
convexDesc.points.data = vertices.data();
|
|
||||||
convexDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX;
|
|
||||||
|
|
||||||
const physx::PxDefaultMemoryOutputStream buf;
|
|
||||||
physx::PxConvexMeshCookingResult::Enum result;
|
|
||||||
|
|
||||||
physx::PxConvexMesh* convexMesh = PxCreateConvexMesh(
|
|
||||||
cookingParams, // 第一步准备的烹饪参数
|
|
||||||
convexDesc, // 第二步准备的网格描述
|
|
||||||
*PxGetStandaloneInsertionCallback(), // 便捷的回调函数,用于将资源插入物理SDK
|
|
||||||
&result // [可选] 获取烹饪结果详情
|
|
||||||
);
|
|
||||||
if (!convexMesh) {
|
|
||||||
PM_CORE_ERROR("Failed to create convex mesh. Cooking result code: {}", static_cast<int>(result));
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return convexMesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
physx::PxTransform Physics3D::CreatePose(const glm::mat4& transform)
|
|
||||||
{
|
|
||||||
auto [translation, rotationQuat, scale] = GetTransformDecomposition(transform);
|
|
||||||
const glm::vec3 rotation = glm::eulerAngles(rotationQuat);
|
|
||||||
|
|
||||||
physx::PxTransform physxTransform(physx::PxVec3(translation.x, translation.y, translation.z));
|
|
||||||
physxTransform.rotate(physx::PxVec3(rotation.x, rotation.y, rotation.z));
|
|
||||||
return physxTransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Physics3D::SetCollisionFilters(physx::PxRigidActor* actor, uint32_t filterGroup, uint32_t filterMask)
|
|
||||||
{
|
|
||||||
physx::PxFilterData filterData;
|
|
||||||
filterData.word0 = filterGroup; // word0 = own ID
|
|
||||||
filterData.word1 = filterMask; // word1 = ID mask to filter pairs that trigger a
|
|
||||||
// contact callback;
|
|
||||||
const physx::PxU32 numShapes = actor->getNbShapes();
|
|
||||||
physx::PxShape** shapes = (physx::PxShape**)s_PXAllocator.allocate(sizeof(physx::PxShape*) * numShapes, "", "", 0);
|
|
||||||
actor->getShapes(shapes, numShapes);
|
|
||||||
for (physx::PxU32 i = 0; i < numShapes; i++)
|
|
||||||
{
|
{
|
||||||
physx::PxShape* shape = shapes[i];
|
auto& transform = e.Transform();
|
||||||
shape->setFlag(physx::PxShapeFlag::eVISUALIZATION, true);
|
// TODO: Come up with a better solution for scale
|
||||||
shape->setSimulationFilterData(filterData);
|
auto [p, r, scale] = GetTransformDecomposition(transform);
|
||||||
}
|
const auto& rb = e.GetComponent<RigidBodyComponent>();
|
||||||
|
const auto actor = static_cast<physx::PxRigidActor*>(rb.RuntimeActor);
|
||||||
|
|
||||||
s_PXAllocator.deallocate(shapes);
|
if (rb.BodyType == RigidBodyComponent::Type::Dynamic)
|
||||||
|
{
|
||||||
|
transform = FromPhysXTransform(actor->getGlobalPose()) * glm::scale(glm::mat4(1.0f), scale);
|
||||||
|
}
|
||||||
|
else if (rb.BodyType == RigidBodyComponent::Type::Static)
|
||||||
|
{
|
||||||
|
actor->setGlobalPose(ToPhysXTransform(transform));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
physx::PxDefaultErrorCallback Physics3D::s_PXErrorCallback;
|
void Physics3D::DestroyScene()
|
||||||
physx::PxDefaultAllocator Physics3D::s_PXAllocator;
|
{
|
||||||
physx::PxFoundation* Physics3D::s_PXFoundation;
|
delete[] s_EntityStorageBuffer;
|
||||||
physx::PxPhysics* Physics3D::s_PXPhysicsFactory;
|
s_EntityStorageBuffer = nullptr;
|
||||||
physx::PxPvd* Physics3D::s_PXPvd;
|
s_EntityStorageBufferPosition = 0;
|
||||||
}
|
|
||||||
|
s_SimulatedEntities.clear();
|
||||||
|
s_Scene->release();
|
||||||
|
s_Scene = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Physics3D::ConnectPVD()
|
||||||
|
{
|
||||||
|
PM_CORE_INFO("Trying to connect PVD");
|
||||||
|
const bool isconnect = PxPhysicsWrappers::ConnectPVD();
|
||||||
|
if (isconnect)
|
||||||
|
PM_CORE_INFO("PVD Connected");
|
||||||
|
else
|
||||||
|
PM_CORE_WARN("canot connect PVD!");
|
||||||
|
return isconnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Physics3D::IsPVDConnected() {return PxPhysicsWrappers::IsPVDConnected();}
|
||||||
|
|
||||||
|
void Physics3D::DisconnectPVD()
|
||||||
|
{
|
||||||
|
PxPhysicsWrappers::DisconnectPVD();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
#ifndef PHYSXMANAGER_H
|
#ifndef PHYSXMANAGER_H
|
||||||
#define PHYSXMANAGER_H
|
#define PHYSXMANAGER_H
|
||||||
#define PX_PHYSX_STATIC_LIB
|
|
||||||
#include <PxPhysicsAPI.h>
|
|
||||||
#include "glm/glm.hpp"
|
#include "glm/glm.hpp"
|
||||||
#include "Prism/Scene/Components.h"
|
#include "Prism/Scene/Components.h"
|
||||||
|
#include "Prism/Scene/Entity.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
@ -21,10 +21,15 @@ namespace Prism
|
|||||||
|
|
||||||
enum class FilterGroup : uint32_t
|
enum class FilterGroup : uint32_t
|
||||||
{
|
{
|
||||||
Static = BIT(0),
|
Static = BIT(0),
|
||||||
Dynamic = BIT(1),
|
Dynamic = BIT(1),
|
||||||
Kinematic = BIT(2),
|
Kinematic = BIT(2),
|
||||||
All = Static | Dynamic | Kinematic
|
All = Static | Dynamic | Kinematic
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SceneParams
|
||||||
|
{
|
||||||
|
glm::vec3 Gravity = { 0.0F, -9.81F, 0.0F };
|
||||||
};
|
};
|
||||||
|
|
||||||
class PRISM_API Physics3D
|
class PRISM_API Physics3D
|
||||||
@ -33,22 +38,16 @@ namespace Prism
|
|||||||
static void Init();
|
static void Init();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
static physx::PxSceneDesc CreateSceneDesc();
|
static void CreateScene(const SceneParams& params);
|
||||||
static physx::PxScene* CreateScene(const physx::PxSceneDesc& sceneDesc);
|
static void CreateActor(Entity e, int entityCount);
|
||||||
static physx::PxRigidActor* CreateAndAddActor(physx::PxScene* scene, const RigidBodyComponent& rigidbody, const glm::mat4& transform);
|
|
||||||
static physx::PxMaterial* CreateMaterial(float staticFriction, float dynamicFriction, float restitution);
|
|
||||||
static physx::PxConvexMesh* CreateMeshCollider(const Ref<Mesh>& mesh);
|
|
||||||
|
|
||||||
static physx::PxTransform CreatePose(const glm::mat4& transform);
|
static void Simulate(TimeStep ts);
|
||||||
|
|
||||||
static void SetCollisionFilters(physx::PxRigidActor* actor, uint32_t filterGroup, uint32_t filterMask);
|
static void DestroyScene();
|
||||||
|
|
||||||
// private:
|
static bool ConnectPVD();
|
||||||
static physx::PxDefaultErrorCallback s_PXErrorCallback;
|
static bool IsPVDConnected();
|
||||||
static physx::PxDefaultAllocator s_PXAllocator;
|
static void DisconnectPVD();
|
||||||
static physx::PxFoundation* s_PXFoundation;
|
|
||||||
static physx::PxPhysics* s_PXPhysicsFactory;
|
|
||||||
static physx::PxPvd* s_PXPvd;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
149
Prism/src/Prism/Physics/PhysicsUtils.cpp
Normal file
149
Prism/src/Prism/Physics/PhysicsUtils.cpp
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-12-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "PhysicsUtils.h"
|
||||||
|
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include "glm/gtx/quaternion.hpp"
|
||||||
|
#include "Prism/Script/ScriptEngine.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
physx::PxTransform ToPhysXTransform(const glm::mat4& matrix)
|
||||||
|
{
|
||||||
|
const physx::PxQuat r = ToPhysXQuat(glm::normalize(glm::toQuat(matrix)));
|
||||||
|
const physx::PxVec3 p = ToPhysXVector(glm::vec3(matrix[3]));
|
||||||
|
return physx::PxTransform{p, r};
|
||||||
|
}
|
||||||
|
|
||||||
|
physx::PxMat44 ToPhysXMatrix(const glm::mat4& matrix)
|
||||||
|
{
|
||||||
|
return *(physx::PxMat44*)&matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
physx::PxVec3 ToPhysXVector(const glm::vec3& vector)
|
||||||
|
{
|
||||||
|
return {vector.x, vector.y, vector.z};
|
||||||
|
}
|
||||||
|
|
||||||
|
physx::PxVec4 ToPhysXVector(const glm::vec4& vector)
|
||||||
|
{
|
||||||
|
return {vector.x, vector.y, vector.z, vector.w};
|
||||||
|
}
|
||||||
|
|
||||||
|
physx::PxQuat ToPhysXQuat(const glm::quat& quat)
|
||||||
|
{
|
||||||
|
return {quat.x, quat.y, quat.z, quat.w};
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 FromPhysXTransform(const physx::PxTransform& transform)
|
||||||
|
{
|
||||||
|
glm::quat rotation = FromPhysXQuat(transform.q);
|
||||||
|
glm::vec3 position = FromPhysXVector(transform.p);
|
||||||
|
return glm::translate(glm::mat4(1.0F), position) * glm::toMat4(rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 FromPhysXMatrix(const physx::PxMat44& matrix)
|
||||||
|
{
|
||||||
|
return *(glm::mat4*)&matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 FromPhysXVector(const physx::PxVec3& vector)
|
||||||
|
{
|
||||||
|
return {vector.x, vector.y, vector.z};
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec4 FromPhysXVector(const physx::PxVec4& vector)
|
||||||
|
{
|
||||||
|
return {vector.x, vector.y, vector.z, vector.w};
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat FromPhysXQuat(const physx::PxQuat& quat)
|
||||||
|
{
|
||||||
|
return {quat.w, quat.x, quat.y, quat.z};
|
||||||
|
}
|
||||||
|
|
||||||
|
physx::PxFilterFlags HazelFilterShader(physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1, physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize)
|
||||||
|
{
|
||||||
|
if (physx::PxFilterObjectIsTrigger(attributes0) || physx::PxFilterObjectIsTrigger(attributes1))
|
||||||
|
{
|
||||||
|
pairFlags = physx::PxPairFlag::eTRIGGER_DEFAULT;
|
||||||
|
return physx::PxFilterFlag::eDEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pairFlags = physx::PxPairFlag::eCONTACT_DEFAULT;
|
||||||
|
|
||||||
|
if ((filterData0.word0 & filterData1.word1) || (filterData1.word0 & filterData0.word1))
|
||||||
|
{
|
||||||
|
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_FOUND;
|
||||||
|
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_LOST;
|
||||||
|
}
|
||||||
|
|
||||||
|
return physx::PxFilterFlag::eDEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactListener::onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count)
|
||||||
|
{
|
||||||
|
PX_UNUSED(constraints);
|
||||||
|
PX_UNUSED(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactListener::onWake(physx::PxActor** actors, physx::PxU32 count)
|
||||||
|
{
|
||||||
|
PX_UNUSED(actors);
|
||||||
|
PX_UNUSED(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactListener::onSleep(physx::PxActor** actors, physx::PxU32 count)
|
||||||
|
{
|
||||||
|
PX_UNUSED(actors);
|
||||||
|
PX_UNUSED(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactListener::onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs)
|
||||||
|
{
|
||||||
|
const Entity& a = *static_cast<Entity*>(pairHeader.actors[0]->userData);
|
||||||
|
const Entity& b = *static_cast<Entity*>(pairHeader.actors[1]->userData);
|
||||||
|
|
||||||
|
if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_HAS_FIRST_TOUCH)
|
||||||
|
{
|
||||||
|
if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnCollisionBegin(a);
|
||||||
|
if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnCollisionBegin(b);
|
||||||
|
}
|
||||||
|
else if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_LOST_TOUCH)
|
||||||
|
{
|
||||||
|
if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnCollisionEnd(a);
|
||||||
|
if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnCollisionEnd(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactListener::onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count)
|
||||||
|
{
|
||||||
|
|
||||||
|
const Entity& a = *static_cast<Entity*>(pairs->triggerActor->userData);
|
||||||
|
const Entity& b = *static_cast<Entity*>(pairs->otherActor->userData);
|
||||||
|
|
||||||
|
if (pairs->status == physx::PxPairFlag::eNOTIFY_TOUCH_FOUND)
|
||||||
|
{
|
||||||
|
if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnTriggerBegin(a);
|
||||||
|
if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnTriggerBegin(b);
|
||||||
|
}
|
||||||
|
else if (pairs->status == physx::PxPairFlag::eNOTIFY_TOUCH_LOST)
|
||||||
|
{
|
||||||
|
if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnTriggerEnd(a);
|
||||||
|
if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnTriggerEnd(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
PX_UNUSED(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactListener::onAdvance(const physx::PxRigidBody* const* bodyBuffer, const physx::PxTransform* poseBuffer, const physx::PxU32 count)
|
||||||
|
{
|
||||||
|
PX_UNUSED(bodyBuffer);
|
||||||
|
PX_UNUSED(poseBuffer);
|
||||||
|
PX_UNUSED(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
46
Prism/src/Prism/Physics/PhysicsUtils.h
Normal file
46
Prism/src/Prism/Physics/PhysicsUtils.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-12-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef PHYSICSUTILS_H
|
||||||
|
#define PHYSICSUTILS_H
|
||||||
|
|
||||||
|
#define PX_PHYSX_STATIC_LIB
|
||||||
|
#include <PxPhysicsAPI.h>
|
||||||
|
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
|
||||||
|
physx::PxTransform ToPhysXTransform(const glm::mat4& matrix);
|
||||||
|
physx::PxMat44 ToPhysXMatrix(const glm::mat4& matrix);
|
||||||
|
physx::PxVec3 ToPhysXVector(const glm::vec3& vector);
|
||||||
|
physx::PxVec4 ToPhysXVector(const glm::vec4& vector);
|
||||||
|
physx::PxQuat ToPhysXQuat(const glm::quat& quat);
|
||||||
|
|
||||||
|
glm::mat4 FromPhysXTransform(const physx::PxTransform& transform);
|
||||||
|
glm::mat4 FromPhysXMatrix(const physx::PxMat44& matrix);
|
||||||
|
glm::vec3 FromPhysXVector(const physx::PxVec3& vector);
|
||||||
|
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::PxFilterData filterData1, physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize);
|
||||||
|
|
||||||
|
class ContactListener final : public physx::PxSimulationEventCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count) override;
|
||||||
|
virtual void onWake(physx::PxActor** actors, physx::PxU32 count) override;
|
||||||
|
virtual void onSleep(physx::PxActor** actors, physx::PxU32 count) override;
|
||||||
|
virtual void onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) override;
|
||||||
|
virtual void onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count) override;
|
||||||
|
virtual void onAdvance(const physx::PxRigidBody* const* bodyBuffer, const physx::PxTransform* poseBuffer, physx::PxU32 count) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //PHYSICSUTILS_H
|
||||||
282
Prism/src/Prism/Physics/PxPhysicsWrappers.cpp
Normal file
282
Prism/src/Prism/Physics/PxPhysicsWrappers.cpp
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-12-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "PxPhysicsWrappers.h"
|
||||||
|
#include "Physics3D.h"
|
||||||
|
#include <cooking/PxCooking.h>
|
||||||
|
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/gtx/rotate_vector.hpp>
|
||||||
|
|
||||||
|
#define PHYSX_DEBUGGER 1
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
static physx::PxDefaultErrorCallback s_ErrorCallback;
|
||||||
|
static physx::PxDefaultAllocator s_Allocator;
|
||||||
|
static physx::PxFoundation* s_Foundation;
|
||||||
|
static physx::PxPhysics* s_Physics;
|
||||||
|
static physx::PxPvd* s_VisualDebugger;
|
||||||
|
|
||||||
|
static physx::PxSimulationFilterShader s_FilterShader = physx::PxDefaultSimulationFilterShader;
|
||||||
|
|
||||||
|
static ContactListener s_ContactListener;
|
||||||
|
|
||||||
|
physx::PxScene* PxPhysicsWrappers::CreateScene(const SceneParams& sceneParams)
|
||||||
|
{
|
||||||
|
physx::PxSceneDesc sceneDesc(s_Physics->getTolerancesScale());
|
||||||
|
|
||||||
|
sceneDesc.gravity = ToPhysXVector(sceneParams.Gravity);
|
||||||
|
sceneDesc.cpuDispatcher = physx::PxDefaultCpuDispatcherCreate(1);
|
||||||
|
sceneDesc.filterShader = HazelFilterShader;
|
||||||
|
sceneDesc.simulationEventCallback = &s_ContactListener;
|
||||||
|
|
||||||
|
PM_CORE_ASSERT(sceneDesc.isValid());
|
||||||
|
return s_Physics->createScene(sceneDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
physx::PxRigidActor* PxPhysicsWrappers::CreateActor(const RigidBodyComponent& rigidbody, const glm::mat4& transform)
|
||||||
|
{
|
||||||
|
physx::PxRigidActor* actor = nullptr;
|
||||||
|
|
||||||
|
if (rigidbody.BodyType == RigidBodyComponent::Type::Static)
|
||||||
|
{
|
||||||
|
actor = s_Physics->createRigidStatic(ToPhysXTransform(transform));
|
||||||
|
}
|
||||||
|
else if (rigidbody.BodyType == RigidBodyComponent::Type::Dynamic)
|
||||||
|
{
|
||||||
|
physx::PxRigidDynamic* dynamicActor = s_Physics->createRigidDynamic(ToPhysXTransform(transform));
|
||||||
|
|
||||||
|
dynamicActor->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, rigidbody.IsKinematic);
|
||||||
|
|
||||||
|
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X, rigidbody.LockPositionX);
|
||||||
|
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y, rigidbody.LockPositionY);
|
||||||
|
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z, rigidbody.LockPositionZ);
|
||||||
|
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, rigidbody.LockRotationX);
|
||||||
|
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, rigidbody.LockRotationY);
|
||||||
|
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, rigidbody.LockRotationZ);
|
||||||
|
|
||||||
|
physx::PxRigidBodyExt::updateMassAndInertia(*dynamicActor, rigidbody.Mass);
|
||||||
|
actor = dynamicActor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return actor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PxPhysicsWrappers::SetCollisionFilters(const physx::PxRigidActor& actor, const uint32_t actorGroup, const uint32_t filters)
|
||||||
|
{
|
||||||
|
physx::PxFilterData filterData;
|
||||||
|
filterData.word0 = actorGroup;
|
||||||
|
filterData.word1 = filters;
|
||||||
|
|
||||||
|
const physx::PxU32 numShapes = actor.getNbShapes();
|
||||||
|
|
||||||
|
const auto shapes = static_cast<physx::PxShape**>(s_Allocator.allocate(sizeof(physx::PxShape*) * numShapes, "", "", 0));
|
||||||
|
actor.getShapes(shapes, numShapes);
|
||||||
|
|
||||||
|
for (physx::PxU32 i = 0; i < numShapes; i++)
|
||||||
|
shapes[i]->setSimulationFilterData(filterData);
|
||||||
|
|
||||||
|
s_Allocator.deallocate(shapes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PxPhysicsWrappers::AddBoxCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const BoxColliderComponent& collider, const glm::vec3& scale)
|
||||||
|
{
|
||||||
|
glm::vec3 colliderSize = collider.Size;
|
||||||
|
|
||||||
|
if (scale.x != 0.0f) colliderSize.x *= scale.x;
|
||||||
|
if (scale.y != 0.0f) colliderSize.y *= scale.y;
|
||||||
|
if (scale.z != 0.0f) colliderSize.z *= scale.z;
|
||||||
|
|
||||||
|
const auto boxGeometry = physx::PxBoxGeometry(colliderSize.x / 2.0f, colliderSize.y / 2.0f, colliderSize.z / 2.0f);
|
||||||
|
|
||||||
|
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, boxGeometry, material);
|
||||||
|
shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger);
|
||||||
|
shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
float colliderRadius = collider.Radius;
|
||||||
|
|
||||||
|
if (scale.x != 0.0f) colliderRadius *= scale.x;
|
||||||
|
|
||||||
|
const auto sphereGeometry = physx::PxSphereGeometry(colliderRadius);
|
||||||
|
|
||||||
|
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, sphereGeometry, material);
|
||||||
|
shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
float colliderRadius = collider.Radius;
|
||||||
|
float colliderHeight = collider.Height;
|
||||||
|
|
||||||
|
if (scale.x != 0.0F) colliderRadius *= scale.x * 0.5f;
|
||||||
|
if (scale.y != 0.0F) colliderHeight *= scale.y;
|
||||||
|
|
||||||
|
|
||||||
|
const auto capsuleGeometry = physx::PxCapsuleGeometry(colliderRadius, colliderHeight / 2.0F);
|
||||||
|
|
||||||
|
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, capsuleGeometry, material);
|
||||||
|
shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger);
|
||||||
|
shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger);
|
||||||
|
|
||||||
|
shape->setLocalPose(physx::PxTransform(physx::PxQuat(physx::PxHalfPi, physx::PxVec3(0, 0, 1))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PxPhysicsWrappers::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);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
const auto& vertices = collider.CollisionMesh->GetStaticVertices();
|
||||||
|
|
||||||
|
const physx::PxCookingParams cookingParams(s_Physics->getTolerancesScale());
|
||||||
|
|
||||||
|
physx::PxConvexMeshDesc convexDesc;
|
||||||
|
convexDesc.points.count = static_cast<physx::PxU32>(vertices.size());
|
||||||
|
convexDesc.points.stride = sizeof(Vertex);
|
||||||
|
convexDesc.points.data = vertices.data();
|
||||||
|
convexDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX;
|
||||||
|
|
||||||
|
physx::PxDefaultMemoryOutputStream buf;
|
||||||
|
physx::PxConvexMeshCookingResult::Enum result;
|
||||||
|
physx::PxConvexMesh* mesh = PxCreateConvexMesh(
|
||||||
|
cookingParams, // 第一步准备的烹饪参数
|
||||||
|
convexDesc, // 第二步准备的网格描述
|
||||||
|
*PxGetStandaloneInsertionCallback(), // 便捷的回调函数,用于将资源插入物理SDK
|
||||||
|
&result // [可选] 获取烹饪结果详情
|
||||||
|
);
|
||||||
|
if (!collider.ProcessedMesh)
|
||||||
|
{
|
||||||
|
// Based On: https://github.com/EpicGames/UnrealEngine/blob/08ee319f80ef47dbf0988e14b546b65214838ec4/Engine/Source/ThirdParty/PhysX3/NvCloth/samples/SampleBase/renderer/ConvexRenderMesh.cpp
|
||||||
|
|
||||||
|
const uint32_t nbPolygons = mesh->getNbPolygons();
|
||||||
|
const physx::PxVec3* convexVertices = mesh->getVertices();
|
||||||
|
const physx::PxU8* convexIndices = mesh->getIndexBuffer();
|
||||||
|
|
||||||
|
uint32_t nbVertices = 0;
|
||||||
|
uint32_t nbFaces = 0;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < nbPolygons; i++)
|
||||||
|
{
|
||||||
|
physx::PxHullPolygon polygon;
|
||||||
|
mesh->getPolygonData(i, polygon);
|
||||||
|
nbVertices += polygon.mNbVerts;
|
||||||
|
nbFaces += (polygon.mNbVerts - 2) * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Vertex> collisionVertices;
|
||||||
|
std::vector<Index> collisionIndices;
|
||||||
|
|
||||||
|
collisionVertices.resize(nbVertices);
|
||||||
|
collisionIndices.resize(nbFaces / 3);
|
||||||
|
|
||||||
|
uint32_t vertCounter = 0;
|
||||||
|
uint32_t indexCounter = 0;
|
||||||
|
for (uint32_t i = 0; i < nbPolygons; i++)
|
||||||
|
{
|
||||||
|
physx::PxHullPolygon polygon;
|
||||||
|
mesh->getPolygonData(i, polygon);
|
||||||
|
|
||||||
|
const uint32_t vI0 = vertCounter;
|
||||||
|
for (uint32_t vI = 0; vI < polygon.mNbVerts; vI++)
|
||||||
|
{
|
||||||
|
// collisionVertices[vertCounter].Position = FromPhysXVector(convexVertices[convexIndices[polygon.mIndexBase + vI]]);
|
||||||
|
// TODO: temp solve
|
||||||
|
// this glm::rotate need #include <glm/gtx/rotate_vector.hpp>
|
||||||
|
collisionVertices[vertCounter].Position = glm::rotate(FromPhysXVector(convexVertices[convexIndices[polygon.mIndexBase + vI]]), glm::radians(90.0f), { 1.0f, 0.0f, 0.0f});
|
||||||
|
vertCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t vI = 1; vI < static_cast<uint32_t>(polygon.mNbVerts) - 1; vI++)
|
||||||
|
{
|
||||||
|
collisionIndices[indexCounter].V1 = static_cast<uint32_t>(vI0);
|
||||||
|
collisionIndices[indexCounter].V2 = static_cast<uint32_t>(vI0 + vI + 1);
|
||||||
|
collisionIndices[indexCounter].V3 = static_cast<uint32_t>(vI0 + vI);
|
||||||
|
indexCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collider.ProcessedMesh = Ref<Mesh>::Create(collisionVertices, collisionIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
physx::PxMaterial* PxPhysicsWrappers::CreateMaterial(const PhysicsMaterialComponent& material)
|
||||||
|
{
|
||||||
|
return s_Physics->createMaterial(material.StaticFriction, material.DynamicFriction, material.Bounciness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PxPhysicsWrappers::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
|
||||||
|
s_VisualDebugger = PxCreatePvd(*s_Foundation);
|
||||||
|
ConnectPVD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
s_Physics = PxCreatePhysics(PX_PHYSICS_VERSION, *s_Foundation, physx::PxTolerancesScale(), true, s_VisualDebugger);
|
||||||
|
PM_CORE_ASSERT(s_Physics, "PxCreatePhysics Failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PxPhysicsWrappers::Shutdown()
|
||||||
|
{
|
||||||
|
s_Physics->release();
|
||||||
|
s_Foundation->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PxPhysicsWrappers::ConnectPVD()
|
||||||
|
{
|
||||||
|
bool isConnect = false;
|
||||||
|
#if PHYSX_DEBUGGER
|
||||||
|
physx::PxPvdTransport* transport = physx::PxDefaultPvdSocketTransportCreate("localhost", 5425, 10);
|
||||||
|
if (s_VisualDebugger->isConnected())
|
||||||
|
{
|
||||||
|
PM_CORE_WARN("PVD is already connected, reconnecting");
|
||||||
|
s_VisualDebugger->disconnect();
|
||||||
|
}
|
||||||
|
isConnect = s_VisualDebugger->connect(*transport, physx::PxPvdInstrumentationFlag::eALL);
|
||||||
|
#endif
|
||||||
|
return isConnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PxPhysicsWrappers::IsPVDConnected()
|
||||||
|
{
|
||||||
|
return s_VisualDebugger->isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PxPhysicsWrappers::DisconnectPVD()
|
||||||
|
{
|
||||||
|
#if PHYSX_DEBUGGER
|
||||||
|
if (s_VisualDebugger->isConnected(false))
|
||||||
|
{
|
||||||
|
s_VisualDebugger->disconnect();
|
||||||
|
PM_CORE_INFO("PVD is disconnected");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
46
Prism/src/Prism/Physics/PxPhysicsWrappers.h
Normal file
46
Prism/src/Prism/Physics/PxPhysicsWrappers.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-12-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef PXPHYSICSWRAPPERS_H
|
||||||
|
#define PXPHYSICSWRAPPERS_H
|
||||||
|
|
||||||
|
#include "PhysicsUtils.h"
|
||||||
|
#include "Prism/Scene/Components.h"
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
struct SceneParams;
|
||||||
|
|
||||||
|
class PxPhysicsWrappers
|
||||||
|
{
|
||||||
|
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 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);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void Initialize();
|
||||||
|
static void Shutdown();
|
||||||
|
|
||||||
|
static bool ConnectPVD();
|
||||||
|
static bool IsPVDConnected();
|
||||||
|
static void DisconnectPVD();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Physics3D;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //PXPHYSICSWRAPPERS_H
|
||||||
@ -42,6 +42,20 @@ namespace Prism
|
|||||||
double xpos, ypos;
|
double xpos, ypos;
|
||||||
glfwGetCursorPos(static_cast<GLFWwindow*>(window.GetNativeWindow()), &xpos, &ypos);
|
glfwGetCursorPos(static_cast<GLFWwindow*>(window.GetNativeWindow()), &xpos, &ypos);
|
||||||
|
|
||||||
return {(float)xpos, (float)ypos};
|
return {static_cast<float>(xpos), static_cast<float>(ypos)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: A better way to do this is to handle it internally, and simply move the cursor the opposite side
|
||||||
|
// of the screen when it reaches the edge
|
||||||
|
void Input::SetCursorMode(CursorMode mode)
|
||||||
|
{
|
||||||
|
const auto& window = dynamic_cast<WindowsWindow&>(Application::Get().GetWindow());
|
||||||
|
glfwSetInputMode(static_cast<GLFWwindow*>(window.GetNativeWindow()), GLFW_CURSOR, GLFW_CURSOR_NORMAL + static_cast<int>(mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorMode Input::GetCursorMode()
|
||||||
|
{
|
||||||
|
const auto& window = dynamic_cast<WindowsWindow&>(Application::Get().GetWindow());
|
||||||
|
return static_cast<CursorMode>(glfwGetInputMode(static_cast<GLFWwindow*>(window.GetNativeWindow()), GLFW_CURSOR) - GLFW_CURSOR_NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,9 +43,8 @@ namespace Prism
|
|||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
glfwSwapBuffers(m_Window);
|
glfwSwapBuffers(m_Window);
|
||||||
|
|
||||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
const ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||||
glfwSetCursor(m_Window, m_ImGuiMouseCursors[imgui_cursor] ? m_ImGuiMouseCursors[imgui_cursor] : m_ImGuiMouseCursors[ImGuiMouseCursor_Arrow]);
|
glfwSetCursor(m_Window, m_ImGuiMouseCursors[imgui_cursor] ? m_ImGuiMouseCursors[imgui_cursor] : m_ImGuiMouseCursors[ImGuiMouseCursor_Arrow]);
|
||||||
glfwSetInputMode(m_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowsWindow::SetVSync(bool enable)
|
void WindowsWindow::SetVSync(bool enable)
|
||||||
|
|||||||
@ -507,6 +507,30 @@ namespace Prism
|
|||||||
m_Pipeline = Pipeline::Create(pipelineSpecification);
|
m_Pipeline = Pipeline::Create(pipelineSpecification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mesh::Mesh(const std::vector<Vertex>& vertices, const std::vector<Index>& indices)
|
||||||
|
: m_StaticVertices(vertices), m_Indices(indices), m_IsAnimated(false)
|
||||||
|
{
|
||||||
|
Submesh submesh;
|
||||||
|
submesh.BaseVertex = 0;
|
||||||
|
submesh.BaseIndex = 0;
|
||||||
|
submesh.IndexCount = static_cast<uint32_t>(indices.size()) * 3;
|
||||||
|
submesh.Transform = glm::mat4(1.0F);
|
||||||
|
m_Submeshes.push_back(submesh);
|
||||||
|
|
||||||
|
m_VertexBuffer = VertexBuffer::Create(m_StaticVertices.data(), static_cast<uint32_t>(m_StaticVertices.size()) * sizeof(Vertex));
|
||||||
|
m_IndexBuffer = IndexBuffer::Create(m_Indices.data(), static_cast<uint32_t>(m_Indices.size()) * sizeof(Index));
|
||||||
|
|
||||||
|
PipelineSpecification pipelineSpecification;
|
||||||
|
pipelineSpecification.Layout = {
|
||||||
|
{ ShaderDataType::Float3, "a_Position" },
|
||||||
|
{ ShaderDataType::Float3, "a_Normal" },
|
||||||
|
{ ShaderDataType::Float3, "a_Tangent" },
|
||||||
|
{ ShaderDataType::Float3, "a_Binormal" },
|
||||||
|
{ ShaderDataType::Float2, "a_TexCoord" },
|
||||||
|
};
|
||||||
|
m_Pipeline = Pipeline::Create(pipelineSpecification);
|
||||||
|
}
|
||||||
|
|
||||||
Mesh::~Mesh() = default;
|
Mesh::~Mesh() = default;
|
||||||
|
|
||||||
void Mesh::OnUpdate(TimeStep deltaTime)
|
void Mesh::OnUpdate(TimeStep deltaTime)
|
||||||
@ -706,14 +730,14 @@ namespace Prism
|
|||||||
if (nodeAnim->mNumRotationKeys == 1)
|
if (nodeAnim->mNumRotationKeys == 1)
|
||||||
{
|
{
|
||||||
// No interpolation necessary for single value
|
// No interpolation necessary for single value
|
||||||
auto v = nodeAnim->mRotationKeys[0].mValue;
|
const auto v = nodeAnim->mRotationKeys[0].mValue;
|
||||||
return glm::quat(v.w, v.x, v.y, v.z);
|
return {v.w, v.x, v.y, v.z};
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RotationIndex = FindRotation(animationTime, nodeAnim);
|
const uint32_t RotationIndex = FindRotation(animationTime, nodeAnim);
|
||||||
uint32_t NextRotationIndex = (RotationIndex + 1);
|
const uint32_t NextRotationIndex = (RotationIndex + 1);
|
||||||
PM_CORE_ASSERT(NextRotationIndex < nodeAnim->mNumRotationKeys);
|
PM_CORE_ASSERT(NextRotationIndex < nodeAnim->mNumRotationKeys);
|
||||||
float DeltaTime = (float)(nodeAnim->mRotationKeys[NextRotationIndex].mTime - nodeAnim->mRotationKeys[RotationIndex].mTime);
|
const float DeltaTime = (float)(nodeAnim->mRotationKeys[NextRotationIndex].mTime - nodeAnim->mRotationKeys[RotationIndex].mTime);
|
||||||
float Factor = (animationTime - (float)nodeAnim->mRotationKeys[RotationIndex].mTime) / DeltaTime;
|
float Factor = (animationTime - (float)nodeAnim->mRotationKeys[RotationIndex].mTime) / DeltaTime;
|
||||||
PM_CORE_ASSERT(Factor <= 1.0f, "Factor must be below 1.0f");
|
PM_CORE_ASSERT(Factor <= 1.0f, "Factor must be below 1.0f");
|
||||||
Factor = glm::clamp(Factor, 0.0f, 1.0f);
|
Factor = glm::clamp(Factor, 0.0f, 1.0f);
|
||||||
@ -722,7 +746,7 @@ namespace Prism
|
|||||||
auto q = aiQuaternion();
|
auto q = aiQuaternion();
|
||||||
aiQuaternion::Interpolate(q, StartRotationQ, EndRotationQ, Factor);
|
aiQuaternion::Interpolate(q, StartRotationQ, EndRotationQ, Factor);
|
||||||
q = q.Normalize();
|
q = q.Normalize();
|
||||||
return glm::quat(q.w, q.x, q.y, q.z);
|
return {q.w, q.x, q.y, q.z};
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Mesh::InterpolateScale(const float animationTime, const aiNodeAnim* nodeAnim)
|
glm::vec3 Mesh::InterpolateScale(const float animationTime, const aiNodeAnim* nodeAnim)
|
||||||
|
|||||||
@ -107,6 +107,7 @@ namespace Prism
|
|||||||
|
|
||||||
|
|
||||||
Mesh(const std::string& filename);
|
Mesh(const std::string& filename);
|
||||||
|
Mesh(const std::vector<Vertex>& vertices, const std::vector<Index>& indices);
|
||||||
~Mesh();
|
~Mesh();
|
||||||
|
|
||||||
void OnUpdate(TimeStep deltaTime);
|
void OnUpdate(TimeStep deltaTime);
|
||||||
|
|||||||
172
Prism/src/Prism/Renderer/MeshFactory.cpp
Normal file
172
Prism/src/Prism/Renderer/MeshFactory.cpp
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-12-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Meshfactory.h"
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
Ref<Mesh> MeshFactory::CreateBox(const glm::vec3& size)
|
||||||
|
{
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
vertices.resize(8);
|
||||||
|
vertices[0].Position = { -size.x / 2.0f, -size.y / 2.0f, size.z / 2.0f };
|
||||||
|
vertices[1].Position = { size.x / 2.0f, -size.y / 2.0f, size.z / 2.0f };
|
||||||
|
vertices[2].Position = { size.x / 2.0f, size.y / 2.0f, size.z / 2.0f };
|
||||||
|
vertices[3].Position = { -size.x / 2.0f, size.y / 2.0f, size.z / 2.0f };
|
||||||
|
vertices[4].Position = { -size.x / 2.0f, -size.y / 2.0f, -size.z / 2.0f };
|
||||||
|
vertices[5].Position = { size.x / 2.0f, -size.y / 2.0f, -size.z / 2.0f };
|
||||||
|
vertices[6].Position = { size.x / 2.0f, size.y / 2.0f, -size.z / 2.0f };
|
||||||
|
vertices[7].Position = { -size.x / 2.0f, size.y / 2.0f, -size.z / 2.0f };
|
||||||
|
|
||||||
|
vertices[0].Normal = { -1.0f, -1.0f, 1.0f };
|
||||||
|
vertices[1].Normal = { 1.0f, -1.0f, 1.0f };
|
||||||
|
vertices[2].Normal = { 1.0f, 1.0f, 1.0f };
|
||||||
|
vertices[3].Normal = { -1.0f, 1.0f, 1.0f };
|
||||||
|
vertices[4].Normal = { -1.0f, -1.0f, -1.0f };
|
||||||
|
vertices[5].Normal = { 1.0f, -1.0f, -1.0f };
|
||||||
|
vertices[6].Normal = { 1.0f, 1.0f, -1.0f };
|
||||||
|
vertices[7].Normal = { -1.0f, 1.0f, -1.0f };
|
||||||
|
|
||||||
|
std::vector<Index> indices;
|
||||||
|
indices.resize(12);
|
||||||
|
indices = {
|
||||||
|
{ 0, 1, 2 },
|
||||||
|
{ 2, 3, 0 },
|
||||||
|
{ 1, 5, 6 },
|
||||||
|
{ 6, 2, 1 },
|
||||||
|
{ 7, 6, 5 },
|
||||||
|
{ 5, 4, 7 },
|
||||||
|
{ 4, 0, 3 },
|
||||||
|
{ 3, 7, 4 },
|
||||||
|
{ 4, 5, 1 },
|
||||||
|
{ 1, 0, 4 },
|
||||||
|
{ 3, 2, 6 },
|
||||||
|
{ 6, 7, 3 }
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ref<Mesh>::Create(vertices, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
Prism::Ref<Prism::Mesh> MeshFactory::CreateSphere(float radius)
|
||||||
|
{
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::vector<Index> indices;
|
||||||
|
|
||||||
|
constexpr float latitudeBands = 30;
|
||||||
|
constexpr float longitudeBands = 30;
|
||||||
|
|
||||||
|
for (float latitude = 0.0f; latitude <= latitudeBands; latitude++)
|
||||||
|
{
|
||||||
|
const float theta = latitude * M_PI / latitudeBands;
|
||||||
|
const float sinTheta = glm::sin(theta);
|
||||||
|
float cosTheta = glm::cos(theta);
|
||||||
|
|
||||||
|
for (float longitude = 0.0f; longitude <= longitudeBands; longitude++)
|
||||||
|
{
|
||||||
|
const float phi = longitude * 2 * M_PI / longitudeBands;
|
||||||
|
const float sinPhi = glm::sin(phi);
|
||||||
|
const float cosPhi = glm::cos(phi);
|
||||||
|
|
||||||
|
Vertex vertex;
|
||||||
|
vertex.Normal = { cosPhi * sinTheta, cosTheta, sinPhi * sinTheta };
|
||||||
|
vertex.Position = { radius * vertex.Normal.x, radius * vertex.Normal.y, radius * vertex.Normal.z };
|
||||||
|
vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t latitude = 0; latitude < latitudeBands; latitude++)
|
||||||
|
{
|
||||||
|
for (uint32_t longitude = 0; longitude < longitudeBands; longitude++)
|
||||||
|
{
|
||||||
|
const uint32_t first = (latitude * (longitudeBands + 1)) + longitude;
|
||||||
|
const uint32_t second = first + longitudeBands + 1;
|
||||||
|
|
||||||
|
indices.push_back({ first, second, first + 1 });
|
||||||
|
indices.push_back({ second, second + 1, first + 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ref<Mesh>::Create(vertices, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Mesh> MeshFactory::CreateCapsule(float radius, float height)
|
||||||
|
{
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::vector<Index> indices;
|
||||||
|
|
||||||
|
constexpr int segments = 30;
|
||||||
|
constexpr int pointCount = segments + 1;
|
||||||
|
|
||||||
|
float pointsX[pointCount];
|
||||||
|
float pointsY[pointCount];
|
||||||
|
float pointsZ[pointCount];
|
||||||
|
float pointsR[pointCount];
|
||||||
|
|
||||||
|
float calcH = 0.0f;
|
||||||
|
float calcV = 0.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < pointCount; i++)
|
||||||
|
{
|
||||||
|
float calcHRadians = glm::radians(calcH);
|
||||||
|
float calcVRadians = glm::radians(calcV);
|
||||||
|
|
||||||
|
pointsX[i] = glm::sin(calcHRadians);
|
||||||
|
pointsZ[i] = glm::cos(calcHRadians);
|
||||||
|
pointsY[i] = glm::cos(calcVRadians);
|
||||||
|
pointsR[i] = glm::sin(calcVRadians);
|
||||||
|
|
||||||
|
calcH += 360.0f / (float)segments;
|
||||||
|
calcV += 180.0f / (float)segments;
|
||||||
|
}
|
||||||
|
|
||||||
|
float yOffset = (height - (radius * 2.0f)) * 0.5f;
|
||||||
|
if (yOffset < 0.0f)
|
||||||
|
yOffset = 0.0f;
|
||||||
|
|
||||||
|
int top = glm::ceil(pointCount * 0.5f);
|
||||||
|
|
||||||
|
for (int y = 0; y < top; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < pointCount; x++)
|
||||||
|
{
|
||||||
|
Vertex vertex;
|
||||||
|
vertex.Position = glm::vec3( pointsX[x] * pointsR[y], pointsY[y] + yOffset, pointsZ[x] * pointsR[y] ) * radius;
|
||||||
|
vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int bottom = glm::floor(pointCount * 0.5f);
|
||||||
|
|
||||||
|
for (int y = bottom; y < pointCount; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < pointCount; x++)
|
||||||
|
{
|
||||||
|
Vertex vertex;
|
||||||
|
vertex.Position = glm::vec3(pointsX[x] * pointsR[y], -yOffset + pointsY[y], pointsZ[x] * pointsR[y]) * radius;
|
||||||
|
vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < segments + 1; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < segments; x++)
|
||||||
|
{
|
||||||
|
Index index1;
|
||||||
|
index1.V1 = ((y + 0) * (segments + 1)) + x + 0;
|
||||||
|
index1.V2 = ((y + 1) * (segments + 1)) + x + 0;
|
||||||
|
index1.V3 = ((y + 1) * (segments + 1)) + x + 1;
|
||||||
|
indices.push_back(index1);
|
||||||
|
|
||||||
|
Index index2;
|
||||||
|
index2.V1 = ((y + 0) * (segments + 1)) + x + 1;
|
||||||
|
index2.V2 = ((y + 0) * (segments + 1)) + x + 0;
|
||||||
|
index2.V3 = ((y + 1) * (segments + 1)) + x + 1;
|
||||||
|
indices.push_back(index2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ref<Mesh>::Create(vertices, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
22
Prism/src/Prism/Renderer/MeshFactory.h
Normal file
22
Prism/src/Prism/Renderer/MeshFactory.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-12-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MESHFACTORY_H
|
||||||
|
#define MESHFACTORY_H
|
||||||
|
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
class MeshFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Ref<Mesh> CreateBox(const glm::vec3& size);
|
||||||
|
static Ref<Mesh> CreateSphere(float radius);
|
||||||
|
static Ref<Mesh> CreateCapsule(float radius, float height);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MESHFACTORY_H
|
||||||
@ -15,138 +15,164 @@
|
|||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
struct SceneRendererData
|
struct SceneRendererData
|
||||||
{
|
{
|
||||||
const Scene* ActiveScene = nullptr;
|
const Scene* ActiveScene = nullptr;
|
||||||
struct SceneInfo
|
struct SceneInfo
|
||||||
{
|
{
|
||||||
SceneRendererCamera SceneCamera;
|
SceneRendererCamera SceneCamera;
|
||||||
|
|
||||||
// Resources
|
// Resources
|
||||||
Ref<MaterialInstance> SkyboxMaterial;
|
Ref<MaterialInstance> SkyboxMaterial;
|
||||||
Environment SceneEnvironment;
|
Environment SceneEnvironment;
|
||||||
Light ActiveLight;
|
Light ActiveLight;
|
||||||
} SceneData;
|
} SceneData;
|
||||||
|
|
||||||
Ref<Texture2D> BRDFLUT;
|
Ref<Texture2D> BRDFLUT;
|
||||||
Ref<Shader> CompositeShader;
|
Ref<Shader> CompositeShader;
|
||||||
|
|
||||||
Ref<RenderPass> GeoPass;
|
Ref<RenderPass> GeoPass;
|
||||||
Ref<RenderPass> CompositePass;
|
Ref<RenderPass> CompositePass;
|
||||||
|
|
||||||
struct DrawCommand
|
struct DrawCommand
|
||||||
{
|
{
|
||||||
Ref<Mesh> mesh;
|
Ref<Mesh> mesh;
|
||||||
Ref<MaterialInstance> Material;
|
Ref<MaterialInstance> Material;
|
||||||
glm::mat4 Transform;
|
glm::mat4 Transform;
|
||||||
};
|
};
|
||||||
std::vector<DrawCommand> DrawList;
|
std::vector<DrawCommand> DrawList;
|
||||||
std::vector<DrawCommand> SelectedMeshDrawList;
|
std::vector<DrawCommand> SelectedMeshDrawList;
|
||||||
|
std::vector<DrawCommand> ColliderDrawList;
|
||||||
|
|
||||||
// Grid
|
// Grid
|
||||||
Ref<MaterialInstance> GridMaterial;
|
Ref<MaterialInstance> GridMaterial;
|
||||||
Ref<MaterialInstance> OutlineMaterial;
|
Ref<MaterialInstance> OutlineMaterial;
|
||||||
|
Ref<MaterialInstance> ColliderMaterial;
|
||||||
|
|
||||||
SceneRendererOptions Options;
|
SceneRendererOptions Options;
|
||||||
};
|
};
|
||||||
|
|
||||||
static SceneRendererData s_Data;
|
static SceneRendererData s_Data;
|
||||||
|
|
||||||
void SceneRenderer::Init()
|
void SceneRenderer::Init()
|
||||||
{
|
{
|
||||||
FramebufferSpecification geoFramebufferSpec;
|
FramebufferSpecification geoFramebufferSpec;
|
||||||
geoFramebufferSpec.Width = 1280;
|
geoFramebufferSpec.Width = 1280;
|
||||||
geoFramebufferSpec.Height = 720;
|
geoFramebufferSpec.Height = 720;
|
||||||
geoFramebufferSpec.Format = FramebufferFormat::RGBA16F;
|
geoFramebufferSpec.Format = FramebufferFormat::RGBA16F;
|
||||||
geoFramebufferSpec.Samples = 8;
|
geoFramebufferSpec.Samples = 8;
|
||||||
geoFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
|
geoFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
|
||||||
|
|
||||||
RenderPassSpecification geoRenderPassSpec;
|
RenderPassSpecification geoRenderPassSpec;
|
||||||
geoRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(geoFramebufferSpec);
|
geoRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(geoFramebufferSpec);
|
||||||
s_Data.GeoPass = RenderPass::Create(geoRenderPassSpec);
|
s_Data.GeoPass = RenderPass::Create(geoRenderPassSpec);
|
||||||
|
|
||||||
FramebufferSpecification compFramebufferSpec;
|
FramebufferSpecification compFramebufferSpec;
|
||||||
compFramebufferSpec.Width = 1280;
|
compFramebufferSpec.Width = 1280;
|
||||||
compFramebufferSpec.Height = 720;
|
compFramebufferSpec.Height = 720;
|
||||||
compFramebufferSpec.Format = FramebufferFormat::RGBA8;
|
compFramebufferSpec.Format = FramebufferFormat::RGBA8;
|
||||||
compFramebufferSpec.ClearColor = { 0.5f, 0.1f, 0.1f, 1.0f };
|
compFramebufferSpec.ClearColor = { 0.5f, 0.1f, 0.1f, 1.0f };
|
||||||
|
|
||||||
RenderPassSpecification compRenderPassSpec;
|
RenderPassSpecification compRenderPassSpec;
|
||||||
compRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(compFramebufferSpec);
|
compRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(compFramebufferSpec);
|
||||||
s_Data.CompositePass = RenderPass::Create(compRenderPassSpec);
|
s_Data.CompositePass = RenderPass::Create(compRenderPassSpec);
|
||||||
|
|
||||||
s_Data.CompositeShader = Shader::Create("assets/shaders/SceneComposite.glsl");
|
s_Data.CompositeShader = Shader::Create("assets/shaders/SceneComposite.glsl");
|
||||||
s_Data.BRDFLUT = Texture2D::Create("assets/textures/BRDF_LUT.tga");
|
s_Data.BRDFLUT = Texture2D::Create("assets/textures/BRDF_LUT.tga");
|
||||||
|
|
||||||
|
|
||||||
// Grid
|
// Grid
|
||||||
const auto gridShader = Shader::Create("assets/shaders/Grid.glsl");
|
const auto gridShader = Shader::Create("assets/shaders/Grid.glsl");
|
||||||
s_Data.GridMaterial = MaterialInstance::Create(Material::Create(gridShader));
|
s_Data.GridMaterial = MaterialInstance::Create(Material::Create(gridShader));
|
||||||
constexpr float gridScale = 16.025f;
|
constexpr float gridScale = 16.025f;
|
||||||
constexpr float gridSize = 0.025f;
|
constexpr float gridSize = 0.025f;
|
||||||
s_Data.GridMaterial->Set("u_Scale", gridScale);
|
s_Data.GridMaterial->Set("u_Scale", gridScale);
|
||||||
s_Data.GridMaterial->Set("u_Res", gridSize);
|
s_Data.GridMaterial->Set("u_Res", gridSize);
|
||||||
|
|
||||||
// outline
|
// outline
|
||||||
const auto outlineShader = Shader::Create("assets/shaders/Outline.glsl");
|
const auto outlineShader = Shader::Create("assets/shaders/Outline.glsl");
|
||||||
s_Data.OutlineMaterial = MaterialInstance::Create(Material::Create(outlineShader));
|
s_Data.OutlineMaterial = MaterialInstance::Create(Material::Create(outlineShader));
|
||||||
s_Data.OutlineMaterial->SetFlag(MaterialFlag::DepthTest, false);
|
s_Data.OutlineMaterial->SetFlag(MaterialFlag::DepthTest, false);
|
||||||
|
|
||||||
}
|
// Collider
|
||||||
|
const auto colliderShader = Shader::Create("assets/shaders/Collider.glsl");
|
||||||
|
s_Data.ColliderMaterial = MaterialInstance::Create(Material::Create(colliderShader));
|
||||||
|
s_Data.ColliderMaterial->SetFlag(MaterialFlag::DepthTest, false);
|
||||||
|
}
|
||||||
|
|
||||||
void SceneRenderer::SetViewportSize(uint32_t width, uint32_t height)
|
void SceneRenderer::SetViewportSize(uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
s_Data.GeoPass->GetSpecification().TargetFramebuffer->Resize(width, height);
|
s_Data.GeoPass->GetSpecification().TargetFramebuffer->Resize(width, height);
|
||||||
s_Data.CompositePass->GetSpecification().TargetFramebuffer->Resize(width, height);
|
s_Data.CompositePass->GetSpecification().TargetFramebuffer->Resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderer::BeginScene(const Scene* scene, const SceneRendererCamera& camera)
|
void SceneRenderer::BeginScene(const Scene* scene, const SceneRendererCamera& camera)
|
||||||
{
|
{
|
||||||
PM_CORE_ASSERT(!s_Data.ActiveScene);
|
PM_CORE_ASSERT(!s_Data.ActiveScene);
|
||||||
|
|
||||||
s_Data.ActiveScene = scene;
|
s_Data.ActiveScene = scene;
|
||||||
|
|
||||||
s_Data.SceneData.SceneCamera = camera;
|
s_Data.SceneData.SceneCamera = camera;
|
||||||
s_Data.SceneData.SkyboxMaterial = scene->m_SkyboxMaterial;
|
s_Data.SceneData.SkyboxMaterial = scene->m_SkyboxMaterial;
|
||||||
s_Data.SceneData.SceneEnvironment = scene->m_Environment;
|
s_Data.SceneData.SceneEnvironment = scene->m_Environment;
|
||||||
s_Data.SceneData.ActiveLight = scene->m_Light;
|
s_Data.SceneData.ActiveLight = scene->m_Light;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderer::EndScene()
|
void SceneRenderer::EndScene()
|
||||||
{
|
{
|
||||||
PM_CORE_ASSERT(s_Data.ActiveScene);
|
PM_CORE_ASSERT(s_Data.ActiveScene);
|
||||||
|
|
||||||
s_Data.ActiveScene = nullptr;
|
s_Data.ActiveScene = nullptr;
|
||||||
|
|
||||||
FlushDrawList();
|
FlushDrawList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderer::SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial)
|
void SceneRenderer::SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial)
|
||||||
{
|
{
|
||||||
// TODO: Culling, sorting, etc.
|
// TODO: Culling, sorting, etc.
|
||||||
|
|
||||||
s_Data.DrawList.push_back({ mesh, overrideMaterial, transform });
|
s_Data.DrawList.push_back({ mesh, overrideMaterial, transform });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderer::SubmitSelectedMesh(const Ref<Mesh>& mesh, const glm::mat4& transform)
|
void SceneRenderer::SubmitSelectedMesh(const Ref<Mesh>& mesh, const glm::mat4& transform)
|
||||||
{
|
{
|
||||||
s_Data.SelectedMeshDrawList.push_back({ mesh, nullptr, transform });
|
s_Data.SelectedMeshDrawList.push_back({ mesh, nullptr, transform });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneRenderer::SubmitColliderMesh(const BoxColliderComponent& component, const glm::mat4& parentTransform)
|
||||||
|
{
|
||||||
|
s_Data.ColliderDrawList.push_back({ component.DebugMesh, nullptr, glm::translate(parentTransform, component.Offset)});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneRenderer::SubmitColliderMesh(const SphereColliderComponent& component, const glm::mat4& parentTransform)
|
||||||
|
{
|
||||||
|
s_Data.ColliderDrawList.push_back({ component.DebugMesh, nullptr, parentTransform });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneRenderer::SubmitColliderMesh(const CapsuleColliderComponent& component, const glm::mat4& parentTransform)
|
||||||
|
{
|
||||||
|
s_Data.ColliderDrawList.push_back({ component.DebugMesh, nullptr, parentTransform });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneRenderer::SubmitColliderMesh(const MeshColliderComponent& component, const glm::mat4& parentTransform)
|
||||||
|
{
|
||||||
|
s_Data.ColliderDrawList.push_back({ component.ProcessedMesh, nullptr, parentTransform });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Ref<Shader> equirectangularConversionShader, envFilteringShader, envIrradianceShader;
|
static Ref<Shader> equirectangularConversionShader, envFilteringShader, envIrradianceShader;
|
||||||
|
|
||||||
std::pair<Ref<TextureCube>, Ref<TextureCube>> SceneRenderer::CreateEnvironmentMap(const std::string& filepath)
|
std::pair<Ref<TextureCube>, Ref<TextureCube>> SceneRenderer::CreateEnvironmentMap(const std::string& filepath)
|
||||||
{
|
{
|
||||||
constexpr uint32_t cubemapSize = 2048;
|
constexpr uint32_t cubemapSize = 2048;
|
||||||
constexpr uint32_t irradianceMapSize = 32;
|
constexpr uint32_t irradianceMapSize = 32;
|
||||||
|
|
||||||
Ref<TextureCube> envUnfiltered = TextureCube::Create(TextureFormat::Float16, cubemapSize, cubemapSize);
|
Ref<TextureCube> envUnfiltered = TextureCube::Create(TextureFormat::Float16, cubemapSize, cubemapSize);
|
||||||
if (!equirectangularConversionShader)
|
if (!equirectangularConversionShader)
|
||||||
equirectangularConversionShader = Shader::Create("assets/shaders/EquirectangularToCubeMap.glsl");
|
equirectangularConversionShader = Shader::Create("assets/shaders/EquirectangularToCubeMap.glsl");
|
||||||
Ref<Texture2D> envEquirect = Texture2D::Create(filepath);
|
Ref<Texture2D> envEquirect = Texture2D::Create(filepath);
|
||||||
if (envEquirect->GetFormat() != TextureFormat::Float16)
|
if (envEquirect->GetFormat() != TextureFormat::Float16)
|
||||||
PM_CORE_WARN("Texture is not HDR!");
|
PM_CORE_WARN("Texture is not HDR!");
|
||||||
|
|
||||||
equirectangularConversionShader->Bind();
|
equirectangularConversionShader->Bind();
|
||||||
envEquirect->Bind();
|
envEquirect->Bind();
|
||||||
@ -198,46 +224,48 @@ namespace Prism
|
|||||||
});
|
});
|
||||||
|
|
||||||
return { envFiltered, irradianceMap };
|
return { envFiltered, irradianceMap };
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<RenderPass> SceneRenderer::GetFinalRenderPass()
|
Ref<RenderPass> SceneRenderer::GetFinalRenderPass()
|
||||||
{
|
{
|
||||||
return s_Data.CompositePass;
|
return s_Data.CompositePass;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Texture2D> SceneRenderer::GetFinalColorBuffer()
|
Ref<Texture2D> SceneRenderer::GetFinalColorBuffer()
|
||||||
{
|
{
|
||||||
PM_CORE_ASSERT(false, "Not implemented");
|
PM_CORE_ASSERT(false, "Not implemented");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SceneRenderer::GetFinalColorBufferRendererID()
|
uint32_t SceneRenderer::GetFinalColorBufferRendererID()
|
||||||
{
|
{
|
||||||
return s_Data.CompositePass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID();
|
return s_Data.CompositePass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID();
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneRendererOptions& SceneRenderer::GetOptions()
|
SceneRendererOptions& SceneRenderer::GetOptions()
|
||||||
{
|
{
|
||||||
return s_Data.Options;
|
return s_Data.Options;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderer::FlushDrawList()
|
void SceneRenderer::FlushDrawList()
|
||||||
{
|
{
|
||||||
PM_CORE_ASSERT(!s_Data.ActiveScene);
|
PM_CORE_ASSERT(!s_Data.ActiveScene);
|
||||||
|
|
||||||
GeometryPass();
|
GeometryPass();
|
||||||
CompositePass();
|
CompositePass();
|
||||||
|
|
||||||
s_Data.DrawList.clear();
|
s_Data.DrawList.clear();
|
||||||
s_Data.SelectedMeshDrawList.clear();
|
s_Data.SelectedMeshDrawList.clear();
|
||||||
s_Data.SceneData = {};
|
s_Data.ColliderDrawList.clear();
|
||||||
}
|
s_Data.SceneData = {};
|
||||||
|
}
|
||||||
|
|
||||||
void SceneRenderer::GeometryPass()
|
void SceneRenderer::GeometryPass()
|
||||||
{
|
{
|
||||||
bool outline = s_Data.SelectedMeshDrawList.size() > 0;
|
const bool outline = s_Data.SelectedMeshDrawList.size() > 0;
|
||||||
|
const bool collider = s_Data.ColliderDrawList.size() > 0;
|
||||||
|
|
||||||
if (outline)
|
if (outline || collider)
|
||||||
{
|
{
|
||||||
Renderer::Submit([]()
|
Renderer::Submit([]()
|
||||||
{
|
{
|
||||||
@ -247,7 +275,7 @@ namespace Prism
|
|||||||
|
|
||||||
Renderer::BeginRenderPass(s_Data.GeoPass);
|
Renderer::BeginRenderPass(s_Data.GeoPass);
|
||||||
|
|
||||||
if (outline)
|
if (outline || collider)
|
||||||
{
|
{
|
||||||
Renderer::Submit([]()
|
Renderer::Submit([]()
|
||||||
{
|
{
|
||||||
@ -283,32 +311,6 @@ namespace Prism
|
|||||||
Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial);
|
Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outline)
|
|
||||||
{
|
|
||||||
Renderer::Submit([]()
|
|
||||||
{
|
|
||||||
glStencilFunc(GL_ALWAYS, 1, 0xff);
|
|
||||||
glStencilMask(0xff);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& dc : s_Data.SelectedMeshDrawList)
|
|
||||||
{
|
|
||||||
auto baseMaterial = dc.mesh->GetMaterial();
|
|
||||||
baseMaterial->Set("u_ViewProjectionMatrix", viewProjection);
|
|
||||||
baseMaterial->Set("u_CameraPosition", cameraPosition);
|
|
||||||
|
|
||||||
// Environment (TODO: don't do this per mesh)
|
|
||||||
baseMaterial->Set("u_EnvRadianceTex", s_Data.SceneData.SceneEnvironment.RadianceMap);
|
|
||||||
baseMaterial->Set("u_EnvIrradianceTex", s_Data.SceneData.SceneEnvironment.IrradianceMap);
|
|
||||||
baseMaterial->Set("u_BRDFLUTTexture", s_Data.BRDFLUT);
|
|
||||||
|
|
||||||
// Set lights (TODO: move to light environment and don't do per mesh)
|
|
||||||
baseMaterial->Set("lights", s_Data.SceneData.ActiveLight);
|
|
||||||
|
|
||||||
auto overrideMaterial = nullptr; // dc.Material;
|
|
||||||
Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outline)
|
if (outline)
|
||||||
{
|
{
|
||||||
@ -349,6 +351,47 @@ namespace Prism
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (collider)
|
||||||
|
{
|
||||||
|
Renderer::Submit([]()
|
||||||
|
{
|
||||||
|
glStencilFunc(GL_NOTEQUAL, 1, 0xff);
|
||||||
|
glStencilMask(0);
|
||||||
|
|
||||||
|
glLineWidth(1);
|
||||||
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
});
|
||||||
|
|
||||||
|
s_Data.ColliderMaterial->Set("u_ViewProjection", viewProjection);
|
||||||
|
for (auto& dc : s_Data.ColliderDrawList)
|
||||||
|
{
|
||||||
|
if (dc.mesh)
|
||||||
|
Renderer::SubmitMesh(dc.mesh, dc.Transform, s_Data.ColliderMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::Submit([]()
|
||||||
|
{
|
||||||
|
glPointSize(1);
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto& dc : s_Data.ColliderDrawList)
|
||||||
|
{
|
||||||
|
if (dc.mesh)
|
||||||
|
Renderer::SubmitMesh(dc.mesh, dc.Transform, s_Data.ColliderMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::Submit([]()
|
||||||
|
{
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
glStencilMask(0xff);
|
||||||
|
glStencilFunc(GL_ALWAYS, 1, 0xff);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Grid
|
// Grid
|
||||||
const auto option = GetOptions();
|
const auto option = GetOptions();
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
#include "Prism/Scene/Components.h"
|
||||||
#include "Prism/Scene/Scene.h"
|
#include "Prism/Scene/Scene.h"
|
||||||
|
|
||||||
|
|
||||||
@ -37,6 +38,11 @@ namespace Prism
|
|||||||
static void SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform = glm::mat4(1.0f), const Ref<MaterialInstance>& overrideMaterial = nullptr);
|
static void SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform = glm::mat4(1.0f), const Ref<MaterialInstance>& overrideMaterial = nullptr);
|
||||||
static void SubmitSelectedMesh(const Ref<Mesh>& mesh, const glm::mat4& transform = glm::mat4(1.0f));
|
static void SubmitSelectedMesh(const Ref<Mesh>& mesh, const glm::mat4& transform = glm::mat4(1.0f));
|
||||||
|
|
||||||
|
static void SubmitColliderMesh(const BoxColliderComponent& component, const glm::mat4& parentTransform = glm::mat4(1.0f));
|
||||||
|
static void SubmitColliderMesh(const SphereColliderComponent& component, const glm::mat4& parentTransform = glm::mat4(1.0f));
|
||||||
|
static void SubmitColliderMesh(const CapsuleColliderComponent& component, const glm::mat4& parentTransform = glm::mat4(1.0f));
|
||||||
|
static void SubmitColliderMesh(const MeshColliderComponent& component, const glm::mat4& parentTransform = glm::mat4(1.0f));
|
||||||
|
|
||||||
static std::pair<Ref<TextureCube>, Ref<TextureCube>> CreateEnvironmentMap(const std::string& filepath);
|
static std::pair<Ref<TextureCube>, Ref<TextureCube>> CreateEnvironmentMap(const std::string& filepath);
|
||||||
|
|
||||||
static Ref<RenderPass> GetFinalRenderPass();
|
static Ref<RenderPass> GetFinalRenderPass();
|
||||||
|
|||||||
@ -12,7 +12,6 @@
|
|||||||
#include "glm/glm.hpp"
|
#include "glm/glm.hpp"
|
||||||
#include "Prism/Core/Ref.h"
|
#include "Prism/Core/Ref.h"
|
||||||
#include "Prism/Core/UUID.h"
|
#include "Prism/Core/UUID.h"
|
||||||
#include "Prism/Renderer/Camera.h"
|
|
||||||
#include "Prism/Renderer/Mesh.h"
|
#include "Prism/Renderer/Mesh.h"
|
||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
@ -141,9 +140,11 @@ namespace Prism
|
|||||||
|
|
||||||
struct SphereColliderComponent
|
struct SphereColliderComponent
|
||||||
{
|
{
|
||||||
float Radius = 1.0f;
|
float Radius = 0.5f;
|
||||||
|
bool IsTrigger = false;
|
||||||
|
|
||||||
// TODO: Physics Material
|
// The mesh that will be drawn in the editor to show the collision bounds
|
||||||
|
Ref<Mesh> DebugMesh;
|
||||||
|
|
||||||
SphereColliderComponent() = default;
|
SphereColliderComponent() = default;
|
||||||
SphereColliderComponent(const SphereColliderComponent& other) = default;
|
SphereColliderComponent(const SphereColliderComponent& other) = default;
|
||||||
@ -151,9 +152,10 @@ namespace Prism
|
|||||||
|
|
||||||
struct RigidBodyComponent
|
struct RigidBodyComponent
|
||||||
{
|
{
|
||||||
enum class Type { Static, Dynamic, Kinematic };
|
enum class Type { Static, Dynamic};
|
||||||
Type BodyType;
|
Type BodyType;
|
||||||
float Mass = 1.0f;
|
float Mass = 1.0f;
|
||||||
|
bool IsKinematic = false;
|
||||||
|
|
||||||
bool LockPositionX = false;
|
bool LockPositionX = false;
|
||||||
bool LockPositionY = false;
|
bool LockPositionY = false;
|
||||||
@ -183,6 +185,10 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
glm::vec3 Size = { 1.0f, 1.0f, 1.0f };
|
glm::vec3 Size = { 1.0f, 1.0f, 1.0f };
|
||||||
glm::vec3 Offset = { 0.0f, 0.0f, 0.0f };
|
glm::vec3 Offset = { 0.0f, 0.0f, 0.0f };
|
||||||
|
bool IsTrigger = false;
|
||||||
|
|
||||||
|
// The mesh that will be drawn in the editor to show the collision bounds
|
||||||
|
Ref<Mesh> DebugMesh;
|
||||||
|
|
||||||
BoxColliderComponent() = default;
|
BoxColliderComponent() = default;
|
||||||
BoxColliderComponent(const BoxColliderComponent& other) = default;
|
BoxColliderComponent(const BoxColliderComponent& other) = default;
|
||||||
@ -192,6 +198,9 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
float Radius = 0.5f;
|
float Radius = 0.5f;
|
||||||
float Height = 1.0f;
|
float Height = 1.0f;
|
||||||
|
bool IsTrigger = false;
|
||||||
|
|
||||||
|
Ref<Mesh> DebugMesh;
|
||||||
|
|
||||||
CapsuleColliderComponent() = default;
|
CapsuleColliderComponent() = default;
|
||||||
CapsuleColliderComponent(const CapsuleColliderComponent& other) = default;
|
CapsuleColliderComponent(const CapsuleColliderComponent& other) = default;
|
||||||
@ -200,6 +209,8 @@ namespace Prism
|
|||||||
struct MeshColliderComponent
|
struct MeshColliderComponent
|
||||||
{
|
{
|
||||||
Ref<Prism::Mesh> CollisionMesh;
|
Ref<Prism::Mesh> CollisionMesh;
|
||||||
|
Ref<Prism::Mesh> ProcessedMesh;
|
||||||
|
bool IsTrigger = false;
|
||||||
|
|
||||||
MeshColliderComponent() = default;
|
MeshColliderComponent() = default;
|
||||||
MeshColliderComponent(const MeshColliderComponent& other) = default;
|
MeshColliderComponent(const MeshColliderComponent& other) = default;
|
||||||
|
|||||||
@ -15,17 +15,14 @@
|
|||||||
#include <glm/gtx/matrix_decompose.hpp>
|
#include <glm/gtx/matrix_decompose.hpp>
|
||||||
|
|
||||||
#include "Prism/Physics/Physics3D.h"
|
#include "Prism/Physics/Physics3D.h"
|
||||||
|
#define PX_PHYSX_STATIC_LIB
|
||||||
|
#include <PxPhysicsAPI.h>
|
||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO: THIS SHOULD MOVE TO PHYSICS FILE!
|
|
||||||
std::unordered_map<UUID, Scene*> s_ActiveScenes;
|
std::unordered_map<UUID, Scene*> s_ActiveScenes;
|
||||||
|
|
||||||
static physx::PxDefaultErrorCallback s_PXErrorCallback;
|
|
||||||
static physx::PxDefaultAllocator s_PXAllocator;
|
|
||||||
static physx::PxFoundation* s_PXFoundation;
|
|
||||||
|
|
||||||
static uint32_t s_SceneIDCounter = 0;
|
static uint32_t s_SceneIDCounter = 0;
|
||||||
|
|
||||||
struct SceneComponent
|
struct SceneComponent
|
||||||
@ -45,11 +42,6 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PhysXSceneComponent
|
|
||||||
{
|
|
||||||
// NOTE: PhysX does some internal ref counting, and thus doesn't allow unique_ptr
|
|
||||||
physx::PxScene* World;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void ProcessContactEvents(const b2WorldId worldId) {
|
void ProcessContactEvents(const b2WorldId worldId) {
|
||||||
@ -85,65 +77,6 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PhysXContactListener : public physx::PxSimulationEventCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count) override
|
|
||||||
{
|
|
||||||
PX_UNUSED(constraints);
|
|
||||||
PX_UNUSED(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onWake(physx::PxActor** actors, physx::PxU32 count) override
|
|
||||||
{
|
|
||||||
PX_UNUSED(actors);
|
|
||||||
PX_UNUSED(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onSleep(physx::PxActor** actors, physx::PxU32 count) override
|
|
||||||
{
|
|
||||||
PX_UNUSED(actors);
|
|
||||||
PX_UNUSED(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) override
|
|
||||||
{
|
|
||||||
Entity& a = *(Entity*)pairHeader.actors[0]->userData;
|
|
||||||
Entity& b = *(Entity*)pairHeader.actors[1]->userData;
|
|
||||||
|
|
||||||
if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_HAS_FIRST_TOUCH)
|
|
||||||
{
|
|
||||||
if (a.HasComponent<ScriptComponent>() && ScriptEngine::ModuleExists(a.GetComponent<ScriptComponent>().ModuleName))
|
|
||||||
ScriptEngine::OnCollisionBegin(a);
|
|
||||||
|
|
||||||
if (b.HasComponent<ScriptComponent>() && ScriptEngine::ModuleExists(b.GetComponent<ScriptComponent>().ModuleName))
|
|
||||||
ScriptEngine::OnCollisionBegin(b);
|
|
||||||
}
|
|
||||||
else if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_LOST_TOUCH)
|
|
||||||
{
|
|
||||||
if (a.HasComponent<ScriptComponent>() && ScriptEngine::ModuleExists(a.GetComponent<ScriptComponent>().ModuleName))
|
|
||||||
ScriptEngine::OnCollisionEnd(a);
|
|
||||||
|
|
||||||
if (b.HasComponent<ScriptComponent>() && ScriptEngine::ModuleExists(b.GetComponent<ScriptComponent>().ModuleName))
|
|
||||||
ScriptEngine::OnCollisionEnd(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count) override
|
|
||||||
{
|
|
||||||
PX_UNUSED(pairs);
|
|
||||||
PX_UNUSED(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onAdvance(const physx::PxRigidBody* const* bodyBuffer, const physx::PxTransform* poseBuffer, const physx::PxU32 count) override
|
|
||||||
{
|
|
||||||
PX_UNUSED(bodyBuffer);
|
|
||||||
PX_UNUSED(poseBuffer);
|
|
||||||
PX_UNUSED(count);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static PhysXContactListener s_PhysXContactListener;
|
|
||||||
|
|
||||||
|
|
||||||
void OnTransformConstruct(entt::registry& registry, entt::entity entity)
|
void OnTransformConstruct(entt::registry& registry, entt::entity entity)
|
||||||
@ -189,8 +122,8 @@ namespace Prism
|
|||||||
return { filepath, radiance, irradiance };
|
return { filepath, radiance, irradiance };
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::Scene(const std::string& debugName)
|
Scene::Scene(const std::string& debugName, const bool isEditorScene)
|
||||||
: m_SceneID(++s_SceneIDCounter), m_DebugName(debugName)
|
: m_SceneID(++s_SceneIDCounter), m_DebugName(debugName)
|
||||||
{
|
{
|
||||||
m_Registry.on_construct<TransformComponent>().connect<&OnTransformConstruct>();
|
m_Registry.on_construct<TransformComponent>().connect<&OnTransformConstruct>();
|
||||||
m_Registry.on_construct<ScriptComponent>().connect<&OnScriptComponentConstruct>();
|
m_Registry.on_construct<ScriptComponent>().connect<&OnScriptComponentConstruct>();
|
||||||
@ -198,34 +131,22 @@ namespace Prism
|
|||||||
m_SceneEntity = m_Registry.create();
|
m_SceneEntity = m_Registry.create();
|
||||||
m_Registry.emplace<SceneComponent>(m_SceneEntity, m_SceneID);
|
m_Registry.emplace<SceneComponent>(m_SceneEntity, m_SceneID);
|
||||||
|
|
||||||
// TODO: Obviously not necessary in all cases
|
|
||||||
Box2DWorldComponent& b2World = m_Registry.emplace<Box2DWorldComponent>(m_SceneEntity, b2Vec2{ 0.0f, -9.8f });
|
Box2DWorldComponent& b2World = m_Registry.emplace<Box2DWorldComponent>(m_SceneEntity, b2Vec2{ 0.0f, -9.8f });
|
||||||
|
|
||||||
s_ActiveScenes[m_SceneID] = this;
|
s_ActiveScenes[m_SceneID] = this;
|
||||||
|
|
||||||
|
|
||||||
physx::PxSceneDesc sceneDesc = Physics3D::CreateSceneDesc();
|
if (!isEditorScene)
|
||||||
sceneDesc.gravity = physx::PxVec3(0.0f, -9.8f, 0.0f);
|
|
||||||
sceneDesc.simulationEventCallback = &s_PhysXContactListener;
|
|
||||||
|
|
||||||
const PhysXSceneComponent& physxWorld = m_Registry.emplace<PhysXSceneComponent>(m_SceneEntity, Physics3D::CreateScene(sceneDesc));
|
|
||||||
physx::PxPvdSceneClient* pvdClient = physxWorld.World->getScenePvdClient();
|
|
||||||
if(pvdClient)
|
|
||||||
{
|
{
|
||||||
pvdClient->setScenePvdFlag(physx::PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
SceneParams sceneDesc;
|
||||||
pvdClient->setScenePvdFlag(physx::PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
sceneDesc.Gravity = glm::vec3(0.0F, -9.81F, 0.0F);
|
||||||
pvdClient->setScenePvdFlag(physx::PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
Physics3D::CreateScene(sceneDesc);
|
||||||
}else
|
|
||||||
{
|
|
||||||
PM_CORE_WARN("you are using pvd to debug: ");
|
|
||||||
PM_CORE_WARN("PvdSceneClient is null is pvd running or you are using release/profile PhysX?");
|
|
||||||
PM_CORE_WARN("to using Pvd, should using debug/checked version to build!");
|
|
||||||
}
|
}
|
||||||
PM_CORE_ASSERT(physxWorld.World);
|
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Scene::~Scene()
|
Scene::~Scene()
|
||||||
{
|
{
|
||||||
m_Registry.on_destroy<ScriptComponent>().disconnect();
|
m_Registry.on_destroy<ScriptComponent>().disconnect();
|
||||||
@ -243,24 +164,22 @@ namespace Prism
|
|||||||
|
|
||||||
void Scene::OnShutdown()
|
void Scene::OnShutdown()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
auto b2WorldView = m_Registry.view<Box2DWorldComponent>();
|
auto b2WorldView = m_Registry.view<Box2DWorldComponent>();
|
||||||
b2DestroyWorld(m_Registry.get<Box2DWorldComponent>(m_SceneEntity).World);
|
b2DestroyWorld(m_Registry.get<Box2DWorldComponent>(m_SceneEntity).World);
|
||||||
|
*/
|
||||||
auto physxView = m_Registry.view<PhysXSceneComponent>();
|
|
||||||
m_Registry.get<PhysXSceneComponent>(m_SceneEntity).World->release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::OnUpdate(TimeStep ts)
|
void Scene::OnUpdate(TimeStep ts)
|
||||||
{
|
{
|
||||||
// Update all entities
|
// Update all entities
|
||||||
{
|
{
|
||||||
auto view = m_Registry.view<ScriptComponent>();
|
const auto view = m_Registry.view<ScriptComponent>();
|
||||||
for (auto entity : view)
|
for (const auto entity : view)
|
||||||
{
|
{
|
||||||
UUID entityID = m_Registry.get<IDComponent>(entity).ID;
|
|
||||||
Entity e = { entity, this };
|
Entity e = { entity, this };
|
||||||
if (ScriptEngine::ModuleExists(e.GetComponent<ScriptComponent>().ModuleName))
|
if (ScriptEngine::ModuleExists(e.GetComponent<ScriptComponent>().ModuleName))
|
||||||
ScriptEngine::OnUpdateEntity(m_SceneID, entityID, ts);
|
ScriptEngine::OnUpdateEntity(e, ts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,65 +215,7 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PhysX Physics
|
Physics3D::Simulate(ts);
|
||||||
auto physxView = m_Registry.view<PhysXSceneComponent>();
|
|
||||||
physx::PxScene* physxScene = m_Registry.get<PhysXSceneComponent>(physxView.front()).World;
|
|
||||||
|
|
||||||
constexpr float stepSize = 0.016666660f;
|
|
||||||
physxScene->simulate(stepSize);
|
|
||||||
physxScene->fetchResults(true);
|
|
||||||
|
|
||||||
{
|
|
||||||
auto view = m_Registry.view<RigidBodyComponent>();
|
|
||||||
for (auto entity : view)
|
|
||||||
{
|
|
||||||
Entity e = { entity, this };
|
|
||||||
auto& transform = e.Transform();
|
|
||||||
RigidBodyComponent& rb = e.GetComponent<RigidBodyComponent>();
|
|
||||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rb.RuntimeActor);
|
|
||||||
const auto& position = actor->getGlobalPose().p;
|
|
||||||
const physx::PxQuat& physicsBodyRotation = actor->getGlobalPose().q;
|
|
||||||
|
|
||||||
auto [translation, rotationQuat, scale] = GetTransformDecomposition(transform);
|
|
||||||
|
|
||||||
if (rb.BodyType == RigidBodyComponent::Type::Dynamic)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
// If the rigidbody is dynamic, the position of the entity is determined by the rigidbody
|
|
||||||
// TODO: Get rotation from RigidActor
|
|
||||||
float xAngle, yAngle, zAngle;
|
|
||||||
physx::PxVec3 axis;
|
|
||||||
physicsBodyRotation.toRadiansAndUnitAxis(xAngle, axis);
|
|
||||||
physicsBodyRotation.toRadiansAndUnitAxis(yAngle, axis);
|
|
||||||
physicsBodyRotation.toRadiansAndUnitAxis(zAngle, axis);
|
|
||||||
|
|
||||||
transform = glm::translate(glm::mat4(1.0f), { position.x, position.y, position.z }) *
|
|
||||||
glm::toMat4(glm::quat({ xAngle, yAngle, zAngle })) *
|
|
||||||
glm::scale(glm::mat4(1.0f), scale);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 获取物理引擎的位置和旋转
|
|
||||||
physx::PxTransform globalPose = actor->getGlobalPose();
|
|
||||||
const physx::PxVec3& pos = globalPose.p;
|
|
||||||
const physx::PxQuat& physicsQuat = globalPose.q;
|
|
||||||
|
|
||||||
glm::quat glmQuat{physicsQuat.w, physicsQuat.x, physicsQuat.y, physicsQuat.z};
|
|
||||||
|
|
||||||
// 使用转换后的四元数创建变换矩阵
|
|
||||||
transform = glm::translate(glm::mat4(1.0f),
|
|
||||||
glm::vec3(pos.x, pos.y, pos.z)) *
|
|
||||||
glm::toMat4(glmQuat) *
|
|
||||||
glm::scale(glm::mat4(1.0f), scale);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (rb.BodyType == RigidBodyComponent::Type::Static)
|
|
||||||
{
|
|
||||||
// If the rigidbody is static, make sure the actor is at the entitys position
|
|
||||||
actor->setGlobalPose(Physics3D::CreatePose(transform));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::OnRenderRuntime(TimeStep ts)
|
void Scene::OnRenderRuntime(TimeStep ts)
|
||||||
@ -425,13 +286,60 @@ namespace Prism
|
|||||||
meshComponent.Mesh->OnUpdate(ts);
|
meshComponent.Mesh->OnUpdate(ts);
|
||||||
|
|
||||||
// TODO: Should we render (logically)
|
// TODO: Should we render (logically)
|
||||||
|
SceneRenderer::SubmitMesh(meshComponent, transformComponent);
|
||||||
if (m_SelectedEntity == entity)
|
|
||||||
SceneRenderer::SubmitSelectedMesh(meshComponent, transformComponent);
|
|
||||||
else
|
|
||||||
SceneRenderer::SubmitMesh(meshComponent, transformComponent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto view = m_Registry.view<BoxColliderComponent>();
|
||||||
|
for (auto entity : view)
|
||||||
|
{
|
||||||
|
Entity e = { entity, this };
|
||||||
|
auto& collider = e.GetComponent<BoxColliderComponent>();
|
||||||
|
|
||||||
|
if (m_SelectedEntity == entity)
|
||||||
|
SceneRenderer::SubmitColliderMesh(collider, e.GetComponent<TransformComponent>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto view = m_Registry.view<SphereColliderComponent>();
|
||||||
|
for (auto entity : view)
|
||||||
|
{
|
||||||
|
Entity e = { entity, this };
|
||||||
|
auto& collider = e.GetComponent<SphereColliderComponent>();
|
||||||
|
|
||||||
|
if (m_SelectedEntity == entity)
|
||||||
|
SceneRenderer::SubmitColliderMesh(collider, e.GetComponent<TransformComponent>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto view = m_Registry.view<CapsuleColliderComponent>();
|
||||||
|
for (auto entity : view)
|
||||||
|
{
|
||||||
|
Entity e = { entity, this };
|
||||||
|
auto& collider = e.GetComponent<CapsuleColliderComponent>();
|
||||||
|
|
||||||
|
if (m_SelectedEntity == entity)
|
||||||
|
SceneRenderer::SubmitColliderMesh(collider, e.GetComponent<TransformComponent>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto view = m_Registry.view<MeshColliderComponent>();
|
||||||
|
for (auto entity : view)
|
||||||
|
{
|
||||||
|
Entity e = { entity, this };
|
||||||
|
auto& collider = e.GetComponent<MeshColliderComponent>();
|
||||||
|
|
||||||
|
if (m_SelectedEntity == entity)
|
||||||
|
{
|
||||||
|
SceneRenderer::SubmitColliderMesh(collider, e.GetComponent<TransformComponent>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SceneRenderer::EndScene();
|
SceneRenderer::EndScene();
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -568,159 +476,21 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
auto physxView = m_Registry.view<PhysXSceneComponent>();
|
auto view = m_Registry.view<RigidBodyComponent>();
|
||||||
physx::PxScene* physxWorld = m_Registry.get<PhysXSceneComponent>(physxView.front()).World;
|
for (auto entity : view)
|
||||||
|
{
|
||||||
{
|
Entity e = { entity, this };
|
||||||
auto view = m_Registry.view<RigidBodyComponent>();
|
Physics3D::CreateActor(e, (int)view.size());
|
||||||
m_Physics3DBodyEntityBuffer = new Entity[view.size()];
|
}
|
||||||
uint32_t physicsBodyEntityBufferIndex = 0;
|
}
|
||||||
|
|
||||||
for (auto entity : view)
|
|
||||||
{
|
|
||||||
Entity e = { entity, this };
|
|
||||||
UUID entityID = e.GetComponent<IDComponent>().ID;
|
|
||||||
auto& transform = e.Transform();
|
|
||||||
auto& rigidbody = m_Registry.get<RigidBodyComponent>(entity);
|
|
||||||
|
|
||||||
physx::PxRigidActor* actor = Physics3D::CreateAndAddActor(physxWorld, rigidbody, transform);
|
|
||||||
PM_CORE_ASSERT(actor);
|
|
||||||
|
|
||||||
Entity* entityStorage = &m_Physics3DBodyEntityBuffer[physicsBodyEntityBufferIndex++];
|
|
||||||
*entityStorage = e;
|
|
||||||
actor->userData = (void*)entityStorage;
|
|
||||||
|
|
||||||
rigidbody.RuntimeActor = actor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto view = m_Registry.view<BoxColliderComponent>();
|
|
||||||
for (auto entity : view)
|
|
||||||
{
|
|
||||||
Entity e = { entity, this };
|
|
||||||
auto& transform = e.Transform();
|
|
||||||
|
|
||||||
auto& boxCollider = m_Registry.get<BoxColliderComponent>(entity);
|
|
||||||
if (e.HasComponent<RigidBodyComponent>())
|
|
||||||
{
|
|
||||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
|
||||||
auto& physicsMaterial = e.GetComponent<PhysicsMaterialComponent>();
|
|
||||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
|
||||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
|
||||||
|
|
||||||
physx::PxBoxGeometry boxGeometry = physx::PxBoxGeometry(boxCollider.Size.x / 2.0F, boxCollider.Size.y / 2.0F, boxCollider.Size.z / 2.0F);
|
|
||||||
physx::PxMaterial* material = Physics3D::CreateMaterial(physicsMaterial.StaticFriction, physicsMaterial.DynamicFriction, physicsMaterial.Bounciness);
|
|
||||||
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor, boxGeometry, *material);
|
|
||||||
shape->setLocalPose(Physics3D::CreatePose(glm::translate(glm::mat4(1.0F), boxCollider.Offset)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto view = m_Registry.view<SphereColliderComponent>();
|
|
||||||
for (auto entity : view)
|
|
||||||
{
|
|
||||||
Entity e = { entity, this };
|
|
||||||
auto& transform = e.Transform();
|
|
||||||
|
|
||||||
auto& sphereCollider = m_Registry.get<SphereColliderComponent>(entity);
|
|
||||||
if (e.HasComponent<RigidBodyComponent>())
|
|
||||||
{
|
|
||||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
|
||||||
auto& physicsMaterial = e.GetComponent<PhysicsMaterialComponent>();
|
|
||||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
|
||||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
|
||||||
physx::PxSphereGeometry sphereGeometry = physx::PxSphereGeometry(sphereCollider.Radius);
|
|
||||||
physx::PxMaterial* material = Physics3D::CreateMaterial(physicsMaterial.StaticFriction, physicsMaterial.DynamicFriction, physicsMaterial.Bounciness);
|
|
||||||
physx::PxRigidActorExt::createExclusiveShape(*actor, sphereGeometry, *material);
|
|
||||||
|
|
||||||
physx::PxRigidDynamic* rigidBodyActor = actor->is<physx::PxRigidDynamic>();
|
|
||||||
|
|
||||||
if (rigidBodyActor)
|
|
||||||
{
|
|
||||||
rigidBodyActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, true);
|
|
||||||
rigidBodyActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, true);
|
|
||||||
rigidBodyActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto view = m_Registry.view<CapsuleColliderComponent>();
|
|
||||||
for (auto entity : view)
|
|
||||||
{
|
|
||||||
Entity e = { entity, this };
|
|
||||||
auto& transform = e.Transform();
|
|
||||||
|
|
||||||
auto& capsuleCollider = m_Registry.get<CapsuleColliderComponent>(entity);
|
|
||||||
if (e.HasComponent<RigidBodyComponent>())
|
|
||||||
{
|
|
||||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
|
||||||
auto& physicsMaterial = e.GetComponent<PhysicsMaterialComponent>();
|
|
||||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
|
||||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
|
||||||
physx::PxCapsuleGeometry capsuleGeometry = physx::PxCapsuleGeometry(capsuleCollider.Radius, capsuleCollider.Height / 2.0F);
|
|
||||||
physx::PxMaterial* material = Physics3D::CreateMaterial(physicsMaterial.StaticFriction, physicsMaterial.DynamicFriction, physicsMaterial.Bounciness);
|
|
||||||
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor, capsuleGeometry, *material);
|
|
||||||
|
|
||||||
// Make sure that the capsule is facing up (+Y)
|
|
||||||
shape->setLocalPose(physx::PxTransform(physx::PxQuat(physx::PxHalfPi, physx::PxVec3(0, 0, 1))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto meshView = m_Registry.view<MeshColliderComponent>();
|
|
||||||
for (auto entity : meshView)
|
|
||||||
{
|
|
||||||
Entity e = { entity, this };
|
|
||||||
auto& transform = e.Transform();
|
|
||||||
|
|
||||||
auto& meshCollider = m_Registry.get<MeshColliderComponent>(entity);
|
|
||||||
if (e.HasComponent<RigidBodyComponent>())
|
|
||||||
{
|
|
||||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
|
||||||
auto& physicsMaterial = e.GetComponent<PhysicsMaterialComponent>();
|
|
||||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
|
||||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
|
||||||
|
|
||||||
physx::PxConvexMesh* triangleMesh = Physics3D::CreateMeshCollider(meshCollider);
|
|
||||||
PM_CORE_ASSERT(triangleMesh);
|
|
||||||
|
|
||||||
physx::PxConvexMeshGeometry triangleGeometry = physx::PxConvexMeshGeometry(triangleMesh);
|
|
||||||
physx::PxMaterial* material = Physics3D::CreateMaterial(physicsMaterial.StaticFriction, physicsMaterial.DynamicFriction, physicsMaterial.Bounciness);
|
|
||||||
physx::PxRigidActorExt::createExclusiveShape(*actor, triangleGeometry, *material);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Collision Filters
|
|
||||||
auto rbView = m_Registry.view<RigidBodyComponent>();
|
|
||||||
for (auto entity : rbView)
|
|
||||||
{
|
|
||||||
Entity e = { entity, this };
|
|
||||||
auto& rigidBody = e.GetComponent<RigidBodyComponent>();
|
|
||||||
PM_CORE_ASSERT(rigidBody.RuntimeActor);
|
|
||||||
physx::PxRigidActor* actor = static_cast<physx::PxRigidActor*>(rigidBody.RuntimeActor);
|
|
||||||
|
|
||||||
if (rigidBody.BodyType == RigidBodyComponent::Type::Static)
|
|
||||||
Physics3D::SetCollisionFilters(actor, (uint32_t)FilterGroup::Static, (uint32_t)FilterGroup::All);
|
|
||||||
else if (rigidBody.BodyType == RigidBodyComponent::Type::Dynamic)
|
|
||||||
Physics3D::SetCollisionFilters(actor, (uint32_t)FilterGroup::Dynamic, (uint32_t)FilterGroup::All);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
m_IsPlaying = true;
|
m_IsPlaying = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::OnRuntimeStop()
|
void Scene::OnRuntimeStop()
|
||||||
{
|
{
|
||||||
auto physxView = m_Registry.view<PhysXSceneComponent>();
|
Physics3D::DestroyScene();
|
||||||
m_Registry.get<PhysXSceneComponent>(m_SceneEntity).World->release();
|
|
||||||
|
|
||||||
|
|
||||||
delete[] m_Physics3DBodyEntityBuffer;
|
delete[] m_Physics3DBodyEntityBuffer;
|
||||||
delete[] m_Physics2DBodyEntityBuffer;
|
delete[] m_Physics2DBodyEntityBuffer;
|
||||||
@ -836,6 +606,7 @@ namespace Prism
|
|||||||
CopyComponentIfExists<PhysicsMaterialComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
CopyComponentIfExists<PhysicsMaterialComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||||
CopyComponentIfExists<BoxColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
CopyComponentIfExists<BoxColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||||
CopyComponentIfExists<SphereColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
CopyComponentIfExists<SphereColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||||
|
CopyComponentIfExists<CapsuleColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||||
CopyComponentIfExists<MeshColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
CopyComponentIfExists<MeshColliderComponent>(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -884,6 +655,7 @@ namespace Prism
|
|||||||
CopyComponent<PhysicsMaterialComponent>(target->m_Registry, m_Registry, enttMap);
|
CopyComponent<PhysicsMaterialComponent>(target->m_Registry, m_Registry, enttMap);
|
||||||
CopyComponent<BoxColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
CopyComponent<BoxColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
||||||
CopyComponent<SphereColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
CopyComponent<SphereColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
||||||
|
CopyComponent<CapsuleColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
||||||
CopyComponent<MeshColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
CopyComponent<MeshColliderComponent>(target->m_Registry, m_Registry, enttMap);
|
||||||
|
|
||||||
const auto& entityInstanceMap = ScriptEngine::GetEntityInstanceMap();
|
const auto& entityInstanceMap = ScriptEngine::GetEntityInstanceMap();
|
||||||
|
|||||||
@ -40,7 +40,7 @@ namespace Prism
|
|||||||
class PRISM_API Scene : public RefCounted
|
class PRISM_API Scene : public RefCounted
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scene(const std::string& debugName = "Scene");
|
Scene(const std::string& debugName = "Scene", bool isEditorScene = false);
|
||||||
~Scene();
|
~Scene();
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
class SceneCamera : public Camera
|
class PRISM_API SceneCamera : public Camera
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class ProjectionType { Perspective = 0, Orthographic = 1 };
|
enum class ProjectionType { Perspective = 0, Orthographic = 1 };
|
||||||
|
|||||||
@ -20,6 +20,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "Prism/Physics/PxPhysicsWrappers.h"
|
||||||
|
#include "Prism/Renderer/Meshfactory.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -195,7 +198,7 @@ namespace Prism
|
|||||||
auto& transform = entity.GetComponent<TransformComponent>().Transform;
|
auto& transform = entity.GetComponent<TransformComponent>().Transform;
|
||||||
auto[pos, rot, scale] = GetTransformDecomposition(transform);
|
auto[pos, rot, scale] = GetTransformDecomposition(transform);
|
||||||
out << YAML::Key << "Position" << YAML::Value << pos;
|
out << YAML::Key << "Position" << YAML::Value << pos;
|
||||||
out << YAML::Key << "Rotation" << YAML::Value << rot;
|
out << YAML::Key << "Rotation" << YAML::Value << rot; // Quat rotation
|
||||||
out << YAML::Key << "Scale" << YAML::Value << scale;
|
out << YAML::Key << "Scale" << YAML::Value << scale;
|
||||||
|
|
||||||
out << YAML::EndMap; // TransformComponent
|
out << YAML::EndMap; // TransformComponent
|
||||||
@ -337,6 +340,7 @@ namespace Prism
|
|||||||
auto& rigidbodyComponent = entity.GetComponent<RigidBodyComponent>();
|
auto& rigidbodyComponent = entity.GetComponent<RigidBodyComponent>();
|
||||||
out << YAML::Key << "BodyType" << YAML::Value << (int)rigidbodyComponent.BodyType;
|
out << YAML::Key << "BodyType" << YAML::Value << (int)rigidbodyComponent.BodyType;
|
||||||
out << YAML::Key << "Mass" << YAML::Value << rigidbodyComponent.Mass;
|
out << YAML::Key << "Mass" << YAML::Value << rigidbodyComponent.Mass;
|
||||||
|
out << YAML::Key << "IsKinematic" << YAML::Value << rigidbodyComponent.IsKinematic;
|
||||||
|
|
||||||
out << YAML::Key << "Constraints";
|
out << YAML::Key << "Constraints";
|
||||||
out << YAML::BeginMap; // Constraints
|
out << YAML::BeginMap; // Constraints
|
||||||
@ -358,7 +362,7 @@ namespace Prism
|
|||||||
out << YAML::Key << "PhysicsMaterialComponent";
|
out << YAML::Key << "PhysicsMaterialComponent";
|
||||||
out << YAML::BeginMap; // PhysicsMaterialComponent
|
out << YAML::BeginMap; // PhysicsMaterialComponent
|
||||||
|
|
||||||
auto& physicsMaterial = entity.GetComponent<PhysicsMaterialComponent>();
|
const auto& physicsMaterial = entity.GetComponent<PhysicsMaterialComponent>();
|
||||||
out << YAML::Key << "StaticFriction" << YAML::Value << physicsMaterial.StaticFriction;
|
out << YAML::Key << "StaticFriction" << YAML::Value << physicsMaterial.StaticFriction;
|
||||||
out << YAML::Key << "DynamicFriction" << YAML::Value << physicsMaterial.DynamicFriction;
|
out << YAML::Key << "DynamicFriction" << YAML::Value << physicsMaterial.DynamicFriction;
|
||||||
out << YAML::Key << "Bounciness" << YAML::Value << physicsMaterial.Bounciness;
|
out << YAML::Key << "Bounciness" << YAML::Value << physicsMaterial.Bounciness;
|
||||||
@ -371,9 +375,10 @@ namespace Prism
|
|||||||
out << YAML::Key << "BoxColliderComponent";
|
out << YAML::Key << "BoxColliderComponent";
|
||||||
out << YAML::BeginMap; // BoxColliderComponent
|
out << YAML::BeginMap; // BoxColliderComponent
|
||||||
|
|
||||||
auto& boxColliderComponent = entity.GetComponent<BoxColliderComponent>();
|
const auto& boxColliderComponent = entity.GetComponent<BoxColliderComponent>();
|
||||||
out << YAML::Key << "Offset" << YAML::Value << boxColliderComponent.Offset;
|
out << YAML::Key << "Offset" << YAML::Value << boxColliderComponent.Offset;
|
||||||
out << YAML::Key << "Size" << YAML::Value << boxColliderComponent.Size;
|
out << YAML::Key << "Size" << YAML::Value << boxColliderComponent.Size;
|
||||||
|
out << YAML::Key << "IsTrigger" << YAML::Value << boxColliderComponent.IsTrigger;
|
||||||
|
|
||||||
out << YAML::EndMap; // BoxColliderComponent
|
out << YAML::EndMap; // BoxColliderComponent
|
||||||
}
|
}
|
||||||
@ -383,19 +388,34 @@ namespace Prism
|
|||||||
out << YAML::Key << "SphereColliderComponent";
|
out << YAML::Key << "SphereColliderComponent";
|
||||||
out << YAML::BeginMap; // SphereColliderComponent
|
out << YAML::BeginMap; // SphereColliderComponent
|
||||||
|
|
||||||
auto& sphereColliderComponent = entity.GetComponent<SphereColliderComponent>();
|
const auto& sphereColliderComponent = entity.GetComponent<SphereColliderComponent>();
|
||||||
out << YAML::Key << "Radius" << YAML::Value << sphereColliderComponent.Radius;
|
out << YAML::Key << "Radius" << YAML::Value << sphereColliderComponent.Radius;
|
||||||
|
out << YAML::Key << "IsTrigger" << YAML::Value << sphereColliderComponent.IsTrigger;
|
||||||
|
|
||||||
out << YAML::EndMap; // SphereColliderComponent
|
out << YAML::EndMap; // SphereColliderComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entity.HasComponent<CapsuleColliderComponent>())
|
||||||
|
{
|
||||||
|
out << YAML::Key << "CapsuleColliderComponent";
|
||||||
|
out << YAML::BeginMap; // CapsuleColliderComponent
|
||||||
|
|
||||||
|
const auto& capsuleColliderComponent = entity.GetComponent<CapsuleColliderComponent>();
|
||||||
|
out << YAML::Key << "Radius" << YAML::Value << capsuleColliderComponent.Radius;
|
||||||
|
out << YAML::Key << "Height" << YAML::Value << capsuleColliderComponent.Height;
|
||||||
|
out << YAML::Key << "IsTrigger" << YAML::Value << capsuleColliderComponent.IsTrigger;
|
||||||
|
|
||||||
|
out << YAML::EndMap; // CapsuleColliderComponent
|
||||||
|
}
|
||||||
|
|
||||||
if (entity.HasComponent<MeshColliderComponent>())
|
if (entity.HasComponent<MeshColliderComponent>())
|
||||||
{
|
{
|
||||||
out << YAML::Key << "MeshColliderComponent";
|
out << YAML::Key << "MeshColliderComponent";
|
||||||
out << YAML::BeginMap; // MeshColliderComponent
|
out << YAML::BeginMap; // MeshColliderComponent
|
||||||
|
|
||||||
auto mesh = entity.GetComponent<MeshColliderComponent>().CollisionMesh;
|
auto meshColliderComponent = entity.GetComponent<MeshColliderComponent>();
|
||||||
out << YAML::Key << "AssetPath" << YAML::Value << mesh->GetFilePath();
|
out << YAML::Key << "AssetPath" << YAML::Value << meshColliderComponent.CollisionMesh->GetFilePath();
|
||||||
|
out << YAML::Key << "IsTrigger" << YAML::Value << meshColliderComponent.IsTrigger;
|
||||||
|
|
||||||
out << YAML::EndMap; // MeshColliderComponent
|
out << YAML::EndMap; // MeshColliderComponent
|
||||||
}
|
}
|
||||||
@ -527,15 +547,17 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
for (auto field : storedFields)
|
for (auto field : storedFields)
|
||||||
{
|
{
|
||||||
std::string name = field["Name"].as<std::string>();
|
auto name = field["Name"].as<std::string>();
|
||||||
FieldType type = (FieldType)field["Type"].as<uint32_t>();
|
auto type = (FieldType)field["Type"].as<uint32_t>();
|
||||||
EntityInstanceData& data = ScriptEngine::GetEntityInstanceData(m_Scene->GetUUID(), uuid);
|
EntityInstanceData& data = ScriptEngine::GetEntityInstanceData(m_Scene->GetUUID(), uuid);
|
||||||
auto& moduleFieldMap = data.ModuleFieldMap;
|
auto& moduleFieldMap = data.ModuleFieldMap;
|
||||||
auto& publicFields = moduleFieldMap[moduleName];
|
auto& publicFields = moduleFieldMap[moduleName];
|
||||||
if (publicFields.find(name) == publicFields.end())
|
if (publicFields.find(name) == publicFields.end())
|
||||||
{
|
{
|
||||||
PublicField pf = { name, type };
|
// PublicField pf = { name, type };
|
||||||
publicFields.emplace(name, std::move(pf));
|
// publicFields.emplace(name, std::move(pf));
|
||||||
|
PM_CORE_WARN("Script field '{0}' not found in current Script file! ignore this.", name);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
auto dataNode = field["Data"];
|
auto dataNode = field["Data"];
|
||||||
switch (type)
|
switch (type)
|
||||||
@ -639,13 +661,15 @@ namespace Prism
|
|||||||
auto& component = deserializedEntity.AddComponent<RigidBodyComponent>();
|
auto& component = deserializedEntity.AddComponent<RigidBodyComponent>();
|
||||||
component.BodyType = (RigidBodyComponent::Type)rigidBodyComponent["BodyType"].as<int>();
|
component.BodyType = (RigidBodyComponent::Type)rigidBodyComponent["BodyType"].as<int>();
|
||||||
component.Mass = rigidBodyComponent["Mass"].as<float>();
|
component.Mass = rigidBodyComponent["Mass"].as<float>();
|
||||||
|
component.IsKinematic = rigidBodyComponent["IsKinematic"] ? rigidBodyComponent["IsKinematic"].as<bool>() : false;
|
||||||
|
|
||||||
|
component.LockPositionX = rigidBodyComponent["Constraints"]["LockPositionX"].as<bool>();
|
||||||
|
component.LockPositionY = rigidBodyComponent["Constraints"]["LockPositionY"].as<bool>();
|
||||||
|
component.LockPositionZ = rigidBodyComponent["Constraints"]["LockPositionZ"].as<bool>();
|
||||||
|
component.LockRotationX = rigidBodyComponent["Constraints"]["LockRotationX"].as<bool>();
|
||||||
|
component.LockRotationY = rigidBodyComponent["Constraints"]["LockRotationY"].as<bool>();
|
||||||
|
component.LockRotationZ = rigidBodyComponent["Constraints"]["LockRotationZ"].as<bool>();
|
||||||
|
|
||||||
component.LockPositionX = rigidBodyComponent["LockPositionX"] ? rigidBodyComponent["LockPositionX"].as<bool>() : false;
|
|
||||||
component.LockPositionY = rigidBodyComponent["LockPositionY"] ? rigidBodyComponent["LockPositionY"].as<bool>() : false;
|
|
||||||
component.LockPositionZ = rigidBodyComponent["LockPositionZ"] ? rigidBodyComponent["LockPositionZ"].as<bool>() : false;
|
|
||||||
component.LockRotationX = rigidBodyComponent["LockRotationX"] ? rigidBodyComponent["LockRotationX"].as<bool>() : false;
|
|
||||||
component.LockRotationY = rigidBodyComponent["LockRotationY"] ? rigidBodyComponent["LockRotationY"].as<bool>() : false;
|
|
||||||
component.LockRotationZ = rigidBodyComponent["LockRotationZ"] ? rigidBodyComponent["LockRotationZ"].as<bool>() : false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto physicsMaterialComponent = entity["PhysicsMaterialComponent"])
|
if (auto physicsMaterialComponent = entity["PhysicsMaterialComponent"])
|
||||||
@ -661,18 +685,33 @@ namespace Prism
|
|||||||
auto& component = deserializedEntity.AddComponent<BoxColliderComponent>();
|
auto& component = deserializedEntity.AddComponent<BoxColliderComponent>();
|
||||||
component.Offset = boxColliderComponent["Offset"].as<glm::vec3>();
|
component.Offset = boxColliderComponent["Offset"].as<glm::vec3>();
|
||||||
component.Size = boxColliderComponent["Size"].as<glm::vec3>();
|
component.Size = boxColliderComponent["Size"].as<glm::vec3>();
|
||||||
|
component.IsTrigger = boxColliderComponent["IsTrigger"] ? boxColliderComponent["IsTrigger"].as<bool>() : false;
|
||||||
|
component.DebugMesh = MeshFactory::CreateBox(component.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto sphereColliderComponent = entity["SphereColliderComponent"])
|
if (auto sphereColliderComponent = entity["SphereColliderComponent"])
|
||||||
{
|
{
|
||||||
auto& component = deserializedEntity.AddComponent<SphereColliderComponent>();
|
auto& component = deserializedEntity.AddComponent<SphereColliderComponent>();
|
||||||
component.Radius = sphereColliderComponent["Radius"].as<float>();
|
component.Radius = sphereColliderComponent["Radius"].as<float>();
|
||||||
|
component.IsTrigger = sphereColliderComponent["IsTrigger"] ? sphereColliderComponent["IsTrigger"].as<bool>() : false;
|
||||||
|
component.DebugMesh = MeshFactory::CreateSphere(component.Radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto capsuleColliderComponent = entity["CapsuleColliderComponent"])
|
||||||
|
{
|
||||||
|
auto& component = deserializedEntity.AddComponent<CapsuleColliderComponent>();
|
||||||
|
component.Radius = capsuleColliderComponent["Radius"].as<float>();
|
||||||
|
component.Height = capsuleColliderComponent["Height"].as<float>();
|
||||||
|
component.IsTrigger = capsuleColliderComponent["IsTrigger"] ? capsuleColliderComponent["IsTrigger"].as<bool>() : false;
|
||||||
|
component.DebugMesh = MeshFactory::CreateCapsule(component.Radius, component.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto meshColliderComponent = entity["MeshColliderComponent"])
|
if (auto meshColliderComponent = entity["MeshColliderComponent"])
|
||||||
{
|
{
|
||||||
auto meshPath = meshColliderComponent["AssetPath"].as<std::string>();
|
auto meshPath = meshColliderComponent["AssetPath"].as<std::string>();
|
||||||
deserializedEntity.AddComponent<MeshColliderComponent>(Ref<Mesh>::Create(meshPath));
|
auto& component = deserializedEntity.AddComponent<MeshColliderComponent>(Ref<Mesh>::Create(meshPath));
|
||||||
|
component.IsTrigger = meshColliderComponent["IsTrigger"] ? meshColliderComponent["IsTrigger"].as<bool>() : false;
|
||||||
|
PxPhysicsWrappers::CreateConvexMesh(component);
|
||||||
|
|
||||||
PM_CORE_INFO(" Mesh Collider Asset Path: {0}", meshPath);
|
PM_CORE_INFO(" Mesh Collider Asset Path: {0}", meshPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,6 +45,7 @@ namespace Prism
|
|||||||
std::string NamespaceName;
|
std::string NamespaceName;
|
||||||
|
|
||||||
MonoClass* Class = nullptr;
|
MonoClass* Class = nullptr;
|
||||||
|
MonoMethod* Constructor = nullptr;
|
||||||
MonoMethod* OnCreateMethod = nullptr;
|
MonoMethod* OnCreateMethod = nullptr;
|
||||||
MonoMethod* OnDestroyMethod = nullptr;
|
MonoMethod* OnDestroyMethod = nullptr;
|
||||||
MonoMethod* OnUpdateMethod = nullptr;
|
MonoMethod* OnUpdateMethod = nullptr;
|
||||||
@ -52,17 +53,22 @@ namespace Prism
|
|||||||
// Physics
|
// Physics
|
||||||
MonoMethod* OnCollisionBeginMethod = nullptr;
|
MonoMethod* OnCollisionBeginMethod = nullptr;
|
||||||
MonoMethod* OnCollisionEndMethod = nullptr;
|
MonoMethod* OnCollisionEndMethod = nullptr;
|
||||||
|
MonoMethod* OnTriggerBeginMethod = nullptr;
|
||||||
|
MonoMethod* OnTriggerEndMethod = nullptr;
|
||||||
MonoMethod* OnCollision2DBeginMethod = nullptr;
|
MonoMethod* OnCollision2DBeginMethod = nullptr;
|
||||||
MonoMethod* OnCollision2DEndMethod = nullptr;
|
MonoMethod* OnCollision2DEndMethod = nullptr;
|
||||||
|
|
||||||
void InitClassMethods(MonoImage* image)
|
void InitClassMethods(MonoImage* image)
|
||||||
{
|
{
|
||||||
|
Constructor = GetMethod(s_CoreAssemblyImage, "Prism.Entity:.ctor(ulong)");
|
||||||
OnCreateMethod = GetMethod(image, FullName + ":OnCreate()");
|
OnCreateMethod = GetMethod(image, FullName + ":OnCreate()");
|
||||||
OnUpdateMethod = GetMethod(image, FullName + ":OnUpdate(single)");
|
OnUpdateMethod = GetMethod(image, FullName + ":OnUpdate(single)");
|
||||||
|
|
||||||
// Physics (Entity class)
|
// Physics (Entity class)
|
||||||
OnCollision2DBeginMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollision2DBegin(single)");
|
OnCollision2DBeginMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollision2DBegin(single)");
|
||||||
OnCollision2DEndMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollision2DEnd(single)");
|
OnCollision2DEndMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollision2DEnd(single)");
|
||||||
|
OnTriggerBeginMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnTriggerBegin(single)");
|
||||||
|
OnTriggerEndMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnTriggerEnd(single)");
|
||||||
OnCollisionBeginMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollisionBegin(single)");
|
OnCollisionBeginMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollisionBegin(single)");
|
||||||
OnCollisionEndMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollisionEnd(single)");
|
OnCollisionEndMethod = GetMethod(s_CoreAssemblyImage, "Prism.Entity:OnCollisionEnd(single)");
|
||||||
|
|
||||||
@ -415,7 +421,7 @@ namespace Prism
|
|||||||
return s_SceneContext;
|
return s_SceneContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::CopyEntityScriptData(UUID dst, UUID src)
|
void ScriptEngine::CopyEntityScriptData(const UUID& dst, const UUID& src)
|
||||||
{
|
{
|
||||||
PM_CORE_ASSERT(s_EntityInstanceMap.find(dst) != s_EntityInstanceMap.end());
|
PM_CORE_ASSERT(s_EntityInstanceMap.find(dst) != s_EntityInstanceMap.end());
|
||||||
PM_CORE_ASSERT(s_EntityInstanceMap.find(src) != s_EntityInstanceMap.end());
|
PM_CORE_ASSERT(s_EntityInstanceMap.find(src) != s_EntityInstanceMap.end());
|
||||||
@ -442,19 +448,14 @@ namespace Prism
|
|||||||
|
|
||||||
void ScriptEngine::OnCreateEntity(Entity entity)
|
void ScriptEngine::OnCreateEntity(Entity entity)
|
||||||
{
|
{
|
||||||
OnCreateEntity(entity.m_Scene->GetUUID(), entity.GetComponent<IDComponent>().ID);
|
EntityInstance& entityInstance = GetEntityInstanceData(entity.GetSceneUUID(), entity.GetUUID()).Instance;
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptEngine::OnCreateEntity(UUID sceneID, UUID entityID)
|
|
||||||
{
|
|
||||||
EntityInstance& entityInstance = GetEntityInstanceData(sceneID, entityID).Instance;
|
|
||||||
if (entityInstance.ScriptClass->OnCreateMethod)
|
if (entityInstance.ScriptClass->OnCreateMethod)
|
||||||
CallMethod(entityInstance.GetInstance(), entityInstance.ScriptClass->OnCreateMethod);
|
CallMethod(entityInstance.GetInstance(), entityInstance.ScriptClass->OnCreateMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::OnUpdateEntity(UUID sceneID, UUID entityID, TimeStep ts)
|
void ScriptEngine::OnUpdateEntity(Entity entity, TimeStep ts)
|
||||||
{
|
{
|
||||||
EntityInstance& entityInstance = GetEntityInstanceData(sceneID, entityID).Instance;
|
EntityInstance& entityInstance = GetEntityInstanceData( entity.GetSceneUUID(), entity.GetUUID()).Instance;
|
||||||
if (entityInstance.ScriptClass->OnUpdateMethod)
|
if (entityInstance.ScriptClass->OnUpdateMethod)
|
||||||
{
|
{
|
||||||
void* args[] = { &ts };
|
void* args[] = { &ts };
|
||||||
@ -462,14 +463,10 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScriptEngine::OnCollision2DBegin(Entity entity)
|
void ScriptEngine::OnCollision2DBegin(Entity entity)
|
||||||
{
|
{
|
||||||
OnCollision2DBegin(entity.m_Scene->GetUUID(), entity.GetComponent<IDComponent>().ID);
|
EntityInstance& entityInstance = GetEntityInstanceData(entity.GetSceneUUID(), entity.GetUUID()).Instance;
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptEngine::OnCollision2DBegin(const UUID &sceneID, const UUID &entityID)
|
|
||||||
{
|
|
||||||
EntityInstance& entityInstance = GetEntityInstanceData(sceneID, entityID).Instance;
|
|
||||||
if (entityInstance.ScriptClass->OnCollision2DBeginMethod)
|
if (entityInstance.ScriptClass->OnCollision2DBeginMethod)
|
||||||
{
|
{
|
||||||
float value = 5.0f;
|
float value = 5.0f;
|
||||||
@ -481,12 +478,7 @@ namespace Prism
|
|||||||
|
|
||||||
void ScriptEngine::OnCollision2DEnd(Entity entity)
|
void ScriptEngine::OnCollision2DEnd(Entity entity)
|
||||||
{
|
{
|
||||||
OnCollision2DEnd(entity.m_Scene->GetUUID(), entity.GetComponent<IDComponent>().ID);
|
EntityInstance& entityInstance = GetEntityInstanceData(entity.GetSceneUUID(), entity.GetUUID()).Instance;
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptEngine::OnCollision2DEnd(const UUID &sceneID, const UUID &entityID)
|
|
||||||
{
|
|
||||||
EntityInstance& entityInstance = GetEntityInstanceData(sceneID, entityID).Instance;
|
|
||||||
if (entityInstance.ScriptClass->OnCollision2DEndMethod)
|
if (entityInstance.ScriptClass->OnCollision2DEndMethod)
|
||||||
{
|
{
|
||||||
float value = 5.0f;
|
float value = 5.0f;
|
||||||
@ -498,12 +490,7 @@ namespace Prism
|
|||||||
|
|
||||||
void ScriptEngine::OnCollisionBegin(Entity entity)
|
void ScriptEngine::OnCollisionBegin(Entity entity)
|
||||||
{
|
{
|
||||||
OnCollisionBegin(entity.m_Scene->GetUUID(), entity.GetComponent<IDComponent>().ID);
|
EntityInstance& entityInstance = GetEntityInstanceData(entity.GetSceneUUID(), entity.GetUUID()).Instance;
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptEngine::OnCollisionBegin(const UUID& sceneID, const UUID& entityID)
|
|
||||||
{
|
|
||||||
EntityInstance& entityInstance = GetEntityInstanceData(sceneID, entityID).Instance;
|
|
||||||
if (entityInstance.ScriptClass->OnCollisionBeginMethod)
|
if (entityInstance.ScriptClass->OnCollisionBeginMethod)
|
||||||
{
|
{
|
||||||
float value = 5.0f;
|
float value = 5.0f;
|
||||||
@ -514,12 +501,7 @@ namespace Prism
|
|||||||
|
|
||||||
void ScriptEngine::OnCollisionEnd(Entity entity)
|
void ScriptEngine::OnCollisionEnd(Entity entity)
|
||||||
{
|
{
|
||||||
OnCollisionEnd(entity.m_Scene->GetUUID(), entity.GetComponent<IDComponent>().ID);
|
EntityInstance& entityInstance = GetEntityInstanceData(entity.GetSceneUUID(), entity.GetUUID()).Instance;
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptEngine::OnCollisionEnd(const UUID& sceneID, const UUID& entityID)
|
|
||||||
{
|
|
||||||
EntityInstance& entityInstance = GetEntityInstanceData(sceneID, entityID).Instance;
|
|
||||||
if (entityInstance.ScriptClass->OnCollisionEndMethod)
|
if (entityInstance.ScriptClass->OnCollisionEndMethod)
|
||||||
{
|
{
|
||||||
float value = 5.0f;
|
float value = 5.0f;
|
||||||
@ -528,6 +510,33 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::OnTriggerBegin(Entity entity)
|
||||||
|
{
|
||||||
|
EntityInstance& entityInstance = GetEntityInstanceData(entity.GetSceneUUID(), entity.GetUUID()).Instance;
|
||||||
|
if (entityInstance.ScriptClass->OnTriggerBeginMethod)
|
||||||
|
{
|
||||||
|
float value = 5.0f;
|
||||||
|
void* args[] = { &value };
|
||||||
|
CallMethod(entityInstance.GetInstance(), entityInstance.ScriptClass->OnTriggerBeginMethod, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::OnTriggerEnd(Entity entity)
|
||||||
|
{
|
||||||
|
EntityInstance& entityInstance = GetEntityInstanceData(entity.GetSceneUUID(), entity.GetUUID()).Instance;
|
||||||
|
if (entityInstance.ScriptClass->OnTriggerEndMethod)
|
||||||
|
{
|
||||||
|
float value = 5.0f;
|
||||||
|
void* args[] = { &value };
|
||||||
|
CallMethod(entityInstance.GetInstance(), entityInstance.ScriptClass->OnTriggerEndMethod, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScriptEngine::IsEntityModuleValid(Entity entity)
|
||||||
|
{
|
||||||
|
return entity.HasComponent<ScriptComponent>() && ModuleExists(entity.GetComponent<ScriptComponent>().ModuleName);
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptEngine::OnScriptComponentDestroyed(const UUID &sceneID, const UUID &entityID)
|
void ScriptEngine::OnScriptComponentDestroyed(const UUID &sceneID, const UUID &entityID)
|
||||||
{
|
{
|
||||||
PM_CORE_ASSERT(s_EntityInstanceMap.find(sceneID) != s_EntityInstanceMap.end());
|
PM_CORE_ASSERT(s_EntityInstanceMap.find(sceneID) != s_EntityInstanceMap.end());
|
||||||
@ -646,11 +655,14 @@ namespace Prism
|
|||||||
PM_CORE_ASSERT(entityInstance.ScriptClass);
|
PM_CORE_ASSERT(entityInstance.ScriptClass);
|
||||||
entityInstance.Handle = Instantiate(*entityInstance.ScriptClass);
|
entityInstance.Handle = Instantiate(*entityInstance.ScriptClass);
|
||||||
|
|
||||||
|
/*
|
||||||
MonoProperty* entityIDPropery = mono_class_get_property_from_name(entityInstance.ScriptClass->Class, "ID");
|
MonoProperty* entityIDPropery = mono_class_get_property_from_name(entityInstance.ScriptClass->Class, "ID");
|
||||||
mono_property_get_get_method(entityIDPropery);
|
mono_property_get_get_method(entityIDPropery);
|
||||||
MonoMethod* entityIDSetMethod = mono_property_get_set_method(entityIDPropery);
|
MonoMethod* entityIDSetMethod = mono_property_get_set_method(entityIDPropery);
|
||||||
|
*/
|
||||||
|
|
||||||
void* param[] = { &id };
|
void* param[] = { &id };
|
||||||
CallMethod(entityInstance.GetInstance(), entityIDSetMethod, param);
|
CallMethod(entityInstance.GetInstance(), entityInstance.ScriptClass->Constructor, param);
|
||||||
|
|
||||||
// Set all public fields to appropriate values
|
// Set all public fields to appropriate values
|
||||||
ScriptModuleFieldMap& moduleFieldMap = entityInstanceData.ModuleFieldMap;
|
ScriptModuleFieldMap& moduleFieldMap = entityInstanceData.ModuleFieldMap;
|
||||||
|
|||||||
@ -112,21 +112,21 @@ namespace Prism
|
|||||||
static void SetSceneContext(const Ref<Scene>& scene);
|
static void SetSceneContext(const Ref<Scene>& scene);
|
||||||
static const Ref<Scene>& GetCurrentSceneContext();
|
static const Ref<Scene>& GetCurrentSceneContext();
|
||||||
|
|
||||||
static void CopyEntityScriptData(UUID dst, UUID src);
|
static void CopyEntityScriptData(const UUID& dst, const UUID& src);
|
||||||
|
|
||||||
static void OnCreateEntity(Entity entity);
|
static void OnCreateEntity(Entity entity);
|
||||||
static void OnCreateEntity(UUID sceneID, UUID entityID);
|
static void OnUpdateEntity(Entity entity, TimeStep ts);
|
||||||
static void OnUpdateEntity(UUID sceneID, UUID entityID, TimeStep ts);
|
|
||||||
|
|
||||||
static void OnCollision2DBegin(Entity entity);
|
static void OnCollision2DBegin(Entity entity);
|
||||||
static void OnCollision2DBegin(const UUID &sceneID, const UUID &entityID);
|
|
||||||
static void OnCollision2DEnd(Entity entity);
|
static void OnCollision2DEnd(Entity entity);
|
||||||
static void OnCollision2DEnd(const UUID &sceneID, const UUID &entityID);
|
|
||||||
|
|
||||||
static void OnCollisionBegin(Entity entity);
|
static void OnCollisionBegin(Entity entity);
|
||||||
static void OnCollisionBegin(const UUID& sceneID, const UUID& entityID);
|
|
||||||
static void OnCollisionEnd(Entity entity);
|
static void OnCollisionEnd(Entity entity);
|
||||||
static void OnCollisionEnd(const UUID& sceneID, const UUID& entityID);
|
|
||||||
|
static void OnTriggerBegin(Entity entityID);
|
||||||
|
static void OnTriggerEnd(Entity entityID);
|
||||||
|
|
||||||
|
static bool IsEntityModuleValid(Entity entity);
|
||||||
|
|
||||||
static void OnScriptComponentDestroyed(const UUID &sceneID, const UUID &entityID);
|
static void OnScriptComponentDestroyed(const UUID &sceneID, const UUID &entityID);
|
||||||
|
|
||||||
|
|||||||
@ -53,9 +53,20 @@ namespace Prism
|
|||||||
|
|
||||||
mono_add_internal_call("Prism.Entity::GetTransform_Native",(const void*)Prism::Script::Prism_Entity_GetTransform);
|
mono_add_internal_call("Prism.Entity::GetTransform_Native",(const void*)Prism::Script::Prism_Entity_GetTransform);
|
||||||
mono_add_internal_call("Prism.Entity::SetTransform_Native",(const void*)Prism::Script::Prism_Entity_SetTransform);
|
mono_add_internal_call("Prism.Entity::SetTransform_Native",(const void*)Prism::Script::Prism_Entity_SetTransform);
|
||||||
|
mono_add_internal_call("Prism.TransformComponent::GetRelativeDirection_Native", (const void*)Prism::Script::Prism_TransformComponent_GetRelativeDirection);
|
||||||
|
|
||||||
|
|
||||||
|
mono_add_internal_call("Prism.TransformComponent::GetTransform_Native", (const void*)Prism::Script::Prism_Entity_GetTransform);
|
||||||
|
mono_add_internal_call("Prism.TransformComponent::SetTransform_Native", (const void*)Prism::Script::Prism_Entity_SetTransform);
|
||||||
|
mono_add_internal_call("Prism.TransformComponent::GetRotation_Native", (const void*)Prism::Script::Prism_TransformComponent_GetRotation);
|
||||||
|
mono_add_internal_call("Prism.TransformComponent::SetRotation_Native", (const void*)Prism::Script::Prism_TransformComponent_SetRotation);
|
||||||
|
|
||||||
|
/*
|
||||||
mono_add_internal_call("Prism.Entity::GetForwardDirection_Native", Prism::Script::Prism_Entity_GetForwardDirection);
|
mono_add_internal_call("Prism.Entity::GetForwardDirection_Native", Prism::Script::Prism_Entity_GetForwardDirection);
|
||||||
mono_add_internal_call("Prism.Entity::GetRightDirection_Native", Prism::Script::Prism_Entity_GetRightDirection);
|
mono_add_internal_call("Prism.Entity::GetRightDirection_Native", Prism::Script::Prism_Entity_GetRightDirection);
|
||||||
mono_add_internal_call("Prism.Entity::GetUpDirection_Native", Prism::Script::Prism_Entity_GetUpDirection);
|
mono_add_internal_call("Prism.Entity::GetUpDirection_Native", Prism::Script::Prism_Entity_GetUpDirection);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
mono_add_internal_call("Prism.Entity::CreateComponent_Native",(const void*)Prism::Script::Prism_Entity_CreateComponent);
|
mono_add_internal_call("Prism.Entity::CreateComponent_Native",(const void*)Prism::Script::Prism_Entity_CreateComponent);
|
||||||
mono_add_internal_call("Prism.Entity::HasComponent_Native",(const void*)Prism::Script::Prism_Entity_HasComponent);
|
mono_add_internal_call("Prism.Entity::HasComponent_Native",(const void*)Prism::Script::Prism_Entity_HasComponent);
|
||||||
@ -64,21 +75,30 @@ namespace Prism
|
|||||||
mono_add_internal_call("Prism.MeshComponent::GetMesh_Native",(const void*)Prism::Script::Prism_MeshComponent_GetMesh);
|
mono_add_internal_call("Prism.MeshComponent::GetMesh_Native",(const void*)Prism::Script::Prism_MeshComponent_GetMesh);
|
||||||
mono_add_internal_call("Prism.MeshComponent::SetMesh_Native",(const void*)Prism::Script::Prism_MeshComponent_SetMesh);
|
mono_add_internal_call("Prism.MeshComponent::SetMesh_Native",(const void*)Prism::Script::Prism_MeshComponent_SetMesh);
|
||||||
|
|
||||||
|
// Input
|
||||||
mono_add_internal_call("Prism.Input::IsKeyPressed_Native", (const void*)Prism::Script::Prism_Input_IsKeyPressed);
|
mono_add_internal_call("Prism.Input::IsKeyPressed_Native", (const void*)Prism::Script::Prism_Input_IsKeyPressed);
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 2D Physic
|
||||||
mono_add_internal_call("Prism.RigidBody2DComponent::ApplyLinearImpulse_Native", (const void*)Prism::Script::Prism_RigidBody2DComponent_ApplyLinearImpulse);
|
mono_add_internal_call("Prism.RigidBody2DComponent::ApplyLinearImpulse_Native", (const void*)Prism::Script::Prism_RigidBody2DComponent_ApplyLinearImpulse);
|
||||||
mono_add_internal_call("Prism.RigidBody2DComponent::GetLinearVelocity_Native", (const void *)Prism::Script::Prism_RigidBody2DComponent_GetLinearVelocity);
|
mono_add_internal_call("Prism.RigidBody2DComponent::GetLinearVelocity_Native", (const void *)Prism::Script::Prism_RigidBody2DComponent_GetLinearVelocity);
|
||||||
mono_add_internal_call("Prism.RigidBody2DComponent::SetLinearVelocity_Native", (const void *)Prism::Script::Prism_RigidBody2DComponent_SetLinearVelocity);
|
mono_add_internal_call("Prism.RigidBody2DComponent::SetLinearVelocity_Native", (const void *)Prism::Script::Prism_RigidBody2DComponent_SetLinearVelocity);
|
||||||
|
|
||||||
|
// Renderer
|
||||||
|
// Texture2D
|
||||||
mono_add_internal_call("Prism.Texture2D::Constructor_Native", (const void*)Prism::Script::Prism_Texture2D_Constructor);
|
mono_add_internal_call("Prism.Texture2D::Constructor_Native", (const void*)Prism::Script::Prism_Texture2D_Constructor);
|
||||||
mono_add_internal_call("Prism.Texture2D::Destructor_Native", (const void*)Prism::Script::Prism_Texture2D_Destructor);
|
mono_add_internal_call("Prism.Texture2D::Destructor_Native", (const void*)Prism::Script::Prism_Texture2D_Destructor);
|
||||||
mono_add_internal_call("Prism.Texture2D::SetData_Native", (const void*)Prism::Script::Prism_Texture2D_SetData);
|
mono_add_internal_call("Prism.Texture2D::SetData_Native", (const void*)Prism::Script::Prism_Texture2D_SetData);
|
||||||
|
|
||||||
mono_add_internal_call("Prism.RigidBodyComponent::AddForce_Native", Prism::Script::Prism_RigidBodyComponent_AddForce);
|
mono_add_internal_call("Prism.RigidBodyComponent::AddForce_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_AddForce);
|
||||||
mono_add_internal_call("Prism.RigidBodyComponent::AddTorque_Native", Prism::Script::Prism_RigidBodyComponent_AddTorque);
|
mono_add_internal_call("Prism.RigidBodyComponent::AddTorque_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_AddTorque);
|
||||||
mono_add_internal_call("Prism.RigidBodyComponent::GetLinearVelocity_Native", Prism::Script::Prism_RigidBodyComponent_GetLinearVelocity);
|
mono_add_internal_call("Prism.RigidBodyComponent::GetLinearVelocity_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_GetLinearVelocity);
|
||||||
mono_add_internal_call("Prism.RigidBodyComponent::SetLinearVelocity_Native", Prism::Script::Prism_RigidBodyComponent_SetLinearVelocity);
|
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);
|
||||||
|
|
||||||
|
// Material
|
||||||
mono_add_internal_call("Prism.Material::Destructor_Native", (const void*)Prism::Script::Prism_Material_Destructor);
|
mono_add_internal_call("Prism.Material::Destructor_Native", (const void*)Prism::Script::Prism_Material_Destructor);
|
||||||
mono_add_internal_call("Prism.Material::SetFloat_Native", (const void*)Prism::Script::Prism_Material_SetFloat);
|
mono_add_internal_call("Prism.Material::SetFloat_Native", (const void*)Prism::Script::Prism_Material_SetFloat);
|
||||||
mono_add_internal_call("Prism.Material::SetTexture_Native", (const void*)Prism::Script::Prism_Material_SetTexture);
|
mono_add_internal_call("Prism.Material::SetTexture_Native", (const void*)Prism::Script::Prism_Material_SetTexture);
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "PxRigidActor.h"
|
#include "PxRigidActor.h"
|
||||||
#include "PxRigidDynamic.h"
|
#include "PxRigidDynamic.h"
|
||||||
#include "Prism/Physics/Physics3D.h"
|
#include "Prism/Physics/Physics3D.h"
|
||||||
|
#include "Prism/Physics/PhysicsUtils.h"
|
||||||
|
|
||||||
namespace Prism {
|
namespace Prism {
|
||||||
extern std::unordered_map<MonoType*, std::function<bool(Entity&)>> s_HasComponentFuncs;
|
extern std::unordered_map<MonoType*, std::function<bool(Entity&)>> s_HasComponentFuncs;
|
||||||
@ -70,6 +71,22 @@ namespace Prism { namespace Script {
|
|||||||
return Input::IsKeyPressed(key);
|
return Input::IsKeyPressed(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Prism_Input_GetMousePosition(glm::vec2* outPosition)
|
||||||
|
{
|
||||||
|
auto [x, y] = Input::GetMousePosition();
|
||||||
|
*outPosition = { x, y };
|
||||||
|
}
|
||||||
|
|
||||||
|
void Prism_Input_SetCursorMode(const CursorMode mode)
|
||||||
|
{
|
||||||
|
Input::SetCursorMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorMode Prism_Input_GetCursorMode()
|
||||||
|
{
|
||||||
|
return Input::GetCursorMode();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
@ -99,6 +116,8 @@ namespace Prism { namespace Script {
|
|||||||
auto& transformComponent = entity.GetComponent<TransformComponent>();
|
auto& transformComponent = entity.GetComponent<TransformComponent>();
|
||||||
memcpy(glm::value_ptr(transformComponent.Transform), inTransform, sizeof(glm::mat4));
|
memcpy(glm::value_ptr(transformComponent.Transform), inTransform, sizeof(glm::mat4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void Prism_Entity_GetForwardDirection(const uint64_t entityID, glm::vec3* outForward)
|
void Prism_Entity_GetForwardDirection(const uint64_t entityID, glm::vec3* outForward)
|
||||||
{
|
{
|
||||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||||
@ -140,6 +159,7 @@ namespace Prism { namespace Script {
|
|||||||
auto [position, rotation, scale] = GetTransformDecomposition(transformComponent.Transform);
|
auto [position, rotation, scale] = GetTransformDecomposition(transformComponent.Transform);
|
||||||
*outUp = glm::rotate(glm::inverse(glm::normalize(rotation)), glm::vec3(0, 1, 0));
|
*outUp = glm::rotate(glm::inverse(glm::normalize(rotation)), glm::vec3(0, 1, 0));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -181,6 +201,50 @@ namespace Prism { namespace Script {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Prism_TransformComponent_GetRelativeDirection(const uint64_t entityID, glm::vec3* outDirection, const glm::vec3* inAbsoluteDirection)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
*outDirection = glm::rotate(glm::normalize(rotation), *inAbsoluteDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Prism_TransformComponent_GetRotation(const uint64_t entityID, glm::vec3* outRotation)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
*outRotation = glm::degrees(glm::eulerAngles(rotation));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Prism_TransformComponent_SetRotation(const uint64_t entityID, const glm::vec3* inRotation)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
auto& transform = entity.Transform();
|
||||||
|
|
||||||
|
auto [position, rotation, scale] = GetTransformDecomposition(transform);
|
||||||
|
transform = glm::translate(glm::mat4(1.0f), position) *
|
||||||
|
glm::toMat4(glm::quat(glm::radians(*inRotation))) *
|
||||||
|
glm::scale(glm::mat4(1.0f), scale);
|
||||||
|
}
|
||||||
|
|
||||||
void* Prism_MeshComponent_GetMesh(const uint64_t entityID)
|
void* Prism_MeshComponent_GetMesh(const uint64_t entityID)
|
||||||
{
|
{
|
||||||
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
Ref<Scene> scene = ScriptEngine::GetCurrentSceneContext();
|
||||||
@ -262,14 +326,16 @@ namespace Prism { namespace Script {
|
|||||||
|
|
||||||
Entity entity = entityMap.at(entityID);
|
Entity entity = entityMap.at(entityID);
|
||||||
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
||||||
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
||||||
physx::PxRigidActor* actor = (physx::PxRigidActor*)component.RuntimeActor;
|
if (component.IsKinematic)
|
||||||
physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
{
|
||||||
|
PM_CORE_WARN("Cannot add a force to a kinematic actor! EntityID({0})", entityID);
|
||||||
// We don't want to assert since scripts might want to be able to switch
|
|
||||||
// between a static and dynamic actor at runtime
|
|
||||||
if (!dynamicActor)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
|
||||||
|
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||||
|
PM_CORE_ASSERT(dynamicActor);
|
||||||
|
|
||||||
PM_CORE_ASSERT(force);
|
PM_CORE_ASSERT(force);
|
||||||
dynamicActor->addForce({ force->x, force->y, force->z }, (physx::PxForceMode::Enum)forceMode);
|
dynamicActor->addForce({ force->x, force->y, force->z }, (physx::PxForceMode::Enum)forceMode);
|
||||||
@ -284,14 +350,16 @@ namespace Prism { namespace Script {
|
|||||||
|
|
||||||
Entity entity = entityMap.at(entityID);
|
Entity entity = entityMap.at(entityID);
|
||||||
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
||||||
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
||||||
physx::PxRigidActor* actor = (physx::PxRigidActor*)component.RuntimeActor;
|
if (component.IsKinematic)
|
||||||
physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
{
|
||||||
|
PM_CORE_WARN("Cannot add torque to a kinematic actor! EntityID({0})", entityID);
|
||||||
// We don't want to assert since scripts might want to be able to switch
|
|
||||||
// between a static and dynamic actor at runtime
|
|
||||||
if (!dynamicActor)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
|
||||||
|
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||||
|
PM_CORE_ASSERT(dynamicActor);
|
||||||
|
|
||||||
PM_CORE_ASSERT(torque);
|
PM_CORE_ASSERT(torque);
|
||||||
dynamicActor->addTorque({ torque->x, torque->y, torque->z }, (physx::PxForceMode::Enum)forceMode);
|
dynamicActor->addTorque({ torque->x, torque->y, torque->z }, (physx::PxForceMode::Enum)forceMode);
|
||||||
@ -306,14 +374,17 @@ namespace Prism { namespace Script {
|
|||||||
|
|
||||||
Entity entity = entityMap.at(entityID);
|
Entity entity = entityMap.at(entityID);
|
||||||
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
||||||
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
||||||
physx::PxRigidActor* actor = (physx::PxRigidActor*)component.RuntimeActor;
|
if (component.IsKinematic)
|
||||||
const physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
{
|
||||||
|
PM_CORE_WARN("Cannot add torque to a kinematic actor! EntityID({0})", entityID);
|
||||||
// We don't want to assert since scripts might want to be able to switch
|
|
||||||
// between a static and dynamic actor at runtime
|
|
||||||
if (!dynamicActor)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
|
||||||
|
const physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||||
|
PM_CORE_ASSERT(dynamicActor);
|
||||||
|
|
||||||
|
|
||||||
PM_CORE_ASSERT(outVelocity);
|
PM_CORE_ASSERT(outVelocity);
|
||||||
physx::PxVec3 velocity = dynamicActor->getLinearVelocity();
|
physx::PxVec3 velocity = dynamicActor->getLinearVelocity();
|
||||||
@ -329,19 +400,44 @@ namespace Prism { namespace Script {
|
|||||||
|
|
||||||
Entity entity = entityMap.at(entityID);
|
Entity entity = entityMap.at(entityID);
|
||||||
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
|
||||||
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
const auto& component = entity.GetComponent<RigidBodyComponent>();
|
||||||
physx::PxRigidActor* actor = (physx::PxRigidActor*)component.RuntimeActor;
|
if (component.IsKinematic)
|
||||||
physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
{
|
||||||
|
PM_CORE_WARN("Cannot add torque to a kinematic actor! EntityID({0})", entityID);
|
||||||
// We don't want to assert since scripts might want to be able to switch
|
|
||||||
// between a static and dynamic actor at runtime
|
|
||||||
if (!dynamicActor)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
|
||||||
|
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||||
|
PM_CORE_ASSERT(dynamicActor);
|
||||||
|
|
||||||
PM_CORE_ASSERT(velocity);
|
PM_CORE_ASSERT(velocity);
|
||||||
dynamicActor->setLinearVelocity({ velocity->x, velocity->y, velocity->z });
|
dynamicActor->setLinearVelocity({ velocity->x, velocity->y, velocity->z });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Prism_RigidBodyComponent_Rotate(uint64_t entityID, glm::vec3* rotation)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
|
||||||
|
PM_CORE_ASSERT(dynamicActor);
|
||||||
|
|
||||||
|
physx::PxTransform transform = dynamicActor->getGlobalPose();
|
||||||
|
transform.q *= (physx::PxQuat(glm::radians(rotation->x), { 1.0F, 0.0F, 0.0F })
|
||||||
|
* physx::PxQuat(glm::radians(rotation->y), { 0.0F, 1.0F, 0.0F })
|
||||||
|
* physx::PxQuat(glm::radians(rotation->z), { 0.0F, 0.0F, 1.0F }));
|
||||||
|
|
||||||
|
dynamicActor->setGlobalPose(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Ref<Mesh>* Prism_Mesh_Constructor(MonoString* filepath)
|
Ref<Mesh>* Prism_Mesh_Constructor(MonoString* filepath)
|
||||||
{
|
{
|
||||||
@ -350,7 +446,7 @@ namespace Prism { namespace Script {
|
|||||||
|
|
||||||
void Prism_Mesh_Destructor(Ref<Mesh>* _this)
|
void Prism_Mesh_Destructor(Ref<Mesh>* _this)
|
||||||
{
|
{
|
||||||
Ref<Mesh>* instance = (Ref<Mesh>*)_this;
|
const Ref<Mesh>* instance = (Ref<Mesh>*)_this;
|
||||||
delete _this;
|
delete _this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#ifndef SCRIPTWARPPERS_H
|
#ifndef SCRIPTWARPPERS_H
|
||||||
#define SCRIPTWARPPERS_H
|
#define SCRIPTWARPPERS_H
|
||||||
|
#include "Prism/Core/Input.h"
|
||||||
#include "Prism/Core/KeyCodes.h"
|
#include "Prism/Core/KeyCodes.h"
|
||||||
#include "Prism/Core/Ref.h"
|
#include "Prism/Core/Ref.h"
|
||||||
#include "Prism/Physics/Physics3D.h"
|
#include "Prism/Physics/Physics3D.h"
|
||||||
@ -23,30 +24,37 @@ namespace Prism { namespace Script {
|
|||||||
|
|
||||||
// Input
|
// Input
|
||||||
bool Prism_Input_IsKeyPressed(KeyCode key);
|
bool Prism_Input_IsKeyPressed(KeyCode key);
|
||||||
|
void Prism_Input_GetMousePosition(glm::vec2* outPosition);
|
||||||
|
void Prism_Input_SetCursorMode(CursorMode mode);
|
||||||
|
CursorMode Prism_Input_GetCursorMode();
|
||||||
|
|
||||||
// Entity
|
// Entity
|
||||||
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_Entity_CreateComponent(uint64_t entityID, void* type);
|
void Prism_Entity_CreateComponent(uint64_t entityID, void* type);
|
||||||
bool Prism_Entity_HasComponent(uint64_t entityID, void* type);
|
bool Prism_Entity_HasComponent(uint64_t entityID, void* type);
|
||||||
uint64_t Prism_Entity_FindEntityByTag(MonoString* tag);
|
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_MeshComponent_GetMesh(uint64_t entityID);
|
void Prism_TransformComponent_GetRelativeDirection(uint64_t entityID, glm::vec3* outDirection, const glm::vec3* inAbsoluteDirection);
|
||||||
void Prism_MeshComponent_SetMesh(uint64_t entityID, const Ref<Mesh>* inMesh);
|
void Prism_TransformComponent_GetRotation(uint64_t entityID,glm::vec3* outRotation);
|
||||||
|
void Prism_TransformComponent_SetRotation(uint64_t entityID,const glm::vec3* inRotation);
|
||||||
|
|
||||||
// 2D Physic
|
// 2D Physic
|
||||||
void Prism_RigidBody2DComponent_ApplyLinearImpulse(uint64_t entityID, const glm::vec2* impulse, const glm::vec2* offset, bool wake);
|
void Prism_RigidBody2DComponent_ApplyLinearImpulse(uint64_t entityID, const glm::vec2* impulse, const glm::vec2* offset, bool wake);
|
||||||
void Prism_RigidBody2DComponent_GetLinearVelocity(uint64_t entityID, glm::vec2* outVelocity);
|
void Prism_RigidBody2DComponent_GetLinearVelocity(uint64_t entityID, glm::vec2* outVelocity);
|
||||||
void Prism_RigidBody2DComponent_SetLinearVelocity(uint64_t entityID, const glm::vec2* velocity);
|
void Prism_RigidBody2DComponent_SetLinearVelocity(uint64_t entityID, const glm::vec2* velocity);
|
||||||
|
|
||||||
|
// 3D Physic
|
||||||
void Prism_RigidBodyComponent_AddForce(uint64_t entityID, glm::vec3* force, ForceMode forceMode);
|
void Prism_RigidBodyComponent_AddForce(uint64_t entityID, glm::vec3* force, ForceMode forceMode);
|
||||||
void Prism_RigidBodyComponent_AddTorque(uint64_t entityID, glm::vec3* torque, ForceMode forceMode);
|
void Prism_RigidBodyComponent_AddTorque(uint64_t entityID, glm::vec3* torque, ForceMode forceMode);
|
||||||
void Prism_RigidBodyComponent_GetLinearVelocity(uint64_t entityID, glm::vec3* outVelocity);
|
void Prism_RigidBodyComponent_GetLinearVelocity(uint64_t entityID, glm::vec3* outVelocity);
|
||||||
void Prism_RigidBodyComponent_SetLinearVelocity(uint64_t entityID, glm::vec3* velocity);
|
void Prism_RigidBodyComponent_SetLinearVelocity(uint64_t entityID, glm::vec3* velocity);
|
||||||
|
void Prism_RigidBodyComponent_Rotate(uint64_t entityID, glm::vec3* rotation);
|
||||||
|
|
||||||
// Renderer
|
// Renderer
|
||||||
// Texture2D
|
// Texture2D
|
||||||
@ -73,6 +81,9 @@ namespace Prism { namespace Script {
|
|||||||
int Prism_Mesh_GetMaterialCount(Ref<Mesh>* inMesh);
|
int Prism_Mesh_GetMaterialCount(Ref<Mesh>* inMesh);
|
||||||
|
|
||||||
void* Prism_MeshFactory_CreatePlane(float width, float height);
|
void* Prism_MeshFactory_CreatePlane(float width, float height);
|
||||||
|
|
||||||
|
void* Prism_MeshComponent_GetMesh(uint64_t entityID);
|
||||||
|
void Prism_MeshComponent_SetMesh(uint64_t entityID, const Ref<Mesh>* inMesh);
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user