Cogs.Core
GhostSystem.cpp
1#include "GhostSystem.h"
2#include "PhysicsManager.h"
3
4#include <glm/gtc/type_ptr.hpp>
5
6#include "Systems/Core/TransformSystem.h"
7
8#include "Context.h"
9
10#include "Services/Services.h"
11#include "Services/Time.h"
12#include "Services/TaskManager.h"
13
14#include "EntityStore.h"
15
16#include "CollisionComponent.h"
17
18#include "Platform/Instrumentation.h"
19
20namespace {
21 using namespace Cogs::Core;
22
23 void updateProperties(GhostData& ghostData)
24 {
25 ghostData.collisionShape->setLocalScaling(toBullet(ghostData.scale));
26
27 const float margin = glm::min(glm::min(ghostData.scale.x, ghostData.scale.y), ghostData.scale.z);
28 const float marginMultiplier = 0.1f;
29 auto diff = ghostData.scale - glm::vec3(1, 1, 1);
30
31 if (glm::any(glm::greaterThan(glm::abs(diff), glm::vec3(0.01f, 0.01f, 0.01f)))) {
32 ghostData.collisionShape->setMargin(margin * marginMultiplier);
33 }
34 }
35
36}
37
38
40{
41 auto manager = context->services->getService<PhysicsManager>();
42 for (auto & ghostComp : pool) {
43 if (!ghostComp.isActive()) continue;
44
45 auto & ghostData = getData(&ghostComp);
46
47 const auto * trComp = ghostComp.getComponent<TransformComponent>();
48 context->transformSystem->updateLocalToWorldTransform(*trComp, true);
49 const auto & worldTransform = context->transformSystem->getLocalToWorld(trComp);
50 const auto scale = glm::vec3(glm::length(worldTransform[0]), glm::length(worldTransform[1]), glm::length(worldTransform[2]));
51 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)))));
52 const auto position = glm::vec4(worldTransform[3]);
53 const btTransform origin(toBullet(rotation), toBullet(position));
54
55 if (!ghostData.collisionObject) {
56 const auto * collComp = ghostComp.getComponent<CollisionComponent>();
57 if (!collComp || !collComp->collisionShape) {
58 continue;
59 }
60 ghostData.collisionShape = collComp->collisionShape;
61
62
63 //ghostData.motionState = std::make_unique<btDefaultMotionState>(origin);
64
65 ghostData.scale = scale;
66 updateProperties(ghostData);
67
68 ghostData.shared = std::make_unique<SharedRigidBodyData>();
69 ghostData.shared->entity = context->store->getEntity(ghostComp.getContainer()->getId());
70
71 ghostData.collisionObject = std::make_unique<btPairCachingGhostObject>();
72 ghostData.collisionObject->setUserPointer(ghostData.shared.get());
73
74 ghostData.collisionObject->setCollisionShape(collComp->collisionShape);
75 ghostData.collisionObject->setCollisionFlags(ghostData.collisionObject->getCollisionFlags() | btCollisionObject::CF_CHARACTER_OBJECT); // Blind copy from an example, no idea what proper flags are.
76 //data.rigidBody->setCollisionFlags(data.rigidBody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_KINEMATIC_OBJECT);
77 //data.rigidBody->setActivationState(DISABLE_DEACTIVATION);
78
79 manager->addCollisionObject(ghostData.collisionObject.get());
80 }
81
82 if (glm::any(glm::greaterThan(glm::abs(scale - ghostData.scale), glm::vec3(0.001f)))) {
83 manager->removeCollisionObject(ghostData.collisionObject.get());
84 ghostData.scale = scale;
85 updateProperties(ghostData);
86 manager->addCollisionObject(ghostData.collisionObject.get());
87 }
88 ghostData.collisionObject->setWorldTransform(origin);
89 }
90}
91
93{
94 auto * ghostComp = component.resolveComponent<GhostComponent>();
95 auto & ghostData = getData(ghostComp);
96
97 if (ghostData.collisionObject) {
98 auto manager = context->services->getService<PhysicsManager>();
99 manager->removeCollisionObject(ghostData.collisionObject.get());
100 }
102}
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.
void destroyComponent(ComponentHandle component) final
Definition: GhostSystem.cpp:92
Defines a 4x4 transformation matrix for the entity and a global offset for root entities.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
Handle to a Component instance.
Definition: Component.h:67
ComponentType * resolveComponent() const
Definition: Component.h:90