Optimize cloth simulation

master
Jeremy Hu 2020-01-18 15:31:10 +09:30
parent 2e047e3d26
commit a7f22efd1b
2 changed files with 15 additions and 5 deletions

View File

@ -873,14 +873,17 @@ bool MeshGenerator::componentRemeshed(const std::map<QString, QString> *componen
{ {
if (nullptr == component) if (nullptr == component)
return false; return false;
bool isCloth = false;
if (ComponentLayer::Cloth == ComponentLayerFromString(valueOfKeyInMapOrEmpty(*component, "layer").toUtf8().constData())) { if (ComponentLayer::Cloth == ComponentLayerFromString(valueOfKeyInMapOrEmpty(*component, "layer").toUtf8().constData())) {
if (nullptr != polyCountValue) if (nullptr != polyCountValue)
*polyCountValue = PolyCountToValue(PolyCount::UltraHighPoly); *polyCountValue = PolyCountToValue(PolyCount::UltraHighPoly);
return true; isCloth = true;
} }
auto polyCount = PolyCountFromString(valueOfKeyInMapOrEmpty(*component, "polyCount").toUtf8().constData()); auto polyCount = PolyCountFromString(valueOfKeyInMapOrEmpty(*component, "polyCount").toUtf8().constData());
if (nullptr != polyCountValue) if (nullptr != polyCountValue)
*polyCountValue = PolyCountToValue(polyCount); *polyCountValue = PolyCountToValue(polyCount);
if (isCloth)
return true;
return polyCount != PolyCount::Original; return polyCount != PolyCount::Original;
} }

View File

@ -36,19 +36,26 @@ public:
std::vector<QVector3D> &filteredClothVertices = clothMesh->vertices; std::vector<QVector3D> &filteredClothVertices = clothMesh->vertices;
std::vector<QVector3D> externalForces; std::vector<QVector3D> externalForces;
std::vector<QVector3D> postProcessDirections;
const auto &clothForce = clothMesh->clothForce; const auto &clothForce = clothMesh->clothForce;
float clothOffset = 0.015f + (clothMesh->clothOffset * 0.05f); float clothOffset = 0.01f + (clothMesh->clothOffset * 0.05f);
if (ClothForce::Centripetal == clothForce) { if (ClothForce::Centripetal == clothForce) {
externalForces.resize(filteredClothVertices.size()); externalForces.resize(filteredClothVertices.size());
postProcessDirections.resize(filteredClothVertices.size());
for (size_t i = 0; i < filteredClothFaces.size(); ++i) { for (size_t i = 0; i < filteredClothFaces.size(); ++i) {
const auto &face = filteredClothFaces[i]; const auto &face = filteredClothFaces[i];
auto faceForceDirection = -polygonNormal(filteredClothVertices, face); auto faceForceDirection = -polygonNormal(filteredClothVertices, face);
for (const auto &vertex: face) for (const auto &vertex: face)
externalForces[vertex] += faceForceDirection; externalForces[vertex] += faceForceDirection;
} }
for (auto &it: externalForces) for (size_t i = 0; i < externalForces.size(); ++i) {
it = (it.normalized() + QVector3D(0.0f, -1.0f, 0.0f)).normalized(); auto &it = externalForces[i];
it.normalize();
postProcessDirections[i] = it * clothOffset;
it = (it + QVector3D(0.0f, -1.0f, 0.0f)).normalized();
}
} else { } else {
postProcessDirections.resize(filteredClothVertices.size(), QVector3D(0.0f, -1.0f, 0.0f) * clothOffset);
externalForces.resize(filteredClothVertices.size(), QVector3D(0.0f, -1.0f, 0.0f)); externalForces.resize(filteredClothVertices.size(), QVector3D(0.0f, -1.0f, 0.0f));
} }
ClothSimulator clothSimulator(filteredClothVertices, ClothSimulator clothSimulator(filteredClothVertices,
@ -62,7 +69,7 @@ public:
clothSimulator.step(); clothSimulator.step();
clothSimulator.getCurrentVertices(&filteredClothVertices); clothSimulator.getCurrentVertices(&filteredClothVertices);
for (size_t i = 0; i < filteredClothVertices.size(); ++i) { for (size_t i = 0; i < filteredClothVertices.size(); ++i) {
filteredClothVertices[i] -= externalForces[i] * clothOffset; filteredClothVertices[i] -= postProcessDirections[i];
} }
} }
void operator()(const tbb::blocked_range<size_t> &range) const void operator()(const tbb::blocked_range<size_t> &range) const