added height field physics shape type
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -412,6 +412,7 @@ namespace wi::scene
|
||||
CONVEX_HULL,
|
||||
TRIANGLE_MESH,
|
||||
CYLINDER,
|
||||
HEIGHTFIELD,
|
||||
ENUM_FORCE_UINT32 = 0xFFFFFFFF
|
||||
};
|
||||
CollisionShape shape;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user