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();
virtual void build();
void makeJoints();
void breakJoints();
Ogre::AxisAlignedBox getBoundingBox() { return m_boundingbox; }
virtual std::string getClassName() { return "Model"; }
virtual void onChildAdded(Instance* instance);

View File

@ -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<ReflectionProperty>& 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; };
};
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <App/V8/Tree/Instance.hpp>
#include <App/V8/Tree/ModelInstance.hpp>
#include <App/V8/DataModel/PartInstance.hpp>
#include <App/V8/World/Weld.hpp>
@ -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);
};
}

View File

@ -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

View File

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

View File

@ -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)
{

View File

@ -1,5 +1,6 @@
#include <App/V8/Tree/ModelInstance.hpp>
#include <App/V8/DataModel/PartInstance.hpp>
#include <App/V8/World/World.hpp>
#include <App/Humanoid/Humanoid.hpp>
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())

View File

@ -1,5 +1,6 @@
#include <App/V8/World/ComPlicitNgine.hpp>
#include <App/V8/World/World.hpp>
#include <App/V8/World/JointsService.hpp>
#include <Helpers/Bullet.hpp>
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;
}

View File

@ -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<ReflectionProperty>& 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");
}
}

View File

@ -20,8 +20,9 @@ namespace RNR
{
for(auto& child : *getChildren())
{
Weld* weld = dynamic_cast<Weld*>(child);
weld->create();
JointInstance* weld = dynamic_cast<JointInstance*>(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<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)
{
p->updateSurfaces();
@ -78,13 +114,13 @@ namespace RNR
{
for(auto& child : *getChildren())
{
Snap* snap = dynamic_cast<Snap*>(child);
JointInstance* snap = dynamic_cast<JointInstance*>(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<Weld*>(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;
}
}

View File

@ -1,45 +1,25 @@
#include <App/V8/World/Weld.hpp>
#include <App/V8/World/World.hpp>
#include <Helpers/Bullet.hpp>
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);
}
}

View File

@ -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)

View File

@ -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());