NVIDIAGameWorks / FleX

Other
664 stars 100 forks source link

Can't create double sided flag #27

Open Hurleyworks opened 6 years ago

Hurleyworks commented 6 years ago

Howdy,

I'm trying to create a cloth flag from a render mesh. The mesh is 2D and it's vertices are all unique but it has coincident triangles for separate front and back surfaces.. My call to NvFlexExtCreateClothFromMesh() always returns a nullptr.

Here's the code I'm using. Am I doing something wrong or are double sided meshes not supported in Flex?

-Steve

Mesh* mesh = ImportMesh(GetFilePathByPlatform("../../data/double_sided_flag.obj").c_str());
Vec3 lower, upper;
mesh->GetBounds(lower, upper);

const int pointCount = mesh->GetNumVertices();
int * uniqueVerts = new int[pointCount];
int * uniqueMap = new int[pointCount];

int count = NvFlexExtCreateWeldedMeshIndices((float*)&mesh->m_positions[0], pointCount, uniqueVerts, uniqueMap,std::numeric_limits<float>::epsilon());

int indexCount = mesh->m_indices.size();
for (int i = 0; i < indexCount; i++)
{
    int index = mesh->m_indices[i];
    mesh->m_indices[i] = uniqueVerts[uniqueMap[index]];
}

delete[] uniqueVerts;
delete[] uniqueMap;

for (size_t i = 0; i < mesh->GetNumVertices(); ++i)
{
    Vec3 p = Vec3(mesh->m_positions[i]);

    float invMass = 1.0f;

    // add contraints to left side top and bottom
    if (p.x == lower.x && (p.y == upper.y || p.y == lower.y))
    { 
        invMass = 0.0f;
    }

    g_buffers->positions.push_back(Vec4(p.x, p.y, p.z, invMass));
    g_buffers->velocities.push_back(0.0f);
    g_buffers->phases.push_back(phase);
}

float tetherStiffness = 0.5;
float tetherGive = 0.01f;
float pressure = 0.0f; 

NvFlexExtAsset * const cloth = NvFlexExtCreateClothFromMesh((float*)&g_buffers->positions[0],
int(g_buffers->positions.size()),
(int*)&mesh->m_indices[0],
mesh->GetNumFaces(),
stretchStiffness,
bendStiffness,
tetherStiffness,
tetherGive, pressure);

if (!cloth) return;
Hurleyworks commented 6 years ago

Oops. I forgot that the extensions are open source too. :)

I can see that NvFlexExtCreateClothFromMesh() constructs a tearable Cloth by default and that requires triangles with unique edges so that's why my mesh fails.

But if I construct a non tearable Cloth, the flag mesh is not rendered properly.