From a2c53327357fb48c7d03b29f843c5f62913700ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= <49535803+damacaa@users.noreply.github.com> Date: Fri, 17 Apr 2026 15:40:52 +0200 Subject: [PATCH 1/4] New parameters on collision events allow user to get entities involved, sample scene added --- .../sample-scenes/assets/Organisms/man.weird | 26 ++- examples/sample-scenes/include/WalkScene.h | 148 ++++++++++++++++++ examples/sample-scenes/src/main.cpp | 22 +-- include/weird-engine/Scene.h | 18 +++ src/weird-engine/Scene.cpp | 18 ++- 5 files changed, 219 insertions(+), 13 deletions(-) create mode 100644 examples/sample-scenes/include/WalkScene.h diff --git a/examples/sample-scenes/assets/Organisms/man.weird b/examples/sample-scenes/assets/Organisms/man.weird index e7c653b8..f695e9e5 100644 --- a/examples/sample-scenes/assets/Organisms/man.weird +++ b/examples/sample-scenes/assets/Organisms/man.weird @@ -1,9 +1,9 @@ { "camera": { "position": [ - -3.5375001430511475, - 1.024999976158142, - 15.000022888183594 + -0.049999967217445374, + 0.6375002861022949, + 5.0 ], "rotation": [ 0.0, @@ -738,6 +738,18 @@ "B": 16, "distance": 4.242640495300293, "k": 0.0024806864093989134 + }, + { + "A": 1, + "B": 6, + "distance": 2.8284270763397217, + "k": 0.0024806864093989134 + }, + { + "A": 3, + "B": 4, + "distance": 2.8284270763397217, + "k": 0.0024806864093989134 } ], "fixedObjects": [], @@ -747,6 +759,14 @@ { "entityId": 40, "name": "head" + }, + { + "entityId": 36, + "name": "foot_left" + }, + { + "entityId": 39, + "name": "foot_right" } ], "version": 1 diff --git a/examples/sample-scenes/include/WalkScene.h b/examples/sample-scenes/include/WalkScene.h new file mode 100644 index 00000000..93a49ba5 --- /dev/null +++ b/examples/sample-scenes/include/WalkScene.h @@ -0,0 +1,148 @@ +#pragma once + +#include + +#include + +#include "globals.h" + +using namespace WeirdEngine; + +struct Foot : public Component +{ + Foot() {}; + + vec2 direction = vec2(1.0f, 0.0f); + vec2 initialPos = vec2(0.0f, 0.0f); + float forceMagnitude = 1.0f; + bool directionChanged = false; + float t = 0.0f; + bool onFloor = false; + bool stepStarted = false; +}; + +class WalkScene : public Scene +{ +public: + WalkScene(const PhysicsSettings& settings) + : Scene(settings) {}; + +private: + // Inherited via Scene + void onStart() override + { + m_debugInput = true; + m_debugFly = true; + + auto tags = loadWeirdFile(ASSETS_PATH "Organisms/man.weird"); + + Entity firstCreated = static_cast(m_ecs.getEntityCount()); + + Entity lastCreated = static_cast(m_ecs.getEntityCount()); + + for (Entity e = 0; e < (lastCreated - firstCreated); e++) + { + auto& t = m_ecs.getComponent(firstCreated + e); + t.position += vec3(-10.0f, 0.0f, 0.0f); + } + + Entity leftFootEntity = tags["foot_left"]; + m_ecs.addComponent(leftFootEntity); + + Entity rightFootEntity = tags["foot_right"]; + m_ecs.addComponent(rightFootEntity); + + float boundsVars[8]{0.0f, 0.0f, 3000.0f}; + Entity outside = addShape(DefaultShapes::CIRCLE, boundsVars, 17, CombinationType::Addition); + + float boundsVars2[8]{0.0f, 0.0f, 20.0f, 20.0f}; + Entity inside = addShape(DefaultShapes::BOX, boundsVars2, DisplaySettings::Black, CombinationType::Subtraction); + + m_ecs.getComponent(m_mainCamera).position = g_cameraPositon; + } + + void onUpdate(float delta) override + { + g_cameraPositon = m_ecs.getComponent(m_mainCamera).position; + + if (Input::GetKeyDown(Input::Q)) + { + setSceneComplete(); + } + } + + int m_currentFoot = 0; + void onPhysicsStep() override + { + auto componentArray = m_ecs.getComponentArray(); + auto rigidBodies = m_ecs.getComponentArray(); + + for (size_t i = 0; i < componentArray->getSize(); i++) + { + auto& foot = componentArray->getDataAtIdx(i); + auto& rb = rigidBodies->getDataFromEntity(foot.Owner); + + if(i != m_currentFoot) + { + if(foot.onFloor) + m_simulation2D.fix(rb.simulationId); + continue; + } + + + + // Start step + if (!foot.stepStarted) + { + if (foot.onFloor) + { + foot.initialPos = m_simulation2D.getPosition(rb.simulationId); + foot.stepStarted = true; + foot.t = 0.0f; + // m_simulation2D.setPosition(rb.simulationId, foot.initialPos + vec2(0.0f, 0.1f)); + } + } + else + { + // End step + if (foot.onFloor && foot.t > 0.5f) + { + foot.stepStarted = false; + m_currentFoot = (m_currentFoot + 1) % componentArray->getSize(); + } + else + { + vec2 offset = vec2(-std::sin(foot.t), 1.0f - std::abs(std::cos(2.0f * foot.t))); + offset.y *= 0.5f; + m_simulation2D.setPosition(rb.simulationId, foot.initialPos + offset); + foot.t += 4.0f * m_simulation2D.getDeltaTime(); + } + } + } + + } + + void onEntityCollision(WeirdEngine::EntityCollisionEvent& event) override + { + Entity entityA = event.entityA; + Entity entityB = event.entityB; + } + + void onEntityShapeCollision(WeirdEngine::EntityShapeCollisionEvent& event) override + { + Entity entity = event.entity; + if (m_ecs.hasComponent(entity)) + { + auto& foot = m_ecs.getComponent(entity); + if (event.raw.state == CollisionState::START) + { + foot.onFloor = true; + } + else if (event.raw.state == CollisionState::END) + { + + foot.onFloor = false; + } + } + } +}; diff --git a/examples/sample-scenes/src/main.cpp b/examples/sample-scenes/src/main.cpp index d7fd8780..2c9c8e62 100644 --- a/examples/sample-scenes/src/main.cpp +++ b/examples/sample-scenes/src/main.cpp @@ -10,6 +10,7 @@ #include "MouseCollisionScene.h" #include "RopeScene.h" #include "ShapesCombinations.h" +#include "WalkScene.h" #include "globals.h" #include "MoleculeEditor.h" @@ -21,15 +22,18 @@ WeirdEngine::vec3 g_cameraPositon = vec3(15.0f, 7.5f, 35.0f); int main(int argc, char* argv[]) { SceneManager& sceneManager = SceneManager::getInstance(); - sceneManager.registerScene("shapes"); - sceneManager.registerScene("rope"); - sceneManager.registerScene("cursor-collision"); - sceneManager.registerScene("image"); - sceneManager.registerScene("collision-handling"); - sceneManager.registerScene("destroy-test"); - sceneManager.registerScene("scene-editor", ASSETS_PATH "example.weird"); - sceneManager.registerScene("molecule-editor"); - sceneManager.registerScene("life"); + + // sceneManager.registerScene("shapes"); + // sceneManager.registerScene("rope"); + // sceneManager.registerScene("cursor-collision"); + // sceneManager.registerScene("image"); + // sceneManager.registerScene("collision-handling"); + // sceneManager.registerScene("destroy-test"); + // sceneManager.registerScene("scene-editor", ASSETS_PATH "example.weird"); + // sceneManager.registerScene("molecule-editor"); + // sceneManager.registerScene("life"); + sceneManager.registerScene("walk"); + DisplaySettings displaySettings{}; displaySettings.width = 800; diff --git a/include/weird-engine/Scene.h b/include/weird-engine/Scene.h index 9625927d..114db87e 100644 --- a/include/weird-engine/Scene.h +++ b/include/weird-engine/Scene.h @@ -21,6 +21,19 @@ namespace WeirdEngine { using namespace ECS; + struct EntityCollisionEvent + { + CollisionEvent& raw; + Entity entityA; + Entity entityB; + }; + + struct EntityShapeCollisionEvent + { + ShapeCollisionEvent& raw; + Entity entity; + }; + constexpr int SOUND_QUEUE_SIZE = 16; // Forward declaration – full definition in SceneSerializer.h @@ -99,7 +112,9 @@ namespace WeirdEngine virtual void onRender(WeirdRenderer::RenderTarget& renderTarget) {}; virtual void onPhysicsStep() {}; virtual void onCollision(WeirdEngine::CollisionEvent& event) {}; + virtual void onEntityCollision(WeirdEngine::EntityCollisionEvent& event) {}; virtual void onShapeCollision(WeirdEngine::ShapeCollisionEvent& event) {}; + virtual void onEntityShapeCollision(WeirdEngine::EntityShapeCollisionEvent& event) {}; virtual void onDestroy() {}; void setSceneComplete(std::string nextScene = "") @@ -143,6 +158,9 @@ namespace WeirdEngine // Return the entity that owns a tag, or MAX_ENTITIES if none. Entity getEntityByTag(const std::string& name) const; + // Resolve a physics SimulationID to the owning entity. + Entity getEntityForSimulationId(SimulationID simulationId); + SDFRenderSystem2DContext m_2DWorldRenderContext; SDFRenderSystem2DContext m_UIRenderContext; diff --git a/src/weird-engine/Scene.cpp b/src/weird-engine/Scene.cpp index 5a86f215..55c991ae 100644 --- a/src/weird-engine/Scene.cpp +++ b/src/weird-engine/Scene.cpp @@ -158,9 +158,13 @@ namespace WeirdEngine void Scene::handleCollision(CollisionEvent& event, void* userData) { - // Unsafe cast! Prone to error. Scene* self = static_cast(userData); self->onCollision(event); + + EntityCollisionEvent entityEvent{event, + self->getEntityForSimulationId(event.bodyA), + self->getEntityForSimulationId(event.bodyB)}; + self->onEntityCollision(entityEvent); } void Scene::handleShapeCollision(ShapeCollisionEvent& event, void* userData) @@ -168,6 +172,9 @@ namespace WeirdEngine Scene* self = static_cast(userData); self->onShapeCollision(event); + EntityShapeCollisionEvent entityEvent{event, self->getEntityForSimulationId(event.body)}; + self->onEntityShapeCollision(entityEvent); + const float m_soundFalloff = 0.1f; bool spatialAudio = false; auto camPosition = self->getCamera().position; // Mutex? @@ -336,6 +343,15 @@ namespace WeirdEngine return it->second; } + Entity Scene::getEntityForSimulationId(SimulationID simulationId) + { + auto rigidBodies = m_ecs.getComponentArray(); + if (simulationId >= static_cast(rigidBodies->getSize())) + return INVALID_ENTITY; + + return rigidBodies->getEntityAtIdx(static_cast(simulationId)); + } + void Scene::saveScene(const std::string& filename) { SceneSerializer::save(*this, filename); From c696fdc0c281b5d6ae52adb3665cea97ceb8f3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= <49535803+damacaa@users.noreply.github.com> Date: Sat, 18 Apr 2026 00:29:11 +0200 Subject: [PATCH 2/4] Finished walk scene --- .../sample-scenes/assets/Organisms/man.weird | 228 ++++++++++++------ examples/sample-scenes/include/WalkScene.h | 57 ++++- examples/sample-scenes/src/main.cpp | 19 +- 3 files changed, 206 insertions(+), 98 deletions(-) diff --git a/examples/sample-scenes/assets/Organisms/man.weird b/examples/sample-scenes/assets/Organisms/man.weird index f695e9e5..d1d205f7 100644 --- a/examples/sample-scenes/assets/Organisms/man.weird +++ b/examples/sample-scenes/assets/Organisms/man.weird @@ -1,9 +1,9 @@ { "camera": { "position": [ - -0.049999967217445374, - 0.6375002861022949, - 5.0 + 0.049999963492155075, + -1.7374986410140991, + 5.00000524520874 ], "rotation": [ 0.0, @@ -22,7 +22,7 @@ "isStatic": false, "materialId": 15 }, - "id": 33, + "id": 35, "rigidBody2D": { "physicsPosition": [ 0.0, @@ -53,7 +53,7 @@ "isStatic": false, "materialId": 15 }, - "id": 34, + "id": 36, "rigidBody2D": { "physicsPosition": [ -1.0, @@ -84,7 +84,7 @@ "isStatic": false, "materialId": 15 }, - "id": 35, + "id": 37, "rigidBody2D": { "physicsPosition": [ -1.0, @@ -115,7 +115,7 @@ "isStatic": false, "materialId": 15 }, - "id": 36, + "id": 38, "rigidBody2D": { "physicsPosition": [ -1.0, @@ -146,7 +146,7 @@ "isStatic": false, "materialId": 15 }, - "id": 37, + "id": 39, "rigidBody2D": { "physicsPosition": [ 1.0, @@ -177,7 +177,7 @@ "isStatic": false, "materialId": 15 }, - "id": 38, + "id": 40, "rigidBody2D": { "physicsPosition": [ 1.0, @@ -208,7 +208,7 @@ "isStatic": false, "materialId": 15 }, - "id": 39, + "id": 41, "rigidBody2D": { "physicsPosition": [ 1.0, @@ -239,7 +239,7 @@ "isStatic": false, "materialId": 11 }, - "id": 40, + "id": 42, "rigidBody2D": { "physicsPosition": [ 0.0, @@ -270,7 +270,7 @@ "isStatic": false, "materialId": 8 }, - "id": 41, + "id": 43, "rigidBody2D": { "physicsPosition": [ -1.0, @@ -301,7 +301,7 @@ "isStatic": false, "materialId": 8 }, - "id": 42, + "id": 44, "rigidBody2D": { "physicsPosition": [ 1.0, @@ -332,7 +332,7 @@ "isStatic": false, "materialId": 8 }, - "id": 43, + "id": 45, "rigidBody2D": { "physicsPosition": [ 0.0, @@ -363,7 +363,7 @@ "isStatic": false, "materialId": 8 }, - "id": 44, + "id": 46, "rigidBody2D": { "physicsPosition": [ 2.0, @@ -394,7 +394,7 @@ "isStatic": false, "materialId": 8 }, - "id": 45, + "id": 47, "rigidBody2D": { "physicsPosition": [ 3.0, @@ -425,7 +425,7 @@ "isStatic": false, "materialId": 11 }, - "id": 46, + "id": 48, "rigidBody2D": { "physicsPosition": [ 4.0, @@ -456,7 +456,7 @@ "isStatic": false, "materialId": 8 }, - "id": 47, + "id": 49, "rigidBody2D": { "physicsPosition": [ -2.0, @@ -487,7 +487,7 @@ "isStatic": false, "materialId": 8 }, - "id": 48, + "id": 50, "rigidBody2D": { "physicsPosition": [ -3.0, @@ -518,7 +518,7 @@ "isStatic": false, "materialId": 11 }, - "id": 49, + "id": 51, "rigidBody2D": { "physicsPosition": [ -4.0, @@ -548,87 +548,75 @@ "physics": { "distanceConstraints": [ { - "A": 1, - "B": 0, + "A": 3, + "B": 2, "distance": 1.0, "k": 1.0 }, { - "A": 0, - "B": 4, + "A": 2, + "B": 1, "distance": 1.0, "k": 1.0 }, { - "A": 4, - "B": 9, + "A": 1, + "B": 0, "distance": 1.0, "k": 1.0 }, { - "A": 9, - "B": 10, + "A": 0, + "B": 4, "distance": 1.0, "k": 1.0 }, { - "A": 10, - "B": 7, + "A": 4, + "B": 5, "distance": 1.0, "k": 1.0 }, { - "A": 10, - "B": 8, + "A": 5, + "B": 6, "distance": 1.0, "k": 1.0 }, { - "A": 8, - "B": 1, + "A": 4, + "B": 9, "distance": 1.0, "k": 1.0 }, { - "A": 10, - "B": 0, + "A": 0, + "B": 10, "distance": 1.0, "k": 1.0 }, { "A": 1, - "B": 10, - "distance": 1.4142135381698608, + "B": 8, + "distance": 1.0, "k": 1.0 }, { "A": 8, - "B": 0, - "distance": 1.4142135381698608, + "B": 10, + "distance": 1.0, "k": 1.0 }, { - "A": 0, + "A": 10, "B": 9, - "distance": 1.4142135381698608, + "distance": 1.0, "k": 1.0 }, { "A": 10, - "B": 4, - "distance": 1.4142135381698608, - "k": 1.0 - }, - { - "A": 7, - "B": 8, - "distance": 1.4142135381698608, - "k": 1.0 - }, - { - "A": 7, - "B": 9, - "distance": 1.4142135381698608, + "B": 7, + "distance": 1.0, "k": 1.0 }, { @@ -669,26 +657,26 @@ }, { "A": 1, - "B": 2, - "distance": 1.0, + "B": 10, + "distance": 1.4142135381698608, "k": 1.0 }, { - "A": 2, - "B": 3, - "distance": 1.0, + "A": 0, + "B": 8, + "distance": 1.4142135381698608, "k": 1.0 }, { - "A": 4, - "B": 5, - "distance": 1.0, + "A": 0, + "B": 9, + "distance": 1.4142135381698608, "k": 1.0 }, { - "A": 5, - "B": 6, - "distance": 1.0, + "A": 10, + "B": 4, + "distance": 1.4142135381698608, "k": 1.0 }, { @@ -705,8 +693,8 @@ }, { "A": 3, - "B": 14, - "distance": 3.1622776985168457, + "B": 1, + "distance": 2.0, "k": 0.0024806864093989134 }, { @@ -716,15 +704,69 @@ "k": 0.0024806864093989134 }, { - "A": 0, - "B": 6, + "A": 6, + "B": 0, "distance": 2.2360680103302, "k": 0.0024806864093989134 }, { "A": 6, - "B": 13, - "distance": 4.242640495300293, + "B": 4, + "distance": 2.0, + "k": 0.0024806864093989134 + }, + { + "A": 2, + "B": 0, + "distance": 1.4142135381698608, + "k": 0.0024806864093989134 + }, + { + "A": 0, + "B": 5, + "distance": 1.4142135381698608, + "k": 0.0024806864093989134 + }, + { + "A": 1, + "B": 14, + "distance": 1.4142135381698608, + "k": 0.0024806864093989134 + }, + { + "A": 4, + "B": 11, + "distance": 1.4142135381698608, + "k": 0.0024806864093989134 + }, + { + "A": 8, + "B": 7, + "distance": 1.4142135381698608, + "k": 0.0024806864093989134 + }, + { + "A": 7, + "B": 9, + "distance": 1.4142135381698608, + "k": 0.0024806864093989134 + }, + { + "A": 14, + "B": 2, + "distance": 2.2360680103302, + "k": 0.0024806864093989134 + }, + { + "A": 14, + "B": 3, + "distance": 3.1622776985168457, + "k": 0.0024806864093989134 + }, + { + "A": 5, + "B": 11, + "distance": 2.2360680103302, "k": 0.0024806864093989134 }, { @@ -733,10 +775,40 @@ "distance": 3.1622776985168457, "k": 0.0024806864093989134 }, + { + "A": 5, + "B": 9, + "distance": 2.0, + "k": 0.0024806864093989134 + }, + { + "A": 6, + "B": 9, + "distance": 3.0, + "k": 0.0024806864093989134 + }, + { + "A": 2, + "B": 8, + "distance": 2.0, + "k": 0.0024806864093989134 + }, { "A": 3, - "B": 16, - "distance": 4.242640495300293, + "B": 8, + "distance": 3.0, + "k": 0.0024806864093989134 + }, + { + "A": 16, + "B": 1, + "distance": 3.1622776985168457, + "k": 0.0024806864093989134 + }, + { + "A": 4, + "B": 13, + "distance": 3.1622776985168457, "k": 0.0024806864093989134 }, { @@ -757,15 +829,15 @@ }, "tags": [ { - "entityId": 40, + "entityId": 42, "name": "head" }, { - "entityId": 36, + "entityId": 38, "name": "foot_left" }, { - "entityId": 39, + "entityId": 41, "name": "foot_right" } ], diff --git a/examples/sample-scenes/include/WalkScene.h b/examples/sample-scenes/include/WalkScene.h index 93a49ba5..29589495 100644 --- a/examples/sample-scenes/include/WalkScene.h +++ b/examples/sample-scenes/include/WalkScene.h @@ -28,6 +28,9 @@ class WalkScene : public Scene : Scene(settings) {}; private: + + Entity m_head; + // Inherited via Scene void onStart() override { @@ -52,13 +55,15 @@ class WalkScene : public Scene Entity rightFootEntity = tags["foot_right"]; m_ecs.addComponent(rightFootEntity); - float boundsVars[8]{0.0f, 0.0f, 3000.0f}; - Entity outside = addShape(DefaultShapes::CIRCLE, boundsVars, 17, CombinationType::Addition); + m_head = tags["head"]; - float boundsVars2[8]{0.0f, 0.0f, 20.0f, 20.0f}; - Entity inside = addShape(DefaultShapes::BOX, boundsVars2, DisplaySettings::Black, CombinationType::Subtraction); + + float boundsVars2[8]{0.0f, -24.0f, 200.0f, 20.0f}; + Entity inside = addShape(DefaultShapes::BOX, boundsVars2, DisplaySettings::LightGray, CombinationType::Addition); m_ecs.getComponent(m_mainCamera).position = g_cameraPositon; + + m_simulation2D.setGravity(-10.0f); } void onUpdate(float delta) override @@ -72,6 +77,7 @@ class WalkScene : public Scene } int m_currentFoot = 0; + bool m_feetTouching = false; void onPhysicsStep() override { auto componentArray = m_ecs.getComponentArray(); @@ -79,7 +85,7 @@ class WalkScene : public Scene for (size_t i = 0; i < componentArray->getSize(); i++) { - auto& foot = componentArray->getDataAtIdx(i); + auto& foot = componentArray->getDataAtIdx(i); auto& rb = rigidBodies->getDataFromEntity(foot.Owner); if(i != m_currentFoot) @@ -89,7 +95,10 @@ class WalkScene : public Scene continue; } + auto& headRB = m_ecs.getComponent(m_head); + m_simulation2D.addForce(headRB.simulationId, vec2(0.0f, 1.0f)); + m_simulation2D.unFix(rb.simulationId); // Start step if (!foot.stepStarted) @@ -100,32 +109,60 @@ class WalkScene : public Scene foot.stepStarted = true; foot.t = 0.0f; // m_simulation2D.setPosition(rb.simulationId, foot.initialPos + vec2(0.0f, 0.1f)); + m_simulation2D.unFix(rb.simulationId); } } else { // End step - if (foot.onFloor && foot.t > 0.5f) + if (foot.onFloor && foot.t > 0.1f) { foot.stepStarted = false; m_currentFoot = (m_currentFoot + 1) % componentArray->getSize(); + // std::cout << "Switching foot: " << m_currentFoot << std::endl; } else { - vec2 offset = vec2(-std::sin(foot.t), 1.0f - std::abs(std::cos(2.0f * foot.t))); - offset.y *= 0.5f; - m_simulation2D.setPosition(rb.simulationId, foot.initialPos + offset); - foot.t += 4.0f * m_simulation2D.getDeltaTime(); + vec2 f; + + if (foot.t < 0.1f) + { + f = (foot.direction + vec2(0.0f, 1.0f)) * foot.forceMagnitude; + } + else if (foot.t < 0.25f) + { + f = (foot.direction + vec2(0.0f, 0.0f)) * foot.forceMagnitude; + } + else + { + f = (foot.direction + vec2(0.0f, -10.0f * foot.t)) * foot.forceMagnitude * foot.t; + } + + if(m_feetTouching) + f.x = 0.0f; + + m_simulation2D.addForce(rb.simulationId, f); + + // vec2 offset = vec2(-std::sin(foot.t), 1.0f - std::abs(std::cos(2.0f * foot.t))); + // offset.y *= 0.5f; + // m_simulation2D.setPosition(rb.simulationId, foot.initialPos + offset); + foot.t += 0.5f * m_simulation2D.getDeltaTime(); } } } + m_feetTouching = false; } void onEntityCollision(WeirdEngine::EntityCollisionEvent& event) override { Entity entityA = event.entityA; Entity entityB = event.entityB; + + if (m_ecs.hasComponent(entityA) && m_ecs.hasComponent(entityB)) + { + m_feetTouching = true; + } } void onEntityShapeCollision(WeirdEngine::EntityShapeCollisionEvent& event) override diff --git a/examples/sample-scenes/src/main.cpp b/examples/sample-scenes/src/main.cpp index 2c9c8e62..3938559e 100644 --- a/examples/sample-scenes/src/main.cpp +++ b/examples/sample-scenes/src/main.cpp @@ -23,18 +23,17 @@ int main(int argc, char* argv[]) { SceneManager& sceneManager = SceneManager::getInstance(); - // sceneManager.registerScene("shapes"); - // sceneManager.registerScene("rope"); - // sceneManager.registerScene("cursor-collision"); - // sceneManager.registerScene("image"); - // sceneManager.registerScene("collision-handling"); - // sceneManager.registerScene("destroy-test"); - // sceneManager.registerScene("scene-editor", ASSETS_PATH "example.weird"); - // sceneManager.registerScene("molecule-editor"); - // sceneManager.registerScene("life"); + sceneManager.registerScene("shapes"); + sceneManager.registerScene("rope"); + sceneManager.registerScene("cursor-collision"); + sceneManager.registerScene("image"); + sceneManager.registerScene("collision-handling"); + sceneManager.registerScene("destroy-test"); + sceneManager.registerScene("scene-editor", ASSETS_PATH "example.weird"); + sceneManager.registerScene("molecule-editor"); + sceneManager.registerScene("life"); sceneManager.registerScene("walk"); - DisplaySettings displaySettings{}; displaySettings.width = 800; displaySettings.height = 800; From a6771c4ff708476131e701c0e3b903e8b82252e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= <49535803+damacaa@users.noreply.github.com> Date: Sat, 18 Apr 2026 00:29:51 +0200 Subject: [PATCH 3/4] Added the ability to remove distance constraints --- .../sample-scenes/include/MoleculeEditor.h | 52 ++++++++++++++++--- include/weird-physics/Simulation2D.h | 1 + src/weird-physics/Simulation2D.cpp | 23 ++++++++ 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/examples/sample-scenes/include/MoleculeEditor.h b/examples/sample-scenes/include/MoleculeEditor.h index a81b64ec..fc25c762 100644 --- a/examples/sample-scenes/include/MoleculeEditor.h +++ b/examples/sample-scenes/include/MoleculeEditor.h @@ -38,6 +38,7 @@ class MoleculeEditor : public Scene Drag, Spring, Distance, + Remove, TagEditor, Material }; @@ -86,7 +87,7 @@ class MoleculeEditor : public Scene int m_selectedMaterial = 1; ToolMode m_toolMode = ToolMode::Drag; - std::array m_toolToggles{}; + std::array m_toolToggles{}; Entity m_gravityToggleEntity = static_cast(-1); Entity m_gridToggleEntity = static_cast(-1); @@ -353,8 +354,8 @@ class MoleculeEditor : public Scene void buildToolbar() { - const char* labels[] = {"drag", "spring", "distance", "tag", "material"}; - for (int i = 0; i < 5; i++) + const char* labels[] = {"drag", "spring", "distance", "remove", "tag", "material"}; + for (int i = 0; i < 6; i++) { float y = (Display::height - TOOL_Y_START) - (i * TOOL_SPACING); float p[8]{TOOL_X, y, TOOL_BTN_HALF, TOOL_BTN_HALF}; @@ -401,7 +402,7 @@ class MoleculeEditor : public Scene void syncToolbar() { int activated = -1; - for (int i = 0; i < 5; i++) + for (int i = 0; i < 6; i++) { auto& t = m_ecs.getComponent(m_toolToggles[i]); if (t.active && t.state == ButtonState::Down) @@ -413,7 +414,7 @@ class MoleculeEditor : public Scene if (activated >= 0) { m_toolMode = static_cast(activated); - for (int i = 0; i < 5; i++) + for (int i = 0; i < 6; i++) { if (i != activated) m_ecs.getComponent(m_toolToggles[i]).active = false; @@ -535,7 +536,7 @@ class MoleculeEditor : public Scene if (rightDown && !m_rightWasDown) { - if (m_toolMode == ToolMode::Spring || m_toolMode == ToolMode::Distance) + if (m_toolMode == ToolMode::Spring || m_toolMode == ToolMode::Distance || m_toolMode == ToolMode::Remove) onConstraintStart(); else if (m_toolMode == ToolMode::TagEditor) onTagEditorRightClick(); @@ -653,8 +654,15 @@ class MoleculeEditor : public Scene Entity hit = pickBallAtMouse(); if (hit != static_cast(-1) && hit != m_constraintStartBall) { - LinkType type = (m_toolMode == ToolMode::Distance) ? LinkType::Distance : LinkType::Spring; - addConstraintLink(m_constraintStartBall, hit, type); + if (m_toolMode == ToolMode::Remove) + { + removeConstraintLink(m_constraintStartBall, hit); + } + else + { + LinkType type = (m_toolMode == ToolMode::Distance) ? LinkType::Distance : LinkType::Spring; + addConstraintLink(m_constraintStartBall, hit, type); + } } m_constraintStartBall = static_cast(-1); @@ -738,6 +746,34 @@ class MoleculeEditor : public Scene m_links.push_back({a, b, idA, idB, restDistance, line, type}); } + void removeConstraintLink(Entity a, Entity b) + { + for (size_t i = 0; i < m_links.size();) + { + DistanceLink& link = m_links[i]; + bool sameDir = (link.a == a && link.b == b); + bool reverseDir = (link.a == b && link.b == a); + if (!sameDir && !reverseDir) + { + ++i; + continue; + } + + if (m_draggedLink == &link) + m_draggedLink = nullptr; + + m_ecs.destroyEntity(link.lineEntity); + m_links.erase(m_links.begin() + i); + } + + int idA = getSimulationId(a); + int idB = getSimulationId(b); + if (idA < 0 || idB < 0) + return; + + m_simulation2D.removeDistanceConstraint(static_cast(idA), static_cast(idB)); + } + void handleConstraintLineClicks() { // Detect click-down via ShapeButton state. diff --git a/include/weird-physics/Simulation2D.h b/include/weird-physics/Simulation2D.h index c8786665..b4dd2263 100644 --- a/include/weird-physics/Simulation2D.h +++ b/include/weird-physics/Simulation2D.h @@ -97,6 +97,7 @@ namespace WeirdEngine void addPositionConstraint(SimulationID a, SimulationID b, float distance = 1.0f); void addGravitationalConstraint(SimulationID a, SimulationID b, float gravity); bool setDistanceConstraintDistance(SimulationID a, SimulationID b, float distance); + bool removeDistanceConstraint(SimulationID a, SimulationID b); void fix(SimulationID id); void unFix(SimulationID id); diff --git a/src/weird-physics/Simulation2D.cpp b/src/weird-physics/Simulation2D.cpp index 24d80ff9..b8c7876e 100644 --- a/src/weird-physics/Simulation2D.cpp +++ b/src/weird-physics/Simulation2D.cpp @@ -956,6 +956,29 @@ namespace WeirdEngine return false; } + bool Simulation2D::removeDistanceConstraint(SimulationID a, SimulationID b) + { + if (a == b) + return false; + + std::lock_guard lock(m_objectMutex); + + size_t previousSize = m_distanceConstraints.size(); + m_distanceConstraints.erase( + std::remove_if(m_distanceConstraints.begin(), m_distanceConstraints.end(), + [a, b](const DistanceConstraint& constraint) + { + bool sameDirection = + (constraint.A == static_cast(a) && constraint.B == static_cast(b)); + bool reverseDirection = + (constraint.A == static_cast(b) && constraint.B == static_cast(a)); + return sameDirection || reverseDirection; + }), + m_distanceConstraints.end()); + + return previousSize != m_distanceConstraints.size(); + } + void Simulation2D::fix(SimulationID id) { std::lock_guard lock(m_fixMutex); From 97b302cc708dcf3be4fdb78d3339b046b565e4fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= <49535803+damacaa@users.noreply.github.com> Date: Sat, 18 Apr 2026 01:12:58 +0200 Subject: [PATCH 4/4] Removed all shape collision event --- examples/sample-scenes/include/DestroyScene.h | 4 ++-- examples/sample-scenes/include/MoleculeEditor.h | 4 ++-- include/weird-engine/Scene.h | 1 - src/weird-engine/Scene.cpp | 2 -- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/examples/sample-scenes/include/DestroyScene.h b/examples/sample-scenes/include/DestroyScene.h index a669833d..3673db1a 100644 --- a/examples/sample-scenes/include/DestroyScene.h +++ b/examples/sample-scenes/include/DestroyScene.h @@ -87,9 +87,9 @@ class DestroyScene : public Scene m_testShape = addShape(DefaultShapes::BOX, variables, 2, CombinationType::Addition); } - void onShapeCollision(WeirdEngine::ShapeCollisionEvent& event) override + void onEntityShapeCollision(WeirdEngine::EntityShapeCollisionEvent& event) override { - event.friction *= 100.0f; + event.raw.friction *= 100.0f; m_collisionDetected = true; } diff --git a/examples/sample-scenes/include/MoleculeEditor.h b/examples/sample-scenes/include/MoleculeEditor.h index fc25c762..7ac3ad95 100644 --- a/examples/sample-scenes/include/MoleculeEditor.h +++ b/examples/sample-scenes/include/MoleculeEditor.h @@ -1100,8 +1100,8 @@ class MoleculeEditor : public Scene << (allConstraints.size() - prevConstraintCount) << " links from " << path << "\n"; } - void onShapeCollision(WeirdEngine::ShapeCollisionEvent& event) override + void onEntityShapeCollision(WeirdEngine::EntityShapeCollisionEvent& event) override { - event.friction *= 100.0f; + event.raw.friction *= 100.0f; } }; diff --git a/include/weird-engine/Scene.h b/include/weird-engine/Scene.h index 114db87e..ac6e4983 100644 --- a/include/weird-engine/Scene.h +++ b/include/weird-engine/Scene.h @@ -113,7 +113,6 @@ namespace WeirdEngine virtual void onPhysicsStep() {}; virtual void onCollision(WeirdEngine::CollisionEvent& event) {}; virtual void onEntityCollision(WeirdEngine::EntityCollisionEvent& event) {}; - virtual void onShapeCollision(WeirdEngine::ShapeCollisionEvent& event) {}; virtual void onEntityShapeCollision(WeirdEngine::EntityShapeCollisionEvent& event) {}; virtual void onDestroy() {}; diff --git a/src/weird-engine/Scene.cpp b/src/weird-engine/Scene.cpp index 55c991ae..22846412 100644 --- a/src/weird-engine/Scene.cpp +++ b/src/weird-engine/Scene.cpp @@ -170,8 +170,6 @@ namespace WeirdEngine void Scene::handleShapeCollision(ShapeCollisionEvent& event, void* userData) { Scene* self = static_cast(userData); - self->onShapeCollision(event); - EntityShapeCollisionEvent entityEvent{event, self->getEntityForSimulationId(event.body)}; self->onEntityShapeCollision(entityEvent);