physics: capsule/cylinder/compound collider shapes
- ColliderType + Capsule/Cylinder/Compound; CompoundChild list (Box/ Sphere/Capsule, local pos/quat, non-recursive) - CreateBody: CapsuleShape/CylinderShape (ctor param orders differ) + StaticCompoundShape; empty/failed compound falls back to Box - BodyRecord caches radius/halfHeight/compound; SyncScene rebuilds on change (per-collider param extraction) - Inspector: combo entries + shape params + compound child list editor - Serialization: new fields with as<T> fallback, compound seq round-trip
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Engine {
|
||||
class Model;
|
||||
@@ -187,15 +188,38 @@ namespace Engine::ECS {
|
||||
// 语义)——Static → Jolt MeshShape(精确三角网格,不可移动);
|
||||
// Dynamic/Kinematic → ConvexHullShape(凸包近似,MeshShape 太贵
|
||||
// 不能动)。数据源 Mesh 的 CPU 位置副本,无 MeshRenderer 回退 Box
|
||||
enum class ColliderType : u8 { Box = 0, Sphere = 1, Mesh = 2 };
|
||||
enum class ColliderType : u8 {
|
||||
Box = 0, Sphere = 1, Mesh = 2,
|
||||
Capsule = 3, Cylinder = 4, Compound = 5
|
||||
};
|
||||
|
||||
// Compound 子形状:局部 pos/rot 相对刚体原点,不递归嵌套
|
||||
//(child 不能再是 Compound)。尺寸语义同顶层(× Transform 缩放烘焙)
|
||||
struct CompoundChild {
|
||||
enum class Shape : u8 { Box = 0, Sphere = 1, Capsule = 2 };
|
||||
Shape shape = Shape::Box;
|
||||
glm::vec3 boxHalfExtents{0.25f, 0.25f, 0.25f};
|
||||
f32 radius = 0.25f; // Sphere 半径 / Capsule 半径
|
||||
f32 capsuleHalfHeight = 0.25f; // 仅 Capsule:圆柱段半高
|
||||
glm::vec3 position{0.0f};
|
||||
glm::quat rotation{1.0f, 0.0f, 0.0f, 0.0f};
|
||||
bool operator==(const CompoundChild&) const = default;
|
||||
};
|
||||
|
||||
BodyType type = BodyType::Dynamic; // Unity 语义:加 Rigidbody 即受物理驱动
|
||||
ColliderType collider = ColliderType::Box;
|
||||
|
||||
// 碰撞体尺寸(× Transform 缩放,Unity BoxCollider.size 语义)——
|
||||
// 程序化模型顶点烘焙尺寸,不能从 scale 反推
|
||||
// 程序化模型顶点烘焙尺寸,不能从 scale 反推。
|
||||
// Capsule/Cylinder 的"半高"指圆柱段半高(不含半球端盖),总高 =
|
||||
// 2*(halfHeight + radius);Jolt 两 ctor 参数序相反见 PhysicsWorld
|
||||
glm::vec3 boxHalfExtents{0.5f, 0.5f, 0.5f};
|
||||
f32 sphereRadius = 0.5f;
|
||||
f32 capsuleRadius = 0.5f; // Unity CapsuleCollider 默认值同构
|
||||
f32 capsuleHalfHeight = 0.5f;
|
||||
f32 cylinderRadius = 0.5f;
|
||||
f32 cylinderHalfHeight = 0.5f;
|
||||
std::vector<CompoundChild> compound; // 仅 ColliderType::Compound
|
||||
|
||||
// 动态体参数
|
||||
f32 mass = 1.0f;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <Engine/Physics/PhysicsDebugDraw.h>
|
||||
#include <Engine/Physics/PhysicsEvents.h>
|
||||
#include <Engine/Physics/PhysicsRay.h>
|
||||
#include <Engine/ECS/Components.h> // BodyRecord 快照存 CompoundChild(完整类型)
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
#include <Jolt/Physics/PhysicsSystem.h>
|
||||
@@ -95,7 +96,9 @@ namespace Engine {
|
||||
u8 type = 0; // RigidBodyComponent::BodyType
|
||||
u8 collider = 0; // RigidBodyComponent::ColliderType
|
||||
glm::vec3 colliderSize{0.0f}; // 碰撞体尺寸缓存(box 半尺寸)
|
||||
f32 radius = 0.0f; // 球半径缓存
|
||||
f32 radius = 0.0f; // 球/Capsule/Cylinder 半径(collider 决定语义)
|
||||
f32 halfHeight = 0.0f; // Capsule/Cylinder 圆柱段半高
|
||||
std::vector<ECS::RigidBodyComponent::CompoundChild> compound; // 子形状快照
|
||||
f32 mass = 0.0f;
|
||||
bool isSensor = false; // 传感器标记(变更 → 重建 body)
|
||||
glm::vec3 lastPos{0.0f}; // 静态/运动体编辑器拖动检测
|
||||
@@ -116,6 +119,10 @@ namespace Engine {
|
||||
JPH::RefConst<JPH::Shape> BuildMeshShape(u32 entityBits,
|
||||
ECS::RigidBodyComponent& rb,
|
||||
ECS::TransformComponent& tr);
|
||||
// Compound 碰撞体:子形状列表 → Jolt StaticCompoundShape。
|
||||
// 空 children 或构建失败返回 null(回退 Box)
|
||||
JPH::RefConst<JPH::Shape> BuildCompoundShape(ECS::RigidBodyComponent& rb,
|
||||
ECS::TransformComponent& tr);
|
||||
void RemoveBody(u32 entityBits);
|
||||
const BodyRecord* FindRecord(u32 entityBits) const; // 刚体驱动寻址
|
||||
void QueueEvent(CollisionEvent&& ev); // 回调线程 append(多线程并发,加锁)
|
||||
|
||||
Reference in New Issue
Block a user