Cogs.Core
TriggerSystem.cpp
1#include "TriggerSystem.h"
2
3#include "PhysicsManager.h"
4
5#include <glm/gtc/type_ptr.hpp>
6
7#include "Systems/Core/TransformSystem.h"
8
9#include "Context.h"
10
11#include "Services/Services.h"
12#include "Services/Time.h"
13#include "Services/TaskManager.h"
14
15#include "EntityStore.h"
16
17#include "CollisionComponent.h"
18
19#include "Platform/Instrumentation.h"
20
22{
23 auto manager = context->services->getService<PhysicsManager>();
24
25 for (auto & c : pool) {
26 if (!c.isActive()) continue;
27
28 auto & data = getData(&c);
29
30 auto transformComponent = c.getComponent<TransformComponent>();
31
32 if (!data.rigidBody) {
33 auto collisionComponent = c.getComponent<CollisionComponent>();
34
35 if (!collisionComponent || !collisionComponent->collisionShape) {
36 continue;
37 }
38
39 data.collisionShape = collisionComponent->collisionShape;
40
41 context->transformSystem->updateLocalToWorldTransform(*transformComponent, true);
42 auto worldTransform = context->transformSystem->getLocalToWorld(transformComponent);
43
44 auto scale = glm::vec3(glm::length(worldTransform[0]), glm::length(worldTransform[1]), glm::length(worldTransform[2]));
45 auto rotation = glm::normalize(glm::quat_cast(glm::mat3(worldTransform * glm::scale(glm::vec3(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z)))));
46 auto position = glm::vec4(worldTransform[3]);
47
48 data.scale = scale;
49 data.collisionShape->setLocalScaling(toBullet(scale));
50
51 const btTransform origin(toBullet(rotation), toBullet(position));
52
53 data.motionState = std::make_unique<btDefaultMotionState>(origin);
54
55 btRigidBody::btRigidBodyConstructionInfo ci(0, data.motionState.get(), data.collisionShape, btVector3());
56
57 data.rigidBody = std::make_unique<btRigidBody>(ci);
58 data.shared = std::make_unique<SharedRigidBodyData>();
59 data.shared->trigger = true;
60 data.shared->entity = context->store->getEntity(c.getContainer()->getId());
61 data.rigidBody->setUserPointer(data.shared.get());
62
63 data.rigidBody->setCollisionFlags(data.rigidBody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_KINEMATIC_OBJECT);
64 data.rigidBody->setActivationState(DISABLE_DEACTIVATION);
65
66 manager->addRigidBody(data.rigidBody.get());
67 }
68
69 if (data.rigidBody) {
70 auto motionState = static_cast<btDefaultMotionState *>(data.motionState.get());
71
72 context->transformSystem->updateLocalToWorldTransform(*transformComponent, true);
73 const auto & worldTransform = context->transformSystem->getLocalToWorld(transformComponent);
74
75 const auto scale = glm::vec3(glm::length(worldTransform[0]), glm::length(worldTransform[1]), glm::length(worldTransform[2]));
76 const auto rotation = glm::normalize(glm::quat_cast(glm::mat3(worldTransform * glm::scale(glm::vec3(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z)))));
77 const auto position = glm::vec4(worldTransform[3]);
78
79 if (glm::any(glm::greaterThan(glm::abs(scale - data.scale), glm::vec3(0.001f)))) {
80 manager->removeRigidBody(data.rigidBody.get());
81 updateMassProperties(data, 0, scale);
82 manager->addRigidBody(data.rigidBody.get());
83 }
84
85 const btTransform origin(toBullet(rotation), toBullet(position));
86
87 motionState->setWorldTransform(origin);
88 }
89 }
90}
91
93{
94 auto manager = context->services->getService<PhysicsManager>();
95 manager->waitForASync(context);
96
97 auto c = component.resolveComponent<TriggerComponent>();
98 auto & data = getData(c);
99
100 if (data.rigidBody) {
101 manager->removeRigidBody(data.rigidBody.get());
102 }
103
105}
ComponentType * getComponent() const
Definition: Component.h:159
Context * context
Pointer to the Context instance the system lives in.
virtual void destroyComponent(ComponentHandle)
Destroy the component held by the given handle.
void update()
Updates the system state to that of the current frame.
ComponentPool< ComponentType > pool
Pool of components managed by the system.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
std::unique_ptr< class Services > services
Services.
Definition: Context.h:174
class EntityStore * store
Entity store.
Definition: Context.h:231
EntityPtr getEntity(const StringView &name, bool logIfNotFound=true) const
Retrieve a reference to the shared entity pointer to the Entity with the given name.
Defines a 4x4 transformation matrix for the entity and a global offset for root entities.
void destroyComponent(ComponentHandle component) final
Handle to a Component instance.
Definition: Component.h:67
ComponentType * resolveComponent() const
Definition: Component.h:90