Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 168 additions & 76 deletions examples/sample-scenes/assets/Organisms/man.weird

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions examples/sample-scenes/include/DestroyScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
56 changes: 46 additions & 10 deletions examples/sample-scenes/include/MoleculeEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class MoleculeEditor : public Scene
Drag,
Spring,
Distance,
Remove,
TagEditor,
Material
};
Expand Down Expand Up @@ -86,7 +87,7 @@ class MoleculeEditor : public Scene
int m_selectedMaterial = 1;

ToolMode m_toolMode = ToolMode::Drag;
std::array<Entity, 5> m_toolToggles{};
std::array<Entity, 6> m_toolToggles{};
Entity m_gravityToggleEntity = static_cast<Entity>(-1);
Entity m_gridToggleEntity = static_cast<Entity>(-1);

Expand Down Expand Up @@ -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};
Expand Down Expand Up @@ -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<ShapeToggle>(m_toolToggles[i]);
if (t.active && t.state == ButtonState::Down)
Expand All @@ -413,7 +414,7 @@ class MoleculeEditor : public Scene
if (activated >= 0)
{
m_toolMode = static_cast<ToolMode>(activated);
for (int i = 0; i < 5; i++)
for (int i = 0; i < 6; i++)
{
if (i != activated)
m_ecs.getComponent<ShapeToggle>(m_toolToggles[i]).active = false;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -653,8 +654,15 @@ class MoleculeEditor : public Scene
Entity hit = pickBallAtMouse();
if (hit != static_cast<Entity>(-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<Entity>(-1);
Expand Down Expand Up @@ -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<SimulationID>(idA), static_cast<SimulationID>(idB));
}

void handleConstraintLineClicks()
{
// Detect click-down via ShapeButton state.
Expand Down Expand Up @@ -1064,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;
}
};
185 changes: 185 additions & 0 deletions examples/sample-scenes/include/WalkScene.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#pragma once

#include <weird-engine.h>

#include <filesystem>

#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:

Entity m_head;

// Inherited via Scene
void onStart() override
{
m_debugInput = true;
m_debugFly = true;

auto tags = loadWeirdFile(ASSETS_PATH "Organisms/man.weird");

Entity firstCreated = static_cast<Entity>(m_ecs.getEntityCount());

Entity lastCreated = static_cast<Entity>(m_ecs.getEntityCount());

for (Entity e = 0; e < (lastCreated - firstCreated); e++)
{
auto& t = m_ecs.getComponent<Transform>(firstCreated + e);
t.position += vec3(-10.0f, 0.0f, 0.0f);
}

Entity leftFootEntity = tags["foot_left"];
m_ecs.addComponent<Foot>(leftFootEntity);

Entity rightFootEntity = tags["foot_right"];
m_ecs.addComponent<Foot>(rightFootEntity);

m_head = tags["head"];


float boundsVars2[8]{0.0f, -24.0f, 200.0f, 20.0f};
Entity inside = addShape(DefaultShapes::BOX, boundsVars2, DisplaySettings::LightGray, CombinationType::Addition);

m_ecs.getComponent<Transform>(m_mainCamera).position = g_cameraPositon;

m_simulation2D.setGravity(-10.0f);
}

void onUpdate(float delta) override
{
g_cameraPositon = m_ecs.getComponent<Transform>(m_mainCamera).position;

if (Input::GetKeyDown(Input::Q))
{
setSceneComplete();
}
}

int m_currentFoot = 0;
bool m_feetTouching = false;
void onPhysicsStep() override
{
auto componentArray = m_ecs.getComponentArray<Foot>();
auto rigidBodies = m_ecs.getComponentArray<RigidBody2D>();

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;
}

auto& headRB = m_ecs.getComponent<RigidBody2D>(m_head);
m_simulation2D.addForce(headRB.simulationId, vec2(0.0f, 1.0f));

m_simulation2D.unFix(rb.simulationId);

// 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));
m_simulation2D.unFix(rb.simulationId);
}
}
else
{
// End step
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 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<Foot>(entityA) && m_ecs.hasComponent<Foot>(entityB))
{
m_feetTouching = true;
}
}

void onEntityShapeCollision(WeirdEngine::EntityShapeCollisionEvent& event) override
{
Entity entity = event.entity;
if (m_ecs.hasComponent<Foot>(entity))
{
auto& foot = m_ecs.getComponent<Foot>(entity);
if (event.raw.state == CollisionState::START)
{
foot.onFloor = true;
}
else if (event.raw.state == CollisionState::END)
{

foot.onFloor = false;
}
}
}
};
3 changes: 3 additions & 0 deletions examples/sample-scenes/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "MouseCollisionScene.h"
#include "RopeScene.h"
#include "ShapesCombinations.h"
#include "WalkScene.h"

#include "globals.h"
#include "MoleculeEditor.h"
Expand All @@ -21,6 +22,7 @@ WeirdEngine::vec3 g_cameraPositon = vec3(15.0f, 7.5f, 35.0f);
int main(int argc, char* argv[])
{
SceneManager& sceneManager = SceneManager::getInstance();

sceneManager.registerScene<ShapeCombinatiosScene>("shapes");
sceneManager.registerScene<RopeScene>("rope");
sceneManager.registerScene<MouseCollisionScene>("cursor-collision");
Expand All @@ -30,6 +32,7 @@ int main(int argc, char* argv[])
sceneManager.registerScene<SceneLoadExample>("scene-editor", ASSETS_PATH "example.weird");
sceneManager.registerScene<MoleculeEditor>("molecule-editor");
sceneManager.registerScene<LifeScene>("life");
sceneManager.registerScene<WalkScene>("walk");

DisplaySettings displaySettings{};
displaySettings.width = 800;
Expand Down
19 changes: 18 additions & 1 deletion include/weird-engine/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -99,7 +112,8 @@ namespace WeirdEngine
virtual void onRender(WeirdRenderer::RenderTarget& renderTarget) {};
virtual void onPhysicsStep() {};
virtual void onCollision(WeirdEngine::CollisionEvent& event) {};
virtual void onShapeCollision(WeirdEngine::ShapeCollisionEvent& event) {};
virtual void onEntityCollision(WeirdEngine::EntityCollisionEvent& event) {};
virtual void onEntityShapeCollision(WeirdEngine::EntityShapeCollisionEvent& event) {};
virtual void onDestroy() {};

void setSceneComplete(std::string nextScene = "")
Expand Down Expand Up @@ -143,6 +157,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;

Expand Down
1 change: 1 addition & 0 deletions include/weird-physics/Simulation2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,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);
Expand Down
Loading
Loading