added height field physics shape type

This commit is contained in:
Turánszki János
2025-03-31 09:55:40 +02:00
parent 76549fa85f
commit bc128fe6eb
7 changed files with 54 additions and 5 deletions
+1
View File
@@ -32,6 +32,7 @@ void RigidBodyWindow::Create(EditorComponent* _editor)
collisionShapeComboBox.AddItem("Cylinder", RigidBodyPhysicsComponent::CollisionShape::CYLINDER);
collisionShapeComboBox.AddItem("Convex Hull", RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL);
collisionShapeComboBox.AddItem("Triangle Mesh", RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH);
collisionShapeComboBox.AddItem("Height Field", RigidBodyPhysicsComponent::CollisionShape::HEIGHTFIELD);
collisionShapeComboBox.OnSelect([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
+37
View File
@@ -1542,6 +1542,43 @@ namespace wi::physics
return;
}
break;
case RigidBodyPhysicsComponent::CollisionShape::HEIGHTFIELD:
if (mesh != nullptr)
{
wi::vector<float> heights;
heights.reserve(mesh->vertex_positions.size());
wi::primitive::AABB aabb;
for (XMFLOAT3 pos : mesh->vertex_positions)
{
pos.x *= scale_local.x;
pos.y *= scale_local.y;
pos.z *= scale_local.z;
heights.push_back(pos.y);
aabb.AddPoint(pos);
}
XMFLOAT3 min = aabb.getMin();
min.y = 0;
uint32_t dim = (uint32_t)std::sqrt((double)heights.size());
wilog_assert(dim >= 2, "Height field shape dimension must be at least 2!");
Vec3 scale = cast(aabb.getHalfWidth()) * 2 / (float)(dim - 1);
scale.SetY(1);
HeightFieldShapeSettings settings(heights.data(), cast(min), scale, dim);
settings.SetEmbedded();
shape_result = settings.Create();
}
else
{
wi::backlog::post("CreateRigidBodyShape failed: height field physics requested, but no MeshComponent provided!", wi::backlog::LogLevel::Error);
return;
}
break;
}
if (!shape_result.IsValid())
+5
View File
@@ -205,6 +205,11 @@ namespace wi::primitive
{
return AABB(wi::math::Min(a.getMin(), b.getMin()), wi::math::Max(a.getMax(), b.getMax()));
}
void AABB::AddPoint(const XMFLOAT3& pos)
{
_min = wi::math::Min(_min, pos);
_max = wi::math::Max(_max, pos);
}
void AABB::Serialize(wi::Archive& archive, wi::ecs::EntitySerializer& seri)
{
if (archive.IsReadMode())
+1
View File
@@ -50,6 +50,7 @@ namespace wi::primitive
bool intersects(const BoundingFrustum& frustum) const;
AABB operator* (float a);
static AABB Merge(const AABB& a, const AABB& b);
void AddPoint(const XMFLOAT3& pos);
// projects the AABB to the screen, returns a 2D rectangle in UV-space as Vector(topleftX, topleftY, bottomrightX, bottomrightY), each value is in range [0, 1]
XMFLOAT4 ProjectToScreen(const XMMATRIX& ViewProjection) const;
+1
View File
@@ -412,6 +412,7 @@ namespace wi::scene
CONVEX_HULL,
TRIANGLE_MESH,
CYLINDER,
HEIGHTFIELD,
ENUM_FORCE_UINT32 = 0xFFFFFFFF
};
CollisionShape shape;
+8 -4
View File
@@ -808,10 +808,14 @@ namespace wi::terrain
if (rigidbody == nullptr)
{
RigidBodyPhysicsComponent& newrigidbody = scene->rigidbodies.Create(chunk_data.entity);
newrigidbody.shape = RigidBodyPhysicsComponent::TRIANGLE_MESH;
newrigidbody.shape = RigidBodyPhysicsComponent::HEIGHTFIELD;
newrigidbody.mass = 0; // terrain chunks are static
newrigidbody.friction = 0.8f;
newrigidbody.mesh_lod = 2;
//newrigidbody.mesh_lod = 2;
}
else
{
rigidbody->shape = RigidBodyPhysicsComponent::HEIGHTFIELD;
}
}
else if(rigidbody != nullptr)
@@ -1037,10 +1041,10 @@ namespace wi::terrain
// Precompute the physics shape here on separate thread, because computing shape for triangle mesh would be slow on main thread:
// Note that this is mesh.precomputed_rigidbody_physics_shape and not a component in scene.rigidbodies, so this only contains the shape, not the simulated rigid bodies
RigidBodyPhysicsComponent& newrigidbody = mesh.precomputed_rigidbody_physics_shape;
newrigidbody.shape = RigidBodyPhysicsComponent::TRIANGLE_MESH;
newrigidbody.shape = RigidBodyPhysicsComponent::HEIGHTFIELD;
newrigidbody.mass = 0; // terrain chunks are static
newrigidbody.friction = 0.8f;
newrigidbody.mesh_lod = 2;
//newrigidbody.mesh_lod = 2;
wi::physics::CreateRigidBodyShape(newrigidbody, transform.scale_local, &mesh);
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 726;
const int revision = 727;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);