WIP JointService; make & break joints functions

This commit is contained in:
floralrainfall 2023-07-22 03:12:48 -04:00
parent bdc8ad0305
commit 0fc6b0cb54
13 changed files with 133 additions and 65 deletions

View File

@ -9,6 +9,8 @@ namespace RNR
ModelInstance(); ModelInstance();
virtual void build(); virtual void build();
void makeJoints();
void breakJoints();
Ogre::AxisAlignedBox getBoundingBox() { return m_boundingbox; } Ogre::AxisAlignedBox getBoundingBox() { return m_boundingbox; }
virtual std::string getClassName() { return "Model"; } virtual std::string getClassName() { return "Model"; }
virtual void onChildAdded(Instance* instance); virtual void onChildAdded(Instance* instance);

View File

@ -7,27 +7,34 @@ namespace RNR
{ {
class JointInstance : public Instance class JointInstance : public Instance
{ {
protected:
PartInstance *m_aInstance, *m_bInstance; PartInstance *m_aInstance, *m_bInstance;
btRigidBody *m_aBody, *m_bBody; btRigidBody *m_aBody, *m_bBody;
CoordinateFrame m_c0, m_c1; CoordinateFrame m_c0, m_c1;
btTypedConstraint *m_constraint;
bool m_dirty;
bool m_collidesWithSelf;
virtual void addProperties(std::vector<ReflectionProperty>& properties); virtual void addProperties(std::vector<ReflectionProperty>& properties);
virtual void deserializeProperty(char* prop_name, pugi::xml_node prop); virtual void deserializeProperty(char* prop_name, pugi::xml_node prop);
virtual btTypedConstraint* constraint() { return NULL; };
public: public:
JointInstance(); JointInstance();
~JointInstance();
void setBodies(PartInstance* a, PartInstance* b); void setBodies(PartInstance* a, PartInstance* b);
PartInstance* getABody() { return m_aInstance; } 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; } 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; } 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; } CoordinateFrame& getC1() { return m_c1; }
void setC1(CoordinateFrame c) { m_c1 = c; } void setC1(CoordinateFrame c) { m_c1 = c; m_dirty = true; }
void link(); void link();
bool getDirty() { return m_dirty; };
}; };
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <App/V8/Tree/Instance.hpp> #include <App/V8/Tree/Instance.hpp>
#include <App/V8/Tree/ModelInstance.hpp>
#include <App/V8/DataModel/PartInstance.hpp> #include <App/V8/DataModel/PartInstance.hpp>
#include <App/V8/World/Weld.hpp> #include <App/V8/World/Weld.hpp>
@ -14,10 +15,12 @@ namespace RNR
void makeJoints(Instance* w, PartInstance* p); void makeJoints(Instance* w, PartInstance* p);
void makeJoints(PartInstance* p); void makeJoints(PartInstance* p);
void breakJoints(PartInstance* b);
void makeModelJoints(ModelInstance* m);
void breakModelJoints(ModelInstance* m);
void fixWelds(); void fixWelds();
void breakJoints(PartInstance* b);
bool isWelded(PartInstance* a, PartInstance* b); bool isWelded(PartInstance* a, PartInstance* b);
}; };
} }

View File

@ -8,25 +8,10 @@ namespace RNR
{ {
class Weld : public JointInstance class Weld : public JointInstance
{ {
btRigidBody* m_aBody; virtual btTypedConstraint* constraint();
PartInstance* m_aInstance;
btRigidBody* m_bBody;
PartInstance* m_bInstance;
btFixedConstraint* m_constraint;
public: public:
Weld(); Weld();
~Weld();
virtual std::string getClassName() { return "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 class Snap : public Weld

View File

@ -41,7 +41,7 @@ namespace RNR
{ {
Weld* headWeld = new Weld(); Weld* headWeld = new Weld();
headWeld->setBodies(getTorso(), getHead()); headWeld->setBodies(getTorso(), getHead());
headWeld->create(); headWeld->link();
headWeld->setParent(getTorso()); headWeld->setParent(getTorso());
} }

View File

@ -105,7 +105,7 @@ namespace RNR
{ {
m_surfaces[i].face = (NormalId)i; m_surfaces[i].face = (NormalId)i;
PartSurfaceInfo& surf = m_surfaces[i]; PartSurfaceInfo& surf = m_surfaces[i];
Ogre::Vector3 size = ((getSize() / 2.f) * getRotation()); Ogre::Vector3 size = ((getSize()) * getRotation());
Ogre::Vector3 pos = getPosition(); Ogre::Vector3 pos = getPosition();
switch(m_surfaces[i].face) switch(m_surfaces[i].face)
{ {

View File

@ -1,5 +1,6 @@
#include <App/V8/Tree/ModelInstance.hpp> #include <App/V8/Tree/ModelInstance.hpp>
#include <App/V8/DataModel/PartInstance.hpp> #include <App/V8/DataModel/PartInstance.hpp>
#include <App/V8/World/World.hpp>
#include <App/Humanoid/Humanoid.hpp> #include <App/Humanoid/Humanoid.hpp>
namespace RNR namespace RNR
@ -16,6 +17,16 @@ namespace RNR
childAddBoundingBox(child); childAddBoundingBox(child);
} }
void ModelInstance::makeJoints()
{
}
void ModelInstance::breakJoints()
{
}
void ModelInstance::childAddBoundingBox(Instance* child) void ModelInstance::childAddBoundingBox(Instance* child)
{ {
for(auto& child2 : *child->getChildren()) for(auto& child2 : *child->getChildren())

View File

@ -1,5 +1,6 @@
#include <App/V8/World/ComPlicitNgine.hpp> #include <App/V8/World/ComPlicitNgine.hpp>
#include <App/V8/World/World.hpp> #include <App/V8/World/World.hpp>
#include <App/V8/World/JointsService.hpp>
#include <Helpers/Bullet.hpp> #include <Helpers/Bullet.hpp>
namespace RNR namespace RNR
@ -20,8 +21,14 @@ namespace RNR
if(m_lastPhysicsDelta == 0) if(m_lastPhysicsDelta == 0)
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
m_world->preStep(); if(m_world->getRunService()->getRunning())
m_world->step(delta); {
m_world->preStep();
m_world->step(delta);
}
JointsService* joints = (JointsService*)m_world->getDatamodel()->getService("JointsService");
joints->fixWelds();
m_lastPhysicsDelta = delta; m_lastPhysicsDelta = delta;
} }

View File

@ -6,6 +6,14 @@ namespace RNR
JointInstance::JointInstance() JointInstance::JointInstance()
{ {
setName("Joint"); 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) void JointInstance::setBodies(PartInstance* a, PartInstance* b)
@ -15,6 +23,8 @@ namespace RNR
m_aBody = world->getComPlicitNgine()->getBody(a); m_aBody = world->getComPlicitNgine()->getBody(a);
m_bBody = world->getComPlicitNgine()->getBody(b); m_bBody = world->getComPlicitNgine()->getBody(b);
m_dirty = true;
} }
void JointInstance::addProperties(std::vector<ReflectionProperty>& properties) void JointInstance::addProperties(std::vector<ReflectionProperty>& properties)
@ -24,10 +34,18 @@ namespace RNR
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_INSTANCE, ACCESS_NONE, OPERATION_READWRITE, PROPERTY_INSTANCE,
REFLECTION_GETTER(JointInstance* instance = (JointInstance*)object; return instance->m_aInstance; ), REFLECTION_GETTER(JointInstance* instance = (JointInstance*)object; return instance->m_aInstance; ),
REFLECTION_SETTER(JointInstance* instance = (JointInstance*)object; ) }, 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(""), { this, std::string("Part1"), std::string(""),
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_INSTANCE, ACCESS_NONE, OPERATION_READWRITE, PROPERTY_INSTANCE,
REFLECTION_GETTER(JointInstance* instance = (JointInstance*)object; return instance->m_bInstance; ), REFLECTION_GETTER(JointInstance* instance = (JointInstance*)object; return instance->m_bInstance; ),
REFLECTION_SETTER(JointInstance* instance = (JointInstance*)object; ) }, 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))); 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");
}
} }

View File

@ -20,8 +20,9 @@ namespace RNR
{ {
for(auto& child : *getChildren()) for(auto& child : *getChildren())
{ {
Weld* weld = dynamic_cast<Weld*>(child); JointInstance* weld = dynamic_cast<JointInstance*>(child);
weld->create(); if(weld->getDirty())
weld->link();
} }
} }
@ -45,8 +46,6 @@ namespace RNR
NormalId n_opp = normalIdOpposite(n); NormalId n_opp = normalIdOpposite(n);
PartSurfaceInfo n_surf = p->getSurface(n); PartSurfaceInfo n_surf = p->getSurface(n);
PartSurfaceInfo n_opp_surf = child_p->getSurface(n_opp); 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.intersects(n_opp_surf))
{ {
if(n_surf.links(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<PartInstance*>(child))
makeJoints(parent_model, (PartInstance*)child);
}
}
void JointsService::breakModelJoints(ModelInstance* m)
{
for(auto& child : *getChildren())
{
JointInstance* snap = dynamic_cast<JointInstance*>(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) void JointsService::makeJoints(PartInstance* p)
{ {
p->updateSurfaces(); p->updateSurfaces();
@ -78,13 +114,13 @@ namespace RNR
{ {
for(auto& child : *getChildren()) for(auto& child : *getChildren())
{ {
Snap* snap = dynamic_cast<Snap*>(child); JointInstance* snap = dynamic_cast<JointInstance*>(child);
if(snap) if(snap)
{ {
bool brk = false; bool brk = false;
if(snap->getPartA() == p) if(snap->getABody() == p)
brk = true; brk = true;
else if(snap->getPartB() == p) else if(snap->getBBody() == p)
brk = true; brk = true;
if(brk) if(brk)
{ {
@ -101,9 +137,9 @@ namespace RNR
Weld* snap = dynamic_cast<Weld*>(child); Weld* snap = dynamic_cast<Weld*>(child);
if(snap) if(snap)
{ {
if(snap->getPartA() == a && snap->getPartB() == b) if(snap->getABody() == a && snap->getBBody() == b)
return true; return true;
else if(snap->getPartA() == b && snap->getPartB() == a) else if(snap->getABody() == b && snap->getBBody() == a)
return true; return true;
} }
} }

View File

@ -1,45 +1,25 @@
#include <App/V8/World/Weld.hpp> #include <App/V8/World/Weld.hpp>
#include <App/V8/World/World.hpp> #include <App/V8/World/World.hpp>
#include <Helpers/Bullet.hpp>
namespace RNR namespace RNR
{ {
Weld::Weld() : JointInstance() Weld::Weld() : JointInstance()
{ {
setName("Weld"); 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; btTransform frameInA, frameInB;
frameInA = btTransform::getIdentity(); frameInA = btTransform::getIdentity();
frameInA.setOrigin(Bullet::v3ToBullet(m_c0.getPosition()));
frameInA.setRotation(Bullet::qtToBullet(m_c0.getRotation()));
frameInB = btTransform::getIdentity(); 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); return 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;
} }
} }

View File

@ -159,7 +159,6 @@ namespace RNR
printf("World::load: XML parsed with errors, description '%s', offset %i\n", result.description(), result.offset); printf("World::load: XML parsed with errors, description '%s', offset %i\n", result.description(), result.offset);
} }
m_workspace->build(); m_workspace->build();
joints->fixWelds();
} }
void World::preRender(float timestep) void World::preRender(float timestep)

View File

@ -55,7 +55,7 @@ namespace RNR
character_humanoid->setParent(m_character); character_humanoid->setParent(m_character);
m_character->setParent(world->getWorkspace()); m_character->setParent(world->getWorkspace());
character_humanoid->buildJoints();
Camera* player_camera = world->getWorkspace()->getCurrentCamera(); Camera* player_camera = world->getWorkspace()->getCurrentCamera();
player_camera->setCFrame(CoordinateFrame()); player_camera->setCFrame(CoordinateFrame());