Merge pull request #2788 from fuchuyuan/generateFaceMesh

Write face mesh to obj and fix rigid transform for softbody
This commit is contained in:
erwincoumans 2020-05-08 13:00:43 -07:00 committed by GitHub
commit b154bf75b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 25 deletions

View File

@ -1046,10 +1046,14 @@ btTransform btSoftBody::getRigidTransform()
btVector3 t = getCenterOfMass();
btMatrix3x3 S;
S.setZero();
// get rotation that minimizes L2 difference: \sum_i || RX_i + t - x_i ||
// Get rotation that minimizes L2 difference: \sum_i || RX_i + t - x_i ||
// It's important to make sure that S has the correct signs.
// SVD is only unique up to the ordering of singular values.
// SVD will manipulate U and V to ensure the ordering of singular values. If all three singular
// vaues are negative, SVD will permute colums of U to make two of them positive.
for (int i = 0; i < m_nodes.size(); ++i)
{
S += OuterProduct(m_X[i], t-m_nodes[i].m_x);
S -= OuterProduct(m_X[i], t-m_nodes[i].m_x);
}
btVector3 sigma;
btMatrix3x3 U,V;

View File

@ -1420,31 +1420,70 @@ void btSoftBodyHelpers::generateBoundaryFaces(btSoftBody* psb)
}
}
//Write the surface mesh to an obj file.
void btSoftBodyHelpers::writeObj(const char* filename, const btSoftBody* psb)
{
std::ofstream fs;
fs.open(filename);
btAssert(fs);
for (int i = 0; i < psb->m_nodes.size(); ++i)
{
fs << "v";
for (int d = 0; d < 3; d++)
{
fs << " " << psb->m_nodes[i].m_x[d];
}
fs << "\n";
}
for (int i = 0; i < psb->m_faces.size(); ++i)
{
fs << "f";
for (int n = 0; n < 3; n++)
{
fs << " " << psb->m_faces[i].m_n[n]->index + 1;
}
fs << "\n";
}
fs.close();
std::ofstream fs;
fs.open(filename);
btAssert(fs);
if (psb->m_tetras.size() > 0)
{
// For tetrahedron mesh, we need to re-index the surface mesh for it to be in obj file/
std::map<int, int> dict;
for (int i = 0; i < psb->m_faces.size(); i++)
{
for (int d = 0; d < 3; d++)
{
int index = psb->m_faces[i].m_n[d]->index;
if (dict.find(index) == dict.end())
{
int dict_size = dict.size();
dict[index] = dict_size;
fs << "v";
for (int k = 0; k < 3; k++)
{
fs << " " << psb->m_nodes[index].m_x[k];
}
fs << "\n";
}
}
}
// Write surface mesh.
for (int i = 0; i < psb->m_faces.size(); ++i)
{
fs << "f";
for (int n = 0; n < 3; n++)
{
fs << " " << dict[psb->m_faces[i].m_n[n]->index] + 1;
}
fs << "\n";
}
}
else
{
// For trimesh, directly write out all the nodes and faces.xs
for (int i = 0; i < psb->m_nodes.size(); ++i)
{
fs << "v";
for (int d = 0; d < 3; d++)
{
fs << " " << psb->m_nodes[i].m_x[d];
}
fs << "\n";
}
for (int i = 0; i < psb->m_faces.size(); ++i)
{
fs << "f";
for (int n = 0; n < 3; n++)
{
fs << " " << psb->m_faces[i].m_n[n]->index + 1;
}
fs << "\n";
}
}
fs.close();
}
void btSoftBodyHelpers::duplicateFaces(const char* filename, const btSoftBody* psb)