From 0fc6b0cb54addb719ee5a5894ce67269e5a133be Mon Sep 17 00:00:00 2001 From: floralrainfall Date: Sat, 22 Jul 2023 03:12:48 -0400 Subject: [PATCH] WIP JointService; make & break joints functions --- .../Header/App/V8/Tree/ModelInstance.hpp | 2 + .../Header/App/V8/World/JointInstance.hpp | 17 ++++-- .../Header/App/V8/World/JointsService.hpp | 5 +- Projects/Engine/Header/App/V8/World/Weld.hpp | 17 +----- .../Engine/Source/App/Humanoid/Humanoid.cpp | 2 +- .../Source/App/V8/DataModel/PartInstance.cpp | 2 +- .../Source/App/V8/Tree/ModelInstance.cpp | 11 ++++ .../Source/App/V8/World/ComPlicitNgine.cpp | 11 +++- .../Source/App/V8/World/JointInstance.cpp | 38 +++++++++++++ .../Source/App/V8/World/JointsService.cpp | 54 +++++++++++++++---- Projects/Engine/Source/App/V8/World/Weld.cpp | 36 +++---------- Projects/Engine/Source/App/V8/World/World.cpp | 1 - Projects/Engine/Source/Network/Player.cpp | 2 +- 13 files changed, 133 insertions(+), 65 deletions(-) diff --git a/Projects/Engine/Header/App/V8/Tree/ModelInstance.hpp b/Projects/Engine/Header/App/V8/Tree/ModelInstance.hpp index 74f3ab2..451e19d 100644 --- a/Projects/Engine/Header/App/V8/Tree/ModelInstance.hpp +++ b/Projects/Engine/Header/App/V8/Tree/ModelInstance.hpp @@ -9,6 +9,8 @@ namespace RNR ModelInstance(); virtual void build(); + void makeJoints(); + void breakJoints(); Ogre::AxisAlignedBox getBoundingBox() { return m_boundingbox; } virtual std::string getClassName() { return "Model"; } virtual void onChildAdded(Instance* instance); diff --git a/Projects/Engine/Header/App/V8/World/JointInstance.hpp b/Projects/Engine/Header/App/V8/World/JointInstance.hpp index 599bb92..603afba 100644 --- a/Projects/Engine/Header/App/V8/World/JointInstance.hpp +++ b/Projects/Engine/Header/App/V8/World/JointInstance.hpp @@ -7,27 +7,34 @@ namespace RNR { class JointInstance : public Instance { + protected: PartInstance *m_aInstance, *m_bInstance; btRigidBody *m_aBody, *m_bBody; CoordinateFrame m_c0, m_c1; + btTypedConstraint *m_constraint; + bool m_dirty; + bool m_collidesWithSelf; virtual void addProperties(std::vector& properties); virtual void deserializeProperty(char* prop_name, pugi::xml_node prop); + + virtual btTypedConstraint* constraint() { return NULL; }; public: JointInstance(); + ~JointInstance(); void setBodies(PartInstance* a, PartInstance* b); PartInstance* getABody() { return m_aInstance; } - void setABody(PartInstance* a) { m_aInstance = a; } + void setABody(PartInstance* a) { m_aInstance = a; m_dirty = true; } PartInstance* getBBody() { return m_bInstance; } - void setBBody(PartInstance* b) { m_bInstance = b; } + void setBBody(PartInstance* b) { m_bInstance = b; m_dirty = true; } CoordinateFrame& getC0() { return m_c0; } - void setC0(CoordinateFrame c) { m_c0 = c; } + void setC0(CoordinateFrame c) { m_c0 = c; m_dirty = true; } CoordinateFrame& getC1() { return m_c1; } - void setC1(CoordinateFrame c) { m_c1 = c; } - + void setC1(CoordinateFrame c) { m_c1 = c; m_dirty = true; } void link(); + bool getDirty() { return m_dirty; }; }; } \ No newline at end of file diff --git a/Projects/Engine/Header/App/V8/World/JointsService.hpp b/Projects/Engine/Header/App/V8/World/JointsService.hpp index 4669d5b..69c5a1a 100644 --- a/Projects/Engine/Header/App/V8/World/JointsService.hpp +++ b/Projects/Engine/Header/App/V8/World/JointsService.hpp @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include @@ -14,10 +15,12 @@ namespace RNR void makeJoints(Instance* w, PartInstance* p); void makeJoints(PartInstance* p); + void breakJoints(PartInstance* b); + void makeModelJoints(ModelInstance* m); + void breakModelJoints(ModelInstance* m); void fixWelds(); - void breakJoints(PartInstance* b); bool isWelded(PartInstance* a, PartInstance* b); }; } \ No newline at end of file diff --git a/Projects/Engine/Header/App/V8/World/Weld.hpp b/Projects/Engine/Header/App/V8/World/Weld.hpp index 5b304bc..e94ca0f 100644 --- a/Projects/Engine/Header/App/V8/World/Weld.hpp +++ b/Projects/Engine/Header/App/V8/World/Weld.hpp @@ -8,25 +8,10 @@ namespace RNR { class Weld : public JointInstance { - btRigidBody* m_aBody; - PartInstance* m_aInstance; - - btRigidBody* m_bBody; - PartInstance* m_bInstance; - - btFixedConstraint* m_constraint; + virtual btTypedConstraint* constraint(); public: Weld(); - ~Weld(); virtual std::string getClassName() { return "Weld"; } - - void weld(PartInstance* a, PartInstance* b); - bool create(); - void destroy(); - - bool getBroken(); - PartInstance* getPartA() { return m_aInstance; } - PartInstance* getPartB() { return m_bInstance; } }; class Snap : public Weld diff --git a/Projects/Engine/Source/App/Humanoid/Humanoid.cpp b/Projects/Engine/Source/App/Humanoid/Humanoid.cpp index 676865b..468dd6c 100644 --- a/Projects/Engine/Source/App/Humanoid/Humanoid.cpp +++ b/Projects/Engine/Source/App/Humanoid/Humanoid.cpp @@ -41,7 +41,7 @@ namespace RNR { Weld* headWeld = new Weld(); headWeld->setBodies(getTorso(), getHead()); - headWeld->create(); + headWeld->link(); headWeld->setParent(getTorso()); } diff --git a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp index ac11fa6..11c286b 100644 --- a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp @@ -105,7 +105,7 @@ namespace RNR { m_surfaces[i].face = (NormalId)i; PartSurfaceInfo& surf = m_surfaces[i]; - Ogre::Vector3 size = ((getSize() / 2.f) * getRotation()); + Ogre::Vector3 size = ((getSize()) * getRotation()); Ogre::Vector3 pos = getPosition(); switch(m_surfaces[i].face) { diff --git a/Projects/Engine/Source/App/V8/Tree/ModelInstance.cpp b/Projects/Engine/Source/App/V8/Tree/ModelInstance.cpp index 833732a..74021df 100644 --- a/Projects/Engine/Source/App/V8/Tree/ModelInstance.cpp +++ b/Projects/Engine/Source/App/V8/Tree/ModelInstance.cpp @@ -1,5 +1,6 @@ #include #include +#include #include namespace RNR @@ -16,6 +17,16 @@ namespace RNR childAddBoundingBox(child); } + void ModelInstance::makeJoints() + { + + } + + void ModelInstance::breakJoints() + { + + } + void ModelInstance::childAddBoundingBox(Instance* child) { for(auto& child2 : *child->getChildren()) diff --git a/Projects/Engine/Source/App/V8/World/ComPlicitNgine.cpp b/Projects/Engine/Source/App/V8/World/ComPlicitNgine.cpp index f32ac2a..02dd89d 100644 --- a/Projects/Engine/Source/App/V8/World/ComPlicitNgine.cpp +++ b/Projects/Engine/Source/App/V8/World/ComPlicitNgine.cpp @@ -1,5 +1,6 @@ #include #include +#include #include namespace RNR @@ -20,8 +21,14 @@ namespace RNR if(m_lastPhysicsDelta == 0) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - m_world->preStep(); - m_world->step(delta); + if(m_world->getRunService()->getRunning()) + { + m_world->preStep(); + m_world->step(delta); + } + + JointsService* joints = (JointsService*)m_world->getDatamodel()->getService("JointsService"); + joints->fixWelds(); m_lastPhysicsDelta = delta; } diff --git a/Projects/Engine/Source/App/V8/World/JointInstance.cpp b/Projects/Engine/Source/App/V8/World/JointInstance.cpp index c28fbde..c6369b9 100644 --- a/Projects/Engine/Source/App/V8/World/JointInstance.cpp +++ b/Projects/Engine/Source/App/V8/World/JointInstance.cpp @@ -6,6 +6,14 @@ namespace RNR JointInstance::JointInstance() { setName("Joint"); + m_collidesWithSelf = true; + m_dirty = false; + } + + JointInstance::~JointInstance() + { + world->getDynamicsWorld()->removeConstraint(m_constraint); + delete m_constraint; } void JointInstance::setBodies(PartInstance* a, PartInstance* b) @@ -15,6 +23,8 @@ namespace RNR m_aBody = world->getComPlicitNgine()->getBody(a); m_bBody = world->getComPlicitNgine()->getBody(b); + + m_dirty = true; } void JointInstance::addProperties(std::vector& properties) @@ -24,10 +34,18 @@ namespace RNR ACCESS_NONE, OPERATION_READWRITE, PROPERTY_INSTANCE, REFLECTION_GETTER(JointInstance* instance = (JointInstance*)object; return instance->m_aInstance; ), REFLECTION_SETTER(JointInstance* instance = (JointInstance*)object; ) }, + { this, std::string("C0"), std::string(""), + ACCESS_NONE, OPERATION_READWRITE, PROPERTY_CFRAME, + REFLECTION_GETTER(JointInstance* instance = (JointInstance*)object; return &instance->m_c0; ), + REFLECTION_SETTER(JointInstance* instance = (JointInstance*)object; ) }, { this, std::string("Part1"), std::string(""), ACCESS_NONE, OPERATION_READWRITE, PROPERTY_INSTANCE, REFLECTION_GETTER(JointInstance* instance = (JointInstance*)object; return instance->m_bInstance; ), REFLECTION_SETTER(JointInstance* instance = (JointInstance*)object; ) }, + { this, std::string("C1"), std::string(""), + ACCESS_NONE, OPERATION_READWRITE, PROPERTY_CFRAME, + REFLECTION_GETTER(JointInstance* instance = (JointInstance*)object; return &instance->m_c0; ), + REFLECTION_SETTER(JointInstance* instance = (JointInstance*)object; ) }, }; properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty))); @@ -37,4 +55,24 @@ namespace RNR { } + + void JointInstance::link() + { + if(!m_aBody || !m_bBody) + { + m_aBody = world->getComPlicitNgine()->getBody(m_aInstance); + m_bBody = world->getComPlicitNgine()->getBody(m_bInstance); + + if(!m_aBody || !m_bBody) + return; + } + m_constraint = constraint(); + m_dirty = false; + if(m_constraint) + { + world->getDynamicsWorld()->addConstraint(m_constraint, !m_collidesWithSelf); + } + else + printf("JointInstance::link: constraint returned NULL\n"); + } } \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/World/JointsService.cpp b/Projects/Engine/Source/App/V8/World/JointsService.cpp index 0ad7ae2..0f76e79 100644 --- a/Projects/Engine/Source/App/V8/World/JointsService.cpp +++ b/Projects/Engine/Source/App/V8/World/JointsService.cpp @@ -20,8 +20,9 @@ namespace RNR { for(auto& child : *getChildren()) { - Weld* weld = dynamic_cast(child); - weld->create(); + JointInstance* weld = dynamic_cast(child); + if(weld->getDirty()) + weld->link(); } } @@ -45,8 +46,6 @@ namespace RNR NormalId n_opp = normalIdOpposite(n); PartSurfaceInfo n_surf = p->getSurface(n); PartSurfaceInfo n_opp_surf = child_p->getSurface(n_opp); - if(n_surf.plane != n_opp_surf.plane) - continue; if(n_surf.intersects(n_opp_surf)) { if(n_surf.links(n_opp_surf)) @@ -68,6 +67,43 @@ namespace RNR } } + void JointsService::makeModelJoints(ModelInstance* m) + { + ModelInstance* parent_model = m; + + if(world->getWorkspace()->isAncestorOf(m)) + { + parent_model = world->getWorkspace(); + } + + for(auto& child : *m->getChildren()) + { + if(dynamic_cast(child)) + makeJoints(parent_model, (PartInstance*)child); + } + } + + void JointsService::breakModelJoints(ModelInstance* m) + { + for(auto& child : *getChildren()) + { + JointInstance* snap = dynamic_cast(child); + if(snap) + { + bool brk = false; + if(m->isAncestorOf(snap->getABody())) + brk = true; + else if(m->isAncestorOf(snap->getBBody())) + brk = true; + if(brk) + { + snap->setParent(NULL); + delete snap; + } + } + } + } + void JointsService::makeJoints(PartInstance* p) { p->updateSurfaces(); @@ -78,13 +114,13 @@ namespace RNR { for(auto& child : *getChildren()) { - Snap* snap = dynamic_cast(child); + JointInstance* snap = dynamic_cast(child); if(snap) { bool brk = false; - if(snap->getPartA() == p) + if(snap->getABody() == p) brk = true; - else if(snap->getPartB() == p) + else if(snap->getBBody() == p) brk = true; if(brk) { @@ -101,9 +137,9 @@ namespace RNR Weld* snap = dynamic_cast(child); if(snap) { - if(snap->getPartA() == a && snap->getPartB() == b) + if(snap->getABody() == a && snap->getBBody() == b) return true; - else if(snap->getPartA() == b && snap->getPartB() == a) + else if(snap->getABody() == b && snap->getBBody() == a) return true; } } diff --git a/Projects/Engine/Source/App/V8/World/Weld.cpp b/Projects/Engine/Source/App/V8/World/Weld.cpp index 7ff2f14..f70c1ae 100644 --- a/Projects/Engine/Source/App/V8/World/Weld.cpp +++ b/Projects/Engine/Source/App/V8/World/Weld.cpp @@ -1,45 +1,25 @@ #include #include +#include namespace RNR { Weld::Weld() : JointInstance() { setName("Weld"); + m_collidesWithSelf = true; } - Weld::~Weld() + btTypedConstraint* Weld::constraint() { - destroy(); - } - - bool Weld::create() - { - if(!m_aBody || !m_bBody) - { - printf("Weld::create: invalid body\n"); - return false; - } - btTransform frameInA, frameInB; frameInA = btTransform::getIdentity(); + frameInA.setOrigin(Bullet::v3ToBullet(m_c0.getPosition())); + frameInA.setRotation(Bullet::qtToBullet(m_c0.getRotation())); frameInB = btTransform::getIdentity(); + frameInB.setOrigin(Bullet::v3ToBullet(m_c1.getPosition())); + frameInB.setRotation(Bullet::qtToBullet(m_c1.getRotation())); - m_constraint = new btFixedConstraint(*m_aBody, *m_bBody, frameInA, frameInB); - printf("Weld::create: welded\n"); - return true; - } - - void Weld::destroy() - { - delete m_constraint; - } - - bool Weld::getBroken() - { - if(!m_constraint) - return true; - - return false; + return new btFixedConstraint(*m_aBody, *m_bBody, frameInA, frameInB); } } \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/World/World.cpp b/Projects/Engine/Source/App/V8/World/World.cpp index 6626436..0ac5954 100644 --- a/Projects/Engine/Source/App/V8/World/World.cpp +++ b/Projects/Engine/Source/App/V8/World/World.cpp @@ -159,7 +159,6 @@ namespace RNR printf("World::load: XML parsed with errors, description '%s', offset %i\n", result.description(), result.offset); } m_workspace->build(); - joints->fixWelds(); } void World::preRender(float timestep) diff --git a/Projects/Engine/Source/Network/Player.cpp b/Projects/Engine/Source/Network/Player.cpp index 7cf27b4..dfd8b18 100644 --- a/Projects/Engine/Source/Network/Player.cpp +++ b/Projects/Engine/Source/Network/Player.cpp @@ -55,7 +55,7 @@ namespace RNR character_humanoid->setParent(m_character); m_character->setParent(world->getWorkspace()); - character_humanoid->buildJoints(); + Camera* player_camera = world->getWorkspace()->getCurrentCamera(); player_camera->setCFrame(CoordinateFrame());