mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-15 00:54:38 +00:00
Center of gravity issues solved
This commit is contained in:
parent
2f0d02ce23
commit
5d845e8f0f
@ -12,7 +12,7 @@ void DynamicMeshSubFilter::initParameterSet(QAction* action,MeshDocument& md, Ri
|
||||
}
|
||||
|
||||
bool DynamicMeshSubFilter::applyFilter(QAction* filter, MeshDocument &md, RichParameterSet& par, vcg::CallBackPos* cb){
|
||||
if(par.getInt("seconds") < 0 || par.getInt("fps") <= 0 || par.getInt("iterations") <= 0 || par.getInt("contacts") <= 0 || par.getFloat("bounciness") < 0.f || par.getFloat("bounciness") > 1.f)
|
||||
if(par.getInt("seconds") < 0 || par.getInt("fps") <= 0 || par.getInt("iterations") <= 0 || par.getInt("contacts") <= 0 || par.getFloat("bounciness") < 0 || par.getFloat("bounciness") > 1)
|
||||
return false;
|
||||
|
||||
if(configurationHasChanged(md, par))
|
||||
@ -45,7 +45,6 @@ bool DynamicMeshSubFilter::configurationHasChanged(MeshDocument& md, RichParamet
|
||||
|
||||
saveMeshState(md);*/
|
||||
|
||||
// Old correctness testing
|
||||
if(md.size() == m_files.size())
|
||||
for(int i = 0; i < m_files.size(); i++)
|
||||
changed |= m_files.at(i) != md.getMesh(i)->fileName;
|
||||
|
||||
@ -6,7 +6,7 @@ MeshSubFilter::MeshSubFilter(){
|
||||
}
|
||||
|
||||
void MeshSubFilter::initParameterSet(QAction* action,MeshDocument& md, RichParameterSet & par){
|
||||
par.addParam(new RichInt("fps", 50, "Frames per second", "The number of times per second the physics simulation is updated"));
|
||||
par.addParam(new RichInt("fps", 100, "Frames per second", "The number of times per second the physics simulation is updated"));
|
||||
par.addParam(new RichInt("iterations", 10, "Physics method iterations", "Number of iterations of the physics iterative method for equation solving"));
|
||||
par.addParam(new RichInt("contacts", 20, "Max contacts", "Maximum number of contact points to generate per object pair"));
|
||||
par.addParam(new RichFloat("bounciness", 0.1f, "Bounciness", "The amount of bounciness of a collision: 0 means the surfaces are not bouncy at all, 1 is the maximum bounciness"));
|
||||
|
||||
@ -29,9 +29,6 @@ void ODEFacade::initialize(){
|
||||
m_world = dWorldCreate();
|
||||
m_space = dSimpleSpaceCreate(0);
|
||||
m_contactGroup = dJointGroupCreate(0);
|
||||
|
||||
/*dWorldSetCFM(m_world, 0.001f);
|
||||
dWorldSetERP(m_world, 0.9f);*/
|
||||
}
|
||||
|
||||
void ODEFacade::clear(MeshDocument& md){
|
||||
@ -56,15 +53,27 @@ void ODEFacade::registerTriMesh(MeshModel& mesh, bool scenery){
|
||||
if(tri::HasPerMeshAttribute(mesh.cm, "physicsID"))
|
||||
return;
|
||||
|
||||
if(mesh.cm.Tr != vcg::Matrix44f::Identity()){
|
||||
vcg::tri::UpdatePosition<CMeshO>::Matrix(mesh.cm, mesh.cm.Tr);
|
||||
mesh.cm.Tr.SetIdentity();
|
||||
}
|
||||
|
||||
tri::Inertia<CMeshO> inertia;
|
||||
inertia.Compute(mesh.cm);
|
||||
Point3f center = mesh.cm.bbox.Center();
|
||||
|
||||
ODEMesh* odeMesh = new ODEMesh();
|
||||
odeMesh->vertices = new dReal[mesh.cm.vert.size()][3];
|
||||
odeMesh->normals = new dReal[mesh.cm.face.size()][3];
|
||||
odeMesh->indices = new dTriIndex[mesh.cm.face.size()][3];
|
||||
odeMesh->centerOfMass[0] = scenery ? 0.f : inertia.CenterOfMass()[0];
|
||||
odeMesh->centerOfMass[1] = scenery ? 0.f : inertia.CenterOfMass()[1];
|
||||
odeMesh->centerOfMass[2] = scenery ? 0.f : inertia.CenterOfMass()[2];
|
||||
|
||||
int i = 0;
|
||||
for(CMeshO::ConstVertexIterator vi = mesh.cm.vert.begin(); vi != mesh.cm.vert.end(); vi++, i++){
|
||||
for(int j = 0; j < 3; j++){
|
||||
odeMesh->vertices[i][j] = vi->P()[j];
|
||||
odeMesh->vertices[i][j] = vi->P()[j] - odeMesh->centerOfMass[j] ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,61 +113,50 @@ void ODEFacade::setAsRigidBody(MeshModel& mesh, bool isRigidBody){
|
||||
tri::Inertia<CMeshO> inertia;
|
||||
inertia.Compute(m_registeredMeshes[index()].first->cm);
|
||||
|
||||
Matrix33f IT;
|
||||
inertia.InertiaTensor(IT);
|
||||
dMassSetParameters(&m_registeredMeshes[index()].second->mass, abs(inertia.Mass()),
|
||||
inertia.CenterOfMass()[0], inertia.CenterOfMass()[1], inertia.CenterOfMass()[2],
|
||||
IT[0][0], IT[1][1], IT[2][2], IT[0][1], IT[0][2], IT[1][2]);
|
||||
//For now it's best to let ODE do the job automatically
|
||||
//dBodySetMass(m_registeredMeshes[index()].second->body, &m_registeredMeshes[index()].second->mass);
|
||||
dMass* mass = &m_registeredMeshes[index()].second->mass;
|
||||
dMassSetTrimesh(mass, 1.0f, m_registeredMeshes[index()].second->geom);
|
||||
mass->mass = 10;
|
||||
|
||||
dReal centerOfMass[3] = { mass->c[0], mass->c[1], mass->c[2] };
|
||||
dMassTranslate(&m_registeredMeshes[index()].second->mass, -centerOfMass[0], -centerOfMass[1], -centerOfMass[2]);
|
||||
dBodySetMass(m_registeredMeshes[index()].second->body, &m_registeredMeshes[index()].second->mass);
|
||||
dBodySetPosition(m_registeredMeshes[index()].second->body, inertia.CenterOfMass()[0], inertia.CenterOfMass()[1], inertia.CenterOfMass()[2]);
|
||||
}
|
||||
|
||||
updateEngineTransform(mesh);
|
||||
}
|
||||
|
||||
void ODEFacade::updateEngineTransform(MeshModel& mesh){
|
||||
if(!tri::HasPerMeshAttribute(mesh.cm, "physicsID"))
|
||||
return;
|
||||
|
||||
MeshIndex index = tri::Allocator<CMeshO>::GetPerMeshAttribute<unsigned int>(mesh.cm, "physicsID");
|
||||
|
||||
Point3<float> trans = mesh.cm.Tr.GetColumn3(3);
|
||||
dGeomSetPosition(m_registeredMeshes[index()].second->geom, trans.X(), trans.Y(), trans.Z());
|
||||
|
||||
dMatrix3 rotationMatrix;
|
||||
|
||||
rotationMatrix[0] = mesh.cm.Tr[0][0];
|
||||
rotationMatrix[1] = mesh.cm.Tr[0][1];
|
||||
rotationMatrix[2] = mesh.cm.Tr[0][2];
|
||||
rotationMatrix[3] = 0.f;
|
||||
rotationMatrix[4] = mesh.cm.Tr[1][0];
|
||||
rotationMatrix[5] = mesh.cm.Tr[1][1];
|
||||
rotationMatrix[6] = mesh.cm.Tr[1][2];
|
||||
rotationMatrix[7] = 0.f;
|
||||
rotationMatrix[8] = mesh.cm.Tr[2][0];
|
||||
rotationMatrix[9] = mesh.cm.Tr[2][1];
|
||||
rotationMatrix[10] = mesh.cm.Tr[2][2];
|
||||
rotationMatrix[11] = 0.f;
|
||||
|
||||
dGeomSetRotation(m_registeredMeshes[index()].second->geom, rotationMatrix);
|
||||
}
|
||||
|
||||
void ODEFacade::updateTransform(){
|
||||
for(MeshContainer::iterator i = m_registeredMeshes.begin(); i != m_registeredMeshes.end(); i++){
|
||||
const dReal* position = dGeomGetPosition(i->second->geom);
|
||||
i->first->cm.Tr.SetTranslate(position[0], position[1], position[2]);
|
||||
const dReal* position = 0;
|
||||
const dReal* rotation = 0;
|
||||
|
||||
if(i->second->body != 0){
|
||||
position = dBodyGetPosition(i->second->body);
|
||||
rotation = dBodyGetRotation(i->second->body);
|
||||
}else{
|
||||
position = dGeomGetPosition(i->second->geom);
|
||||
rotation = dGeomGetRotation(i->second->geom);
|
||||
}
|
||||
|
||||
const dReal* rotation = dGeomGetRotation(i->second->geom);
|
||||
i->first->cm.Tr[0][0] = rotation[0];
|
||||
i->first->cm.Tr[0][1] = rotation[1];
|
||||
i->first->cm.Tr[0][2] = rotation[2];
|
||||
i->first->cm.Tr[0][3] = position[0];
|
||||
i->first->cm.Tr[1][0] = rotation[4];
|
||||
i->first->cm.Tr[1][1] = rotation[5];
|
||||
i->first->cm.Tr[1][2] = rotation[6];
|
||||
i->first->cm.Tr[1][3] = position[1];
|
||||
i->first->cm.Tr[2][0] = rotation[8];
|
||||
i->first->cm.Tr[2][1] = rotation[9];
|
||||
i->first->cm.Tr[2][2] = rotation[10];
|
||||
i->first->cm.Tr[2][3] = position[2];
|
||||
i->first->cm.Tr[3][0] = 0.f;
|
||||
i->first->cm.Tr[3][1] = 0.f;
|
||||
i->first->cm.Tr[3][2] = 0.f;
|
||||
i->first->cm.Tr[3][3] = 1.f;
|
||||
|
||||
vcg::Matrix44f m;
|
||||
m.SetTranslate(-i->second->centerOfMass[0], -i->second->centerOfMass[1], -i->second->centerOfMass[2]);
|
||||
i->first->cm.Tr *= m;
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,12 +181,6 @@ void ODEFacade::collisionCallback(dGeomID o1, dGeomID o2){
|
||||
m_contacts[i].surface.bounce = m_bounciness;
|
||||
m_contacts[i].surface.bounce_vel = 0.1;
|
||||
m_contacts[i].surface.soft_cfm = 0.01;
|
||||
/*m_contacts[i].surface.mode = dContactBounce | dContactSoftCFM;
|
||||
m_contacts[i].surface.mu = dInfinity;
|
||||
m_contacts[i].surface.mu2 = 0;
|
||||
m_contacts[i].surface.bounce = 0.1;
|
||||
m_contacts[i].surface.bounce_vel = 0.1;
|
||||
m_contacts[i].surface.soft_cfm = 0.01;*/
|
||||
}
|
||||
|
||||
int collisions = dCollide(o1, o2, m_contacts.size(), &m_contacts[0].geom, sizeof(dContact));
|
||||
@ -205,8 +197,16 @@ vcg::Matrix44f ODEFacade::getTransformationMatrix(MeshModel& mesh){
|
||||
MeshIndex index = tri::Allocator<CMeshO>::GetPerMeshAttribute<unsigned int>(mesh.cm, "physicsID");
|
||||
|
||||
vcg::Matrix44f matrix;
|
||||
const dReal* position = dGeomGetPosition(m_registeredMeshes[index()].second->geom);
|
||||
const dReal* rotation = dGeomGetRotation(m_registeredMeshes[index()].second->geom);
|
||||
const dReal* position = 0;
|
||||
const dReal* rotation = 0;
|
||||
|
||||
if(m_registeredMeshes[index()].second->body != 0){
|
||||
position = dBodyGetPosition(m_registeredMeshes[index()].second->body);
|
||||
rotation = dBodyGetRotation(m_registeredMeshes[index()].second->body);
|
||||
}else{
|
||||
position = dGeomGetPosition(m_registeredMeshes[index()].second->geom);
|
||||
rotation = dGeomGetRotation(m_registeredMeshes[index()].second->geom);
|
||||
}
|
||||
|
||||
matrix[0][0] = rotation[0];
|
||||
matrix[0][1] = rotation[1];
|
||||
@ -225,7 +225,10 @@ vcg::Matrix44f ODEFacade::getTransformationMatrix(MeshModel& mesh){
|
||||
matrix[3][2] = 0.f;
|
||||
matrix[3][3] = 1.f;
|
||||
|
||||
return matrix;
|
||||
vcg::Matrix44f m;
|
||||
m.SetTranslate(-m_registeredMeshes[index()].second->centerOfMass[0], -m_registeredMeshes[index()].second->centerOfMass[1], -m_registeredMeshes[index()].second->centerOfMass[2]);
|
||||
|
||||
return matrix * m;
|
||||
}
|
||||
|
||||
void ODEFacade::setIterations(int iterations){
|
||||
|
||||
@ -52,6 +52,7 @@ protected:
|
||||
dTriMeshDataID data;
|
||||
dReal (*vertices)[3];
|
||||
dReal (*normals)[3];
|
||||
dReal centerOfMass[3];
|
||||
dTriIndex (*indices)[3];
|
||||
};
|
||||
|
||||
@ -60,7 +61,6 @@ protected:
|
||||
|
||||
static void collisionCallback(void* data, dGeomID o1, dGeomID o2);
|
||||
void collisionCallback(dGeomID o1, dGeomID o2);
|
||||
void updateEngineTransform(MeshModel& mesh);
|
||||
|
||||
//This class is a monostate
|
||||
static bool m_initialized;
|
||||
|
||||
@ -32,7 +32,7 @@ class FilterPhysics : public QObject, public MeshFilterInterface
|
||||
virtual QString filterInfo(FilterIDType filter) const;
|
||||
|
||||
virtual int getRequirements(QAction*){return MeshModel::MM_FACEVERT | MeshModel::MM_FACENORMAL;}
|
||||
virtual int postCondition( QAction* ) const{return MeshModel::MM_TRANSFMATRIX;}
|
||||
virtual int postCondition( QAction* ) const{return MeshModel::MM_FACENORMAL; /*MeshModel::MM_TRANSFMATRIX; */}
|
||||
|
||||
virtual bool autoDialog(QAction*) {return true;}
|
||||
virtual void initParameterSet(QAction*, MeshDocument&, RichParameterSet&);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user