• Create Account

# BlueSpud

Member Since 17 Jul 2013
Offline Last Active Mar 01 2014 08:56 PM

### Mesh - Elipse Collision Detection and Response Problem

05 February 2014 - 03:27 PM

Hi,

So for hours Ive been working on collision detection with triangle meshes and ellipses. The paper I've been using for reference can be found here:

http://www.peroxide.dk/papers/collision/collision.pdf

After a few hours of toiling, I've gotten the collision detection piece working pretty well, I just haven't implemented the collision detection for checking the edges, but this shouldn't be effecting the collision results when it is ellipse to triangle collision. When it comes to the response step, the thing just kind of falls apart. It kind of works, but it seems to be moving the ellipse back away from the triangle as well as sliding it, so obviously something is wrong. I've read the papers several times over and tried many different things, but I haven't been able to figure out quite whats going on with this strange problem. Here is the assorted code that goes with the collision detection and response:

The detection code, this is run for each mesh and then the results are reported back to the physics class

```bool physicsObject::onSameSide(glm::vec3 point, glm::vec3 p1, glm::vec3 p2, glm::vec3 p3)
{
glm::vec3 cross1 = glm::cross(p3-p2, point-p2);
glm::vec3 cross2 = glm::cross(p3-p2, p1-p2);
if (glm::dot(cross1, cross2) >= 0.0)
return  true;
else return false;

}
collisionResponsePacket physicsObject::checkTriangle(unsigned int i)
{
collisionResponsePacket packetToReturn;
glm::vec3 velocity = playerESpace.vecInElipsoidSpace( glm::vec3(-camx,-camy,-camz)-glm::vec3(-lcamx,-lcamy,-lcamz));
glm::vec3 basePos = playerESpace.vecInElipsoidSpace(glm::vec3(-lcamx,-lcamy,-lcamz));

//for now, we're just going to check the one triangle.
//.obj stores vertexes in counter-clockwise order, so we're going to swap the positions.
glm::vec3 p1 =playerESpace.vecInElipsoidSpace( (glm::vec3(ModelRegistry.models[model].m.obj[i].x3,ModelRegistry.models[model].m.obj[i].y3,ModelRegistry.models[model].m.obj[i].z3)));
glm::vec3 p2 = playerESpace.vecInElipsoidSpace((glm::vec3(ModelRegistry.models[model].m.obj[i].x2,ModelRegistry.models[model].m.obj[i].y2,ModelRegistry.models[model].m.obj[i].z2)));
glm::vec3 p3 = playerESpace.vecInElipsoidSpace((glm::vec3(ModelRegistry.models[model].m.obj[i].x1,ModelRegistry.models[model].m.obj[i].y1,ModelRegistry.models[model].m.obj[i].z1)));

//get the normal
glm::vec3 normal  = glm::normalize(glm::cross(p2-p1, p3-p1));

//get signed distance
float distance = glm::dot(normal, basePos) - ((normal.x*p1.x)+(normal.y*p1.y)+(normal.z*p1.z));
if (abs(distance) < 2)
{
//normal dot velocity
float ndv = glm::dot(normal, velocity);
//times of intersection
float time1 = (1.0f - distance)/ndv;
float time2 = (-1.0f - distance)/ndv;

if (time1 > time2)
{
float temp = time2;
time2 = time1;
time1 = temp;
}
if (time1 > 1.0 || time2 < 0.0)
{
//do something to say there wasn't a collision here
}
else
{
if (time2 > 1)
time2 = 1;
if (time1 < 0.0)
time1 = 0;

//get the point where we think that the sphere is going to collide
glm::vec3 intersectionPoint = (basePos  + (time1*velocity*(float)0.95)) - normal;

//now we need to check if this collided
if (onSameSide(intersectionPoint, p1, p2, p3) && onSameSide(intersectionPoint, p2, p1, p3) && onSameSide(intersectionPoint, p3, p1, p2))
{
//there was a collision inside the triangle, so wer're done here.
packetToReturn.intersectionPoint = intersectionPoint;
packetToReturn.time0 = time1;
packetToReturn.time1 = time2;
packetToReturn.collided = true;

}
else
{
//temp, I just want to be able to check more complex meshes
return packetToReturn;
//there wasn't a collision inside the triangle so now for the fin stuff, we get to check the collision for the edges and points.
//this is also called the sweep test

//first we check collisions with the vertexes
}
}
}
return packetToReturn;
}

void physicsObject::testCollisionMeshWithElipsoid(double time)
{
//some of the vectors we require for the response
glm::vec3 velocity = playerESpace.vecInElipsoidSpace( glm::vec3(-camx,-camy,-camz)-glm::vec3(-lcamx,-lcamy,-lcamz));
std::vector<collisionResponsePacket>results;

for (int i = 0; i < ModelRegistry.models[model].m.obj.size(); i++)
//we chech each triangle
results.push_back(checkTriangle(i));

float closest = 0;
int triangle = 0;
bool initial = false;
//now we find which one we are going to respond against, then do it
for (int i = 0; i < results.size(); i++)
{
if (results[i].collided == true)
{

//get the distance to the collision
float distanceToCollision = results[0].time0*glm::length(velocity);
if (initial == false || distanceToCollision < closest )
{
//this one was less than the previos one
initial = true;
closest = distanceToCollision;
triangle = i;
}

}
}
//we store the information for the closest collision here
closestResults.i = triangle;
closestResults.distance = closest;
closestResults.packet = results[triangle];
results.clear();

}
```

The response code:

```void physics::collisions()
{
if (pysObjs.size() > 0)
{
//here we're going to test all the collision objects and apply the collision response to the nearest collision
glm::vec3 velocity = playerESpace.vecInElipsoidSpace( glm::vec3(-camx,-camy,-camz)-glm::vec3(-lcamx,-lcamy,-lcamz));
glm::vec3 basePos = playerESpace.vecInElipsoidSpace(glm::vec3(-lcamx,-lcamy,-lcamz));
glm::vec3 destination = playerESpace.vecInElipsoidSpace(glm::vec3(-camx,-camy,-camz));
int object = 0;
float distance = 0;
bool initial = false;
std::vector<collisionResultsPacket>results;
for (int i = 0; i < pysObjs.size(); i++)
{
//we need to test each mesh and see which is the closest triangle from all the meshes
pysObjs[i].testCollisionMeshWithElipsoid(0);
//we just got the closest result for that mesh
//now we test if that is closer than the one we already have
if (initial == false || pysObjs[i].closestResults.distance < distance )
{
initial = true;
distance = pysObjs[i].closestResults.distance;
object = i;
}
}

//now we have the colsest collision point and we can calculate the collision response properly
if (pysObjs[object].closestResults.packet.collided == true)
{
glm::vec3 newPosition = basePos + (glm::normalize(velocity)*(pysObjs[object].closestResults.distance - 0.005f));
glm::vec3 intersectionPoint = pysObjs[object].closestResults.packet.intersectionPoint; //- (glm::normalize(velocity)*0.005f);
glm::vec3 slingingPlaneOrigin = intersectionPoint;
glm::vec3 slidingPlaneNormal = glm::normalize(newPosition - intersectionPoint);
float distanceCollision = glm::dot(slidingPlaneNormal, destination) - ((slidingPlaneNormal.x*slingingPlaneOrigin.x)+(slidingPlaneNormal.y*slingingPlaneOrigin.y)+(slidingPlaneNormal.z*slingingPlaneOrigin.z));
destination = destination - (distanceCollision)*slidingPlaneNormal;

//convert the new point back into what the camera will take
lcamx = -intersectionPoint.x*ELIPSE_X;
lcamy = -intersectionPoint.y*ELIPSE_Y;
lcamz = -intersectionPoint.z*ELIPSE_Z;
//now we can update everything
camx = -destination.x*ELIPSE_X;
camz = -destination.z*ELIPSE_Z;
camy = -destination.y*ELIPSE_Y;
}

}
}
```

I've been working at this for hours, and if theres some obvious or not so obvious mistake in here, I would greatly appreciate anyone pointing it out. Thanks.

### Questions about mesh rendering performance

11 December 2013 - 01:48 PM

Hello,

I've been working on my mesh rendering lately for my game engine and with large models I have run into problems. I know that the best thing in OpenGL is to avoid state changes to improve performance. With the model I was rendering, with one solid texture, I was getting ~35-40 fps. After I added multi texturing, I get  ~25-28. I'm using draw lists and here is my code:

```//make the list
int materiali = 0;
list = glGenLists(1);
glNewList(list, GL_COMPILE);
glBegin(GL_TRIANGLES);
for (int i = 0; i < ModelRegistry.models[m].m.obj.size(); i++)
{
if (i == ModelRegistry.models[m].m.materialFaces[materiali].i)
{
//we have a texture change here
for (int i = 0; i < Materials.size(); i++)
{

if  (strcmp( ModelRegistry.models[m].m.materialFaces[materiali].name.c_str(), Materials[i].name.c_str()) == 0)
{
materiali++;
if (strcmp( lastMaterial.c_str(), Materials[i].name.c_str()) != 0)
{
glEnd();
lastMaterial = Materials[i].name;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Materials[i].textureID);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specularID);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, normalID);
glBegin(GL_TRIANGLES);
}
break;
}
}

}
glNormal3f(ModelRegistry.models[m].m.obj[i].nx1, ModelRegistry.models[m].m.obj[i].ny1, ModelRegistry.models[m].m.obj[i].nz1);
glTexCoord2f(ModelRegistry.models[m].m.obj[i].tx1, ModelRegistry.models[m].m.obj[i].ty1);
glVertex3f(ModelRegistry.models[m].m.obj[i].x1,ModelRegistry.models[m].m.obj[i].y1,ModelRegistry.models[m].m.obj[i].z1);
glNormal3f(ModelRegistry.models[m].m.obj[i].nx2, ModelRegistry.models[m].m.obj[i].ny2, ModelRegistry.models[m].m.obj[i].nz2);
glTexCoord2f(ModelRegistry.models[m].m.obj[i].tx2, ModelRegistry.models[m].m.obj[i].ty2);
glVertex3f(ModelRegistry.models[m].m.obj[i].x2,ModelRegistry.models[m].m.obj[i].y2,ModelRegistry.models[m].m.obj[i].z2);
glNormal3f(ModelRegistry.models[m].m.obj[i].nx3, ModelRegistry.models[m].m.obj[i].ny3, ModelRegistry.models[m].m.obj[i].nz3);
glTexCoord2f(ModelRegistry.models[m].m.obj[i].tx3, ModelRegistry.models[m].m.obj[i].ty3);
glVertex3f(ModelRegistry.models[m].m.obj[i].x3,ModelRegistry.models[m].m.obj[i].y3,ModelRegistry.models[m].m.obj[i].z3);

}
glEnd();
glEndList();

```

Here are my questions, they should be fairly basic, even if you don't understand the code.

Can new textures be bound inside glBegin() ?

Is there anything faster than glBindTexture() ?

Is the accessing data from the std::vector slowing down the rendering?

Does the GPU have to go through the for loop every time the list is called?

Those are other questions, but I think those are the big ones. Any input would be appreciated because the visual result of the rendering is great, just the frame rate isn't. Thanks.

### Collision Response Jerky

14 November 2013 - 06:20 PM

I've been implementing the collision detection and response detailed in this paper:http://www.peroxide.dk/papers/collision/collision.pdf I've got it mostly working now, but the collision response is a bit jumpy. I've only implemented collision inside the triangle but for what I've testing it against, it doesn't make a difference. Here is my code:

```bool physicsObject::onSameSide(glm::vec3 point, glm::vec3 p1, glm::vec3 p2, glm::vec3 p3)
{
glm::vec3 cross1 = glm::cross(p3-p2, point-p2);
glm::vec3 cross2 = glm::cross(p3-p2, p1-p2);
if (glm::dot(cross1, cross2) >= 0.0)
return true;
else return false;

}

collisionResponsePacket physicsObject::checkTriangle(unsigned int i)
{
collisionResponsePacket packetToReturn;
glm::vec3 velocity = playerESpace.vecInElipsoidSpace( glm::vec3(-camx,-camy,-camz)-glm::vec3(-lcamx,-lcamy,-lcamz));
glm::vec3 basePos = playerESpace.vecInElipsoidSpace(glm::vec3(-lcamx,-lcamy,-lcamz));

//for now, we're just going to check the one triangle.
//.obj stores vertexes in counter-clockwise order, so we're going to swap the positions.
glm::vec3 p1 =playerESpace.vecInElipsoidSpace( (glm::vec3(ModelRegistry.models[model].m.obj[i].x3,ModelRegistry.models[model].m.obj[i].y3,ModelRegistry.models[model].m.obj[i].z3)));
glm::vec3 p2 = playerESpace.vecInElipsoidSpace((glm::vec3(ModelRegistry.models[model].m.obj[i].x2,ModelRegistry.models[model].m.obj[i].y2,ModelRegistry.models[model].m.obj[i].z2)));
glm::vec3 p3 = playerESpace.vecInElipsoidSpace((glm::vec3(ModelRegistry.models[model].m.obj[i].x1,ModelRegistry.models[model].m.obj[i].y1,ModelRegistry.models[model].m.obj[i].z1)));

//get the normal
glm::vec3 normal = glm::normalize(glm::cross(p2-p1, p3-p1));

//get signed distance
float distance = glm::dot(normal, basePos) - ((normal.x*p1.x)+(normal.y*p1.y)+(normal.z*p1.z));
//normal dot velocity
float ndv = glm::dot(normal, velocity);
//times of intersection
float time1 = (1.0 - distance)/ndv;
float time2 = (-1.0 - distance)/ndv;

if (time1 > time2)
{
float temp = time2;
time2 = time1;
time1 = temp;
}
if (time1 > 1.0 || time2 < 0.0)
{
//do something to say there wasn't a collision here
}
else
{
if (time2 > 10)
time2 = 0;
if (time1 < 0.0)
time1 = 0;

//get the point where we think that the sphere is going to collide
glm::vec3 intersectionPoint = (basePos + (time1*velocity*(float)0.95)) - normal;

//now we need to check if this collided
if (onSameSide(intersectionPoint, p1, p2, p3) && onSameSide(intersectionPoint, p2, p1, p3) && onSameSide(intersectionPoint, p3, p1, p2))
{
//there was a collision inside the triangle, so wer're done here.
packetToReturn.intersectionPoint = intersectionPoint;
packetToReturn.time0 = time1;
packetToReturn.time1 = time2;
packetToReturn.collided = true;
}
else
{
//temp, I just want to be able to check more complex meshes
return packetToReturn;
//there wasn't a collision inside the triangle so now for the fin stuff, we get to check the collision for the edges and points.
//this is also called the sweep test

//first we check collisions with the vertexes
}
}

return packetToReturn;
}

void physicsObject::testCollisionMeshWithElipsoid(double time)
{
//some of the vectors we require for the response
glm::vec3 velocity = playerESpace.vecInElipsoidSpace( glm::vec3(-camx,-camy,-camz)-glm::vec3(-lcamx,-lcamy,-lcamz));
glm::vec3 basePos = playerESpace.vecInElipsoidSpace(glm::vec3(-lcamx,-lcamy,-lcamz));
glm::vec3 destination = playerESpace.vecInElipsoidSpace(glm::vec3(-camx,-camy,-camz));

std::vector<collisionResponsePacket>results;
for (int i = 0; i < ModelRegistry.models[model].m.obj.size(); i++)
//we chech each triangle
results.push_back(checkTriangle(i));

//now we find which one we are going to respond against, then do it
for (int i = 0; i < results.size(); i++)
{
if (results[i].collided == true)
{

//we found the droids we are looking for ;)
glm::vec3 newPosition = basePos + (velocity*results[i].time0*0.9f);
glm::vec3 intersectionPoint = results[i].intersectionPoint - (velocity*results[i].time0*0.9f);
glm::vec3 slingingPlaneOrigin = intersectionPoint;
glm::vec3 slidingPlaneNormal = glm::normalize(newPosition - intersectionPoint);
float distance = glm::dot(slidingPlaneNormal, destination) - ((slidingPlaneNormal.x*slingingPlaneOrigin.x)+(slidingPlaneNormal.y*slingingPlaneOrigin.y)+(slidingPlaneNormal.z*slingingPlaneOrigin.z));
destination = destination - (distance)*slidingPlaneNormal;

//convert the new point back into what the camera will take
// lcamx = results[i].intersectionPoint.x;
//lcamy = results[i].intersectionPoint.y;
//lcamz = results[i].intersectionPoint.z;
//now we can update everything
camx = -destination.x*ELIPSE_X;
camz = -destination.z*ELIPSE_Z;
camy = -destination.y*ELIPSE_Y;

break;
}
}
results.clear();
}```

I know its very inefficient, but I want the functionality there first. I've looked at the sample code in the paper but I haven't been able to work out whats wrong. I'm not recursing, but when I do, the camera warps to different places. What I want to know what is wrong with the length of the velocities, etc that would cause this kind of problem. Any help or information would be appreciated.

EDIT:

I've tried dividing the distance variable, this one: "destination - (distance)*slidingPlaneNormal;" and that seems to smooth it out but it seems to cause inaccuracies in the response and causing the camera to clip through the world.

### Display lists not really giving a performance boost

22 October 2013 - 01:42 PM

Hello,

Recently, I've been stress testing my game engine after implementing my deferred renderer. I loaded in the Sponza model that Crytech provides for testing lighting in Cry Engine, even though many people use it for their own engines. The engine could handle one pass of the model at about  30 fps. So I popped into my 3D modeler and it was able to render 3 passes real time just fine. I also tried it in blender as well. I started to clock the different parts of the rendering and the lighting takes little to no time to do. I'm using FBOs, but I don't thing that would effect speed. I looked into ways to optimize mesh rendering and found display lists are the fastest. After putting them in, I didn't get much of a boost in fps. In the openGl settings of my 3D program, there is an option to use display lists, and I have it on so this left me puzzled. I've looked for a while now to find a solution, changing the state less often, etc. but nothing. So here is my code to create the display list:

``` list = glGenLists(1);
glNewList(list, GL_COMPILE);
for (int i = 0; i < ModelRegistry.models[m].m.obj.size(); i++)
{
glBegin(GL_TRIANGLES);
glNormal3f(ModelRegistry.models[m].m.obj[i].nx1, ModelRegistry.models[m].m.obj[i].ny1, ModelRegistry.models[m].m.obj[i].nz1);
glTexCoord2f(ModelRegistry.models[m].m.obj[i].tx1, ModelRegistry.models[m].m.obj[i].ty1);
glVertex3f(ModelRegistry.models[m].m.obj[i].x1,ModelRegistry.models[m].m.obj[i].y1,ModelRegistry.models[m].m.obj[i].z1);
glNormal3f(ModelRegistry.models[m].m.obj[i].nx2, ModelRegistry.models[m].m.obj[i].ny2, ModelRegistry.models[m].m.obj[i].nz2);
glTexCoord2f(ModelRegistry.models[m].m.obj[i].tx2, ModelRegistry.models[m].m.obj[i].ty2);
glVertex3f(ModelRegistry.models[m].m.obj[i].x2,ModelRegistry.models[m].m.obj[i].y2,ModelRegistry.models[m].m.obj[i].z2);
glNormal3f(ModelRegistry.models[m].m.obj[i].nx3, ModelRegistry.models[m].m.obj[i].ny3, ModelRegistry.models[m].m.obj[i].nz3);
glTexCoord2f(ModelRegistry.models[m].m.obj[i].tx3, ModelRegistry.models[m].m.obj[i].ty3);
glVertex3f(ModelRegistry.models[m].m.obj[i].x3,ModelRegistry.models[m].m.obj[i].y3,ModelRegistry.models[m].m.obj[i].z3);
glEnd();
}
glEndList();

```

And here is my rendering code:

```void object::renderObjectWithProgram(GLuint program)
{
//default values for the textures
glUniform1i(glGetUniformLocation(program,"texture"),0);
glUniform1i(glGetUniformLocation(program,"specularTexture"),1);
glUniform1i(glGetUniformLocation(program,"normalTexture"),2);

renderCamera();
glUseProgram(program);
glScalef(scaleFloat, scaleFloat, scaleFloat);
glTranslatef(-x, -y, -z);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specularID);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, normalID);

glDisable(GL_LIGHTING);
/*
for (int i = 0; i < ModelRegistry.models[m].m.obj.size(); i++)
{
glBegin(GL_TRIANGLES);
glNormal3f(ModelRegistry.models[m].m.obj[i].nx1, ModelRegistry.models[m].m.obj[i].ny1, ModelRegistry.models[m].m.obj[i].nz1);
glTexCoord2f(ModelRegistry.models[m].m.obj[i].tx1, ModelRegistry.models[m].m.obj[i].ty1);
glVertex3f(ModelRegistry.models[m].m.obj[i].x1,ModelRegistry.models[m].m.obj[i].y1,ModelRegistry.models[m].m.obj[i].z1);
glNormal3f(ModelRegistry.models[m].m.obj[i].nx2, ModelRegistry.models[m].m.obj[i].ny2, ModelRegistry.models[m].m.obj[i].nz2);
glTexCoord2f(ModelRegistry.models[m].m.obj[i].tx2, ModelRegistry.models[m].m.obj[i].ty2);
glVertex3f(ModelRegistry.models[m].m.obj[i].x2,ModelRegistry.models[m].m.obj[i].y2,ModelRegistry.models[m].m.obj[i].z2);
glNormal3f(ModelRegistry.models[m].m.obj[i].nx3, ModelRegistry.models[m].m.obj[i].ny3, ModelRegistry.models[m].m.obj[i].nz3);
glTexCoord2f(ModelRegistry.models[m].m.obj[i].tx3, ModelRegistry.models[m].m.obj[i].ty3);
glVertex3f(ModelRegistry.models[m].m.obj[i].x3,ModelRegistry.models[m].m.obj[i].y3,ModelRegistry.models[m].m.obj[i].z3);
glEnd();

}
*/
glCallList(list);

glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glUseProgram(0);
}

```

The data comes from a std::vector, I don't know if that could be the problem, the internet doesn't seem to say anything about it. Any help would be great, thanks.

### tutorial deferred shading? [Implemented it, not working properly]

11 October 2013 - 11:48 AM

I've been trying to implement a 1 light deferred shading for upwards of 10 hours no because I have no idea what I'm doing wrong. I'm writing this using GLSL. It seems I've tried every variation of view space, world space, etc. and nothing works. I've looked on the internet for tutorials, but I can't find any, just papers explaining the theory. If anyone could point me to a good tutorial, that would be greatly appreciated. Thanks.

PARTNERS