Issues turning loaded meshes into cloth simulation - c++

I'm having a bit of issue trying to get meshes I import into my program to have cloth simulation physics using a particle/spring system. I'm kind of a beginner into graphics programming, so sorry if this is super obvious and I'm just missing something. I'm using C++ with OpenGL, as well as Assimp to import the models. I'm fairly sure my code to calculate the constraints/springs and step each particle is correct, as I tested it out with generated meshes (with quads instead of triangles), and it looked fine, but idk.
I've been using this link to study up on how to actually do this: https://nccastaff.bournemouth.ac.uk/jmacey/MastersProjects/MSc2010/07LuisPereira/Thesis/LuisPereira_Thesis.pdf
What it looks like in-engine: https://www.youtube.com/watch?v=RyAan27wryU
I'm pretty sure it's an issue with the connections/springs, as the imported model thats just a flat plane seems to work fine, for the most part. The other model though.. seems to just fall apart. I keep looking at papers on this, and from what I understand everything should be working right, as I connect the edge/bend springs seemingly correctly, and the physics side seems to work from the flat planes. I really can't figure it out for the life of me! Any tips/help would be GREATLY appreciated! :)
Code for processing Mesh into Cloth:
// Container to temporarily hold faces while we process springs
std::vector<Face> faces;
// Go through indices and take the ones making a triangle.
// Indices come from assimp, so i think this is the right thing to do to get each face?
for (int i = 0; i < this->indices.size(); i+=3)
{
std::vector<unsigned int> faceIds = { this->indices.at(i), this->indices.at(i + 1), this->indices.at(i + 2) };
Face face;
face.vertexIDs = faceIds;
faces.push_back(face);
}
// Iterate through faces and add constraints when needed.
for (int l = 0; l < faces.size(); l++)
{
// Adding edge springs.
Face temp = faces[l];
makeConstraint(particles.at(temp.vertexIDs[0]), particles.at(temp.vertexIDs[1]));
makeConstraint(particles.at(temp.vertexIDs[0]), particles.at(temp.vertexIDs[2]));
makeConstraint(particles.at(temp.vertexIDs[1]), particles.at(temp.vertexIDs[2]));
// We need to get the bending springs as well, and i've just written a function to do that.
for (int x = 0; x < faces.size(); x++)
{
Face temp2 = faces[x];
if (l != x)
{
verticesShared(temp, temp2);
}
}
}
And heres the code where I process the bending springs as well:
// Container for any indices the two faces have in common.
std::vector<glm::vec2> traversed;
// Loop through both face's indices, to see if they match eachother.
for (int i = 0; i < a.vertexIDs.size(); i++)
{
for (int k = 0; k < b.vertexIDs.size(); k++)
{
// If we do get a match, we push a vector into the container containing the two indices of the faces so we know which ones are equal.
if (a.vertexIDs.at(i) == b.vertexIDs.at(k))
{
traversed.push_back(glm::vec2(i, k));
}
}
// If we're here, if means we have an edge in common, aka that we have two vertices shared between the two faces.
if (traversed.size() == 2)
{
// Get the adjacent vertices.
int face_a_adj_ind = 3 - ((traversed[0].x) + (traversed[1].x));
int face_b_adj_ind = 3 - ((traversed[0].y) + (traversed[1].y));
// Turn the stored ones from earlier and just get the ACTUAL indices from the face. Indices of indices, eh.
unsigned int adj_1 = a.vertexIDs[face_a_adj_ind];
unsigned int adj_2 = b.vertexIDs[face_b_adj_ind];
// And finally, make a bending spring between the two adjacent particles.
makeConstraint(particles.at(adj_1), particles.at(adj_2));
}
}

Related

Marching Cubes Issues

I've been trying to implement the marching cubes algorithm with C++ and Qt. Anyway, so far all the steps have been written, but I'm getting a really bad result. I'm looking for orientation or advices about what can be going wrong. I suspect one of the problems may be with the voxel conception, specifically about which vertex goes in which corner (0, 1, ..., 7). Also, I'm not a 100% sure about how to interpret the input for the algorithm (I'm using datasets). Should I read it in the ZYX order and move the marching cube in the same way or it doesn't matter at all? (Leaving aside the fact that no every dimension has to have the same size).
Here is what I'm getting against what it should look like...
http://i57.tinypic.com/2nb7g46.jpg
http://en.wikipedia.org/wiki/Marching_cubes
http://en.wikipedia.org/wiki/Marching_cubes#External_links
Paul Bourke. "Overview and source code".
http://paulbourke.net/geometry/polygonise/
Qt_MARCHING_CUBES.zip: Qt/OpenGL example courtesy Dr. Klaus Miltenberger.
http://paulbourke.net/geometry/polygonise/Qt_MARCHING_CUBES.zip
The example requires boost, but looks like it probably should work.
In his example, it has in marchingcubes.cpp, a few different methods for calculating the marching cubes: vMarchCube1 and vMarchCube2.
In the comments it says vMarchCube2 performs the Marching Tetrahedrons algorithm on a single cube by making six calls to vMarchTetrahedron.
Below is the source for the first one vMarchCube1:
//vMarchCube1 performs the Marching Cubes algorithm on a single cube
GLvoid GL_Widget::vMarchCube1(const GLfloat &fX, const GLfloat &fY, const GLfloat &fZ, const GLfloat &fScale, const GLfloat &fTv)
{
GLint iCorner, iVertex, iVertexTest, iEdge, iTriangle, iFlagIndex, iEdgeFlags;
GLfloat fOffset;
GLvector sColor;
GLfloat afCubeValue[8];
GLvector asEdgeVertex[12];
GLvector asEdgeNorm[12];
//Make a local copy of the values at the cube's corners
for(iVertex = 0; iVertex < 8; iVertex++)
{
afCubeValue[iVertex] = (this->*fSample)(fX + a2fVertexOffset[iVertex][0]*fScale,fY + a2fVertexOffset[iVertex][1]*fScale,fZ + a2fVertexOffset[iVertex][2]*fScale);
}
//Find which vertices are inside of the surface and which are outside
iFlagIndex = 0;
for(iVertexTest = 0; iVertexTest < 8; iVertexTest++)
{
if(afCubeValue[iVertexTest] <= fTv) iFlagIndex |= 1<<iVertexTest;
}
//Find which edges are intersected by the surface
iEdgeFlags = aiCubeEdgeFlags[iFlagIndex];
//If the cube is entirely inside or outside of the surface, then there will be no intersections
if(iEdgeFlags == 0)
{
return;
}
//Find the point of intersection of the surface with each edge
//Then find the normal to the surface at those points
for(iEdge = 0; iEdge < 12; iEdge++)
{
//if there is an intersection on this edge
if(iEdgeFlags & (1<<iEdge))
{
fOffset = fGetOffset(afCubeValue[ a2iEdgeConnection[iEdge][0] ],afCubeValue[ a2iEdgeConnection[iEdge][1] ], fTv);
asEdgeVertex[iEdge].fX = fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0] + fOffset * a2fEdgeDirection[iEdge][0]) * fScale;
asEdgeVertex[iEdge].fY = fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1] + fOffset * a2fEdgeDirection[iEdge][1]) * fScale;
asEdgeVertex[iEdge].fZ = fZ + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][2] + fOffset * a2fEdgeDirection[iEdge][2]) * fScale;
vGetNormal(asEdgeNorm[iEdge], asEdgeVertex[iEdge].fX, asEdgeVertex[iEdge].fY, asEdgeVertex[iEdge].fZ);
}
}
//Draw the triangles that were found. There can be up to five per cube
for(iTriangle = 0; iTriangle < 5; iTriangle++)
{
if(a2iTriangleConnectionTable[iFlagIndex][3*iTriangle] < 0) break;
for(iCorner = 0; iCorner < 3; iCorner++)
{
iVertex = a2iTriangleConnectionTable[iFlagIndex][3*iTriangle+iCorner];
vGetColor(sColor, asEdgeVertex[iVertex], asEdgeNorm[iVertex]);
glColor4f(sColor.fX, sColor.fY, sColor.fZ, 0.6);
glNormal3f(asEdgeNorm[iVertex].fX, asEdgeNorm[iVertex].fY, asEdgeNorm[iVertex].fZ);
glVertex3f(asEdgeVertex[iVertex].fX, asEdgeVertex[iVertex].fY, asEdgeVertex[iVertex].fZ);
}
}
}
UPDATE: Github working example, tested
https://github.com/peteristhegreat/qt-marching-cubes
Hope that helps.
Finally, I found what was wrong.
I use a VBO indexer class to reduce the ammount of duplicated vertices and make the render faster. This class is implemented with a std::map to find and discard already existing vertices, using a tuple of < vec3, unsigned short >. As you may imagine, a marching cubes algorithm generates structures with thousands if not millions of vertices. The highest number a common unsigned short can hold is 65536, or 2^16. So, when the output geometry had more than that, the map index started to overflow and the result was a mess, since it started to overwrite vertices with the new ones. I just changed my implementation to draw with common VBO and not indexed while I fix my class to support millions of vertices.
The result, with some minor vertex normal issues, speaks for itself:
http://i61.tinypic.com/fep2t3.jpg

Draw polygon wire in Maya using OpenGL

I'm looking for fast way of drawing polygon wireframe in Maya using openGL. I have a working solution, however it's very slow for complex scenes.
I also have a fast solution using MGeometry and MGeometryPrimitive, however it gives me triangles and I can't see a way to get polygon definition.
I am only interested in points and polygon definition, I don't care about normals, UVs and such.
Here's my working slow solution:
MPointArray points;
for (MItMeshPolygon oPolyIter(object); !oPolyIter.isDone(); oPolyIter.next())
{
gGLFT->glBegin(MGL_LINE_LOOP);
oPolyIter.getPoints(points);
for (unsigned int i = 0; i < points.length(); i++)
gGLFT->glVertex3d(points[i].x, points[i].y, points[i].z);
gGLFT->glEnd();
}
Any ideas or pointers?
After some research, I came up with this solution, which runs considerably faster.
gGLFT->glPolygonMode(MGL_FRONT_AND_BACK, MGL_LINE);
MIntArray verts;
UintArray vertIds;
for (int i = 0 ; i < mesh.numPolygons(); i++)
{
mesh.getPolygonVertices(i, verts);
vertIds.convert(verts);
gGLFT->glDrawElements(GL_POLYGON, verts.length(), GL_UNSIGNED_INT, vertIds.data() );
}

Memory increase rapidly using gluTess*, display list and frame buffer

I'm programming with OpenGL under MSVC 2010.
One of my goal is to pick objects in the scene. I design it in the way like assigning each object a unique color, rendering them in a framebuffer, then reading the color where the cursor is, and the corresponding object can be acquired.
Now the picking is working well. However, as long as a picking happens, the memory increases rapidly. In detail, the following code render objects into a framebuffer:
for (unsigned i = 0; i < objects.size(); ++i)
{
//some code computing color;
Color color;
for (unsigned j = 0; j < objects[i].listOfPrimitives.size(); ++j)
{
objects[i].listOfPrimitives[j]->color = color;
}
objects[i].Render();
for (unsigned j = 0; j < objects[i].listOfPrimitives.size(); ++j)
{
objects[i].listOfPrimitives[j]->color = colorStorage[i][j];
}
}
where objects are objects to be rendered. Since every object has a certain number of primitives(which may be a cylinder, sphere etc.), this piece of code just changes the color of each object's primitives to a unique computed one, render the object, then change it back (colorSotrage stores the original colors). And there are some code in the following to deal with the object, which I'm sure has nothing to do with this issue.
The render method are implemented as following for most object:
glColor3ub(color[0], color[1], color[2]);
glBegin(GL_TRIANGLES);
for (unsigned i = 0; i < mesh.faces.size(); ++i)
{
glNormal3d(mesh.faces[i].normal.x, mesh.faces[i].normal.y, mesh.faces[i].normal.z);
for (unsigned j = 0; j < 3; ++j)
{
glVertex3d(mesh.vertices[mesh.faces[i].verts[j]].x,
mesh.vertices[mesh.faces[i].verts[j]].y,
mesh.vertices[mesh.faces[i].verts[j]].z);
}
}
glEnd();
But for some object, there are some concave polygons (even with holes), so I use the gluTess* group functions in GLU to render them, and to speed up the rendering procedure, I use display list to that part.
Now, as I've mentioned. this picking procedure increases the memory cost rapidly. There are two more phenomenons I can't explain:
If I comment line 8 in the first piece of code, the memory will not change at all when the piece of code runs (of course, this code will not work);
After the memory increases, if I do some refresh to the scene (I design an interactive trackball), the memory will drop off again.
So I'm wondering which part could be the reason of this issue? The display list? the gluTess*() calling? or even something related to framebuffer?

convert a convex path to triangle list

What is the best way to convert a convex path (it is describing in points set) to a list of triangles to be used in opengl render. I think the best stuff is sample code or demo :) thanks!
It sounds like you are looking for one of the many "convert a polygon to a series of triangles" solutions:
Maybe something in one of these will help:
Ear Clipping
List item
poly2tri (with source code)
If you are trying to understand the concepts, the first two are a good place to start.
If you need an implementation, start with the third.
Was this helpful?
If your polygon is really convex and not concave you can just draw it as a triangle fan. That is guaranteed to work.
Here is a alternative recursive algorithm that I wrote a few years ago. It also triangulates a concave polygon and on average generates a much nicer triangulation (e.g. less sliver polygons):
void ConcaveTesselator (unsigned a_NumVertices)
{
unsigned left[32]; // enough space for 2^32 recursions:
unsigned right[32];
unsigned stacktop = 0;
// prepare stack:
left[0] = 0;
right[0] = a_NumVertices-1;
stacktop = 1;
while (stacktop)
{
unsigned l,r,m;
// pop current interval from the stack and subdivide:
stacktop--;
l = left[stacktop];
r = right[stacktop];
m = (l+r)>>1;
// replace this with your triangle drawing function
// or store the indices l,m,r and draw the triangles
// as a triangle list later:
DrawTriangleWithIndices (l,m,r);
// recursive subdivide:
if (m-l > 1)
{
left[stacktop] = l;
right[stacktop] = m;
stacktop++;
}
if (r-m > 1)
{
left[stacktop] = m;
right[stacktop] = r;
stacktop++;
}
}
}

Polygon to Polygon Collision Detection Issue

I have been having a few issues implementing my narrow phase collision detection. Broadphase is working perfectly.
I have a group of polygons, that have a stl::vector array of points for their vertices in clockwise order. Every cycle, I check to see whether they're colliding.
I have borrowed the following Point in Polygon test from here and changed it using my Point data structures:
int InsidePolygon(std::vector <Point> poly, Point p) {
int i, j, c = 0;
int nvert = poly.size();
for (i = 0, j = nvert-1; i < nvert; j = i++) {
if ( ((poly[i].y> p.y) != (poly[j].y> p.y)) && (p.x < (poly[j].x-poly[i].x) * (p.y-poly[i].y) / (poly[j].y-poly[i].y) + poly[i].x) )
c = !c;
}
return c;
}
I have extended that to include a PolygonPolygon function, which check all the points of 1 polygon against another and then reverse it to check the other way around.
int PolygonPolygon(std::vector <Point> polygon1, std::vector <Point> polygon2) {
for(int i=0; i<polygon1.size();i++) {
if(InsidePolygon(polygon2, polygon1[i])) {
return 1;
}
}
for(int j=0; j<polygon2.size();j++) {
if(InsidePolygon(polygon1, polygon2[j])) {
return 1;
}
}
return 0;
}
The strange thing is that my PolygonPolygon function is always returning 1. So I have a few questions:
Have I screwed up the logic somewhere? Should I write my PolygonPolygon function differently?
Are there any better methods for a PolygonPolygon test, the polygons themselves are not guaranteed to be convex, which is why I went for the point in polygon method. I also hope to determine which point is colliding eventually, if I can get past this bit.
Should I be presenting my points in a particular order for the InsidePolygon test?
You may want to consider trying to draw a line between polygons as an alternative collision detection method.
[edit] Oops, I missed the fact that you have non-convex polys in there too. Maybe "Determining if a point lies on the interior of a polygon" would be better? Either that or you could break your non-convex polygons up into convex polygons first.
Also, there's at least one similar question here on StackOverflow.
Thanks for your help guys! But i've managed to sort it out on my own.
The importance of translating your vertices to world space and rotating them should not be overlooked, especially if you're colliding them.