WIP JointService; make & break joints functions
This commit is contained in:
parent
bdc8ad0305
commit
0fc6b0cb54
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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; };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue