A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by Julio Jerez » Mon May 31, 2010 12:35 pm
I thought we discussed that before that the tree collision is does no really deal with double faces.
Adding a face twice by inerting the winding is a cheat that lead to unpredictable results.
I believe I posted an algorithm to go around the problem.
That displace the double face by some distance parallel to the face normal.
And if you want to do better, you need to extrude the face algorithmically. That way you will add a solid volume.
If you are going to do that please do not try some distant like 1 millimeter, that does not makes sense and will not solve the problem,
a reasonable distance will be something like 5 to 10 centimeter gap between tow parallel faces.
Here is an algorithm you can use to fix the problem.
-Create a list to save all double faces.
-add all double side face to this list with the winding inverted.
-Create a collision tree to use as helper.
-Add all faces from the previous List to this collision tree.
-close the tree with optimization on.
-using debug display read all the faces in teh collision tree
For each face you need to add a extruded so that the face for
Walking the perimeter of each face from the collision craete a extruded volume, tah is a parallet face with all the sides,
-Destroy the collision tree.
Not you make the new collision tree, and you add all the face in you mesh, all the face you read form the
Optimize collision tree, and you also add the rivet faces you made to make solid fences
Give two or three hours I will write a function to do that for you. It is eassy using Netwon collsion and the Newton Mesh.
The Netwon Mesh is a computation tool that can be use to help when thing like thsi need to be done.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Julio Jerez » Mon May 31, 2010 1:45 pm
Ok here is a function that you can use to build the Auxiliary mesh to fix the double side faces
- Code: Select all
static void ExtrudeFaces (void* userData, int vertexCount, const dFloat* faceVertec, int id)
{
float OFFSET = 0.1f;
float face[32][10];
NewtonMesh* mesh = (NewtonMesh*) userData;
// calculate the face normal
dVector normal (0, 0, 0);
dVector p0 (faceVertec[0 * 3 + 0], faceVertec[0 * 3 + 1], faceVertec[0 * 3 + 2]);
dVector p1 (faceVertec[1 * 3 + 0], faceVertec[1 * 3 + 1], faceVertec[1 * 3 + 2]);
dVector e0 (p1 - p0);
for (int i = 2; i < vertexCount; i ++) {
dVector p2 (faceVertec[i * 3 + 0], faceVertec[i * 3 + 1], faceVertec[i * 3 + 2]);
dVector e1 (p2 - p0);
normal += e0 * e1;
e0 = e1;
}
normal = normal.Scale (1.0f / dSqrt (normal % normal));
dVector displacemnet (normal.Scale (OFFSET));
// add the face displace by some offset
for (int i = 0; i < vertexCount; i ++) {
dVector p1 (faceVertec[i * 3 + 0], faceVertec[i * 3 + 1], faceVertec[i * 3 + 2]);
p1 += displacemnet;
face[i][0] = p1.m_x;
face[i][1] = p1.m_y;
face[i][2] = p1.m_z;
face[i][3] = normal.m_x;
face[i][4] = normal.m_y;
face[i][5] = normal.m_z;
face[i][6] = 0.0f;
face[i][7] = 0.0f;
face[i][8] = 0.0f;
face[i][9] = 0.0f;
}
// add the face
NewtonMeshAddFace (mesh, vertexCount, &face[0][0], 10 * sizeof (float), id);
// now add on face walk the perimeter and add a rivet face
dVector q0 (faceVertec[(vertexCount - 1) * 3 + 0], faceVertec[(vertexCount - 1) * 3 + 1], faceVertec[(vertexCount - 1) * 3 + 2]);
q0 += displacemnet;
for (int i = 0; i < vertexCount; i ++) {
dVector q1 (faceVertec[i * 3 + 0], faceVertec[i * 3 + 1], faceVertec[i * 3 + 2]);
q1 += displacemnet;
// calculate the river normal
dVector edge (q1 - q0);
dVector n (edge * normal);
n = n.Scale (1.0f / sqrtf (n % n));
// build a quad to serve a the face between the two parellel faces
face[0][0] = q0.m_x;
face[0][1] = q0.m_y;
face[0][2] = q0.m_z;
face[0][3] = n.m_x;
face[0][4] = n.m_y;
face[0][5] = n.m_z;
face[0][6] = 0.0f;
face[0][7] = 0.0f;
face[0][8] = 0.0f;
face[0][9] = 0.0f;
face[1][0] = q1.m_x;
face[1][1] = q1.m_y;
face[1][2] = q1.m_z;
face[1][3] = n.m_x;
face[1][4] = n.m_y;
face[1][5] = n.m_z;
face[1][6] = 0.0f;
face[1][7] = 0.0f;
face[1][8] = 0.0f;
face[1][9] = 0.0f;
face[2][0] = q1.m_x - displacemnet.m_x;
face[2][1] = q1.m_y - displacemnet.m_y;
face[2][2] = q1.m_z - displacemnet.m_z;
face[2][3] = n.m_x;
face[2][4] = n.m_y;
face[2][5] = n.m_z;
face[2][6] = 0.0f;
face[2][7] = 0.0f;
face[2][8] = 0.0f;
face[2][9] = 0.0f;
face[3][0] = q0.m_x - displacemnet.m_x;
face[3][1] = q0.m_y - displacemnet.m_y;
face[3][2] = q0.m_z - displacemnet.m_z;
face[3][3] = n.m_x;
face[3][4] = n.m_y;
face[3][5] = n.m_z;
face[3][6] = 0.0f;
face[3][7] = 0.0f;
face[3][8] = 0.0f;
face[3][9] = 0.0f;
// save the first point for the next rivet
q0 = q1;
// add this face to the mesh
NewtonMeshAddFace (mesh, 4, &face[0][0], 10 * sizeof (float), id);
}
}
NewtonMesh* CreateCollisionTreeDoubleFaces (NewtonWorld* world, NewtonCollision* optimizedDoubelFacesTree)
{
NewtonMesh* mesh = NewtonMeshCreate(world);
dMatrix matrix (GetIdentityMatrix());
NewtonMeshBeginFace(mesh);
NewtonCollisionForEachPolygonDo (optimizedDoubelFacesTree, &matrix[0][0], ExtrudeFaces, mesh);
NewtonMeshEndFace(mesh);
return mesh;
}
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Julio Jerez » Mon May 31, 2010 2:10 pm
here is a pseudo code of how you can use to make the collision mesh
- Code: Select all
NewtonCollsion* CreteCollsionTree (Racer* mesh)
{
NewtonCollision* auxiliaryTree = NewtonCreateTreeCollision(world, 0);
NewtonTreeCollisionBeginBuild(auxiliaryTree);
//for each Face in racer mesh
{
if (Face[i] is double face) {
tmpface = create a face with the verce winding in tmp
NewtonTreeCollisionAddFace(auxiliaryTree, faceindexCount, &tmpface[0].m_x, sizeof (vertex), faceID);
}
}
// finalize with optimization on
NewtonTreeCollisionEndBuild(auxiliaryTree, 1);
// create a mesh with rivets
NewtonMesh* auxiliaryMesh = CreateCollisionTreeDoubleFaces (world, auxiliaryTree);
// Release the auxiliary collision tree
NewtonReleaseCollision (world, auxiliaryTree);
// now make teh collsiion tree here
NewtonCollision* tree = NewtonCreateTreeCollision(world, 0);
NewtonTreeCollisionBeginBuild(tree);
// add all the face is mesh to the tree
{
// normal code for build ad collision tree
}
// now add all the faces in auxiliaryMesh to final tree
// extract the materials index array for mesh
{
int vertexCount = NewtonMeshGetVertexCount (auxiliaryMesh);
float tmpvertex = new float [2 * vertexCount];
float tmpdummy = new float [2 * vertexCount];
NewtonMeshGetVertexStreams (mesh,
3 * sizeof (dFloat), (dFloat*) tmpvertex,
3 * sizeof (dFloat), (dFloat*) tmpdummy,
2 * sizeof (dFloat), (dFloat*) tmpdummy,
2 * sizeof (dFloat), (dFloat*) tmpdummy);
void* geometryHandle;
geometryHandle = NewtonMeshBeginHandle (auxiliaryTree);
for (int handle = NewtonMeshFirstMaterial (auxiliaryTree, geometryHandle); handle != -1; handle = NewtonMeshNextMaterial (auxiliaryTree, geometryHandle, handle)) {
int material;
int indexCount;
dSubMesh* segment;
material = NewtonMeshMaterialGetMaterial (mesh, geometryHandle, handle);
indexCount = NewtonMeshMaterialGetIndexCount (mesh, geometryHandle, handle);
segment = AddSubMesh();
segment->m_textureHandle = (GLuint)material;
int* indexList = new int [indexCount];
NewtonMeshMaterialGetIndexStream (mesh, geometryHandle, handle, indexList);
for (int i = 0 ; < indexCount; i += 3) {
float face[3][3];
for (int j = 0 j < 3; j ++) {
int index = indexList[i + j];
face[j][0] = indexList[index * 3 + 0];
face[j][1] = indexList[index * 3 + 0];
face[j][2] = indexList[index * 3 + 0];
}
NewtonTreeCollisionAddFace(tree, 3, &face[0][0], 3 * sizeof (float), material);
}
delete[] indexList;
}
delete[] tmpvertex;
NewtonMeshEndHandle (mesh, geometryHandle);
}
// finalize the collision wi th you optimization flag
NewtonTreeCollisionEndBuild(tree, optimization);
//destroy the helper mesh
NewtonMeshDestroy(auxiliaryMesh);
return tree;
}
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Julio Jerez » Fri Jun 04, 2010 2:36 pm
Hey Delfi working on rvangaal problem I finally foudn teh Bug in teh collsion tree tha was makin teh collision fail in his level.
I will be in 2.22 but I beleive that many be why you are seen soem faces tha do not get converet to convex in more optimal ways.
I had to do with convex faces with edges having more than one point that fall on a straight line.
when that case happens the face was mangled, but it was rare that is happens.
I put 2.22 in the server maybe you can try and see if is makes it better.
I am not sure if this was what was makinf the problem you show before in the picture, but is was cerrtailly a serius bug,
that not only make bad face, it also leave holes in the mesh.
I am glad rVangaal post this bug because I got to fix two big problems in the engine,
collision with big faces, and thsi optimizer bug.
now if I can fix the one were sweep collision miss soem time, 2.22 will be the most robust yet of all versions.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JernejL » Fri Jun 04, 2010 6:00 pm
I tried new dll, i think it works slightly better, but it will still not merge faces on same plane along a non-world-flat planes (world space)
I have a few examples where it will fail to optimize, here is one:
ingame debug rendering.
This is how it looks in editor:
I can send you a demo and you can look around on why those cases fail to optimize, if the original reason was a bug this could be still connected to the bug?
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Julio Jerez » Fri Jun 04, 2010 6:59 pm
hold in teh demo, I have a couple of Bug I am fixing now.
can you outline, in the image, where the error is wuth a red marker?
Oh I see the entire ramp is flat, and should be a single face, is that what is is?
If that is what is is that will be a good test to find out where the problem is.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JernejL » Sat Jun 05, 2010 9:46 am
Julio Jerez wrote:Oh I see the entire ramp is flat, and should be a single face, is that what is is?
If that is what is is that will be a good test to find out where the problem is.
Yes this is one of the problems, the slope should been optimized into a totally flat quad face, all those strips are on the same plane and with properly matching vertices that they make a 100% flat plane.
I have another place where it doesn't optimize very well, i'll post pictures of that one later (i'm in a hurry atm)
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Julio Jerez » Sun Jun 06, 2010 1:11 pm
Ok SDK 2.22 is out, it fave some imprtant bug fixes.
Delfi can you send me tha demo that fail to optimized those oviuos faces.
Maybe I can find some other bugs, and since I was lokking at that now mayeb it is time to check out again with you test.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JernejL » Sun Jun 06, 2010 3:41 pm
Ok, i built a demo here:
http://mathpudding.com/tdc/juliotest%20TDC%20DEMO.rar After you run it, the game will save serialized collision files in data\maps\cached you can just delete those files so the game will rebuild them.
Here is a optimization issue 1, this is north from where player will spawn, the particular fence surface is totally flat and yet it is cut in pieces.
This is a oddly shaped part of a building column, the side wall is not optimized optimally, i marked the outline of the actual wall:
To the left of player start is the slope i shown a few posts ago, i put everything in correct place so that it should be easy to test.
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Julio Jerez » Sun Jun 06, 2010 6:33 pm
ther are lot of .ngd file do you kno wwhich one can be one with the error.
also I forgot how to see the wire frame mode.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JernejL » Sun Jun 06, 2010 7:20 pm
press F1 and go to debug controls tab -> view all newton geometry
the files are:
tstd_X1Y3T0.ngd (floor)
tstd_X1Y3T1.ngd (water - probably empty)
tstd_X1Y3T2.ngd (walls)
3 files.. one per material type, for that city section.
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Julio Jerez » Sun Jun 06, 2010 7:59 pm
do those tree have the Bug?
I ask because it saves me a lot of time trying for insulate the bug.
Oh I see the ramp you mention. I also see many vertical wall that at first look like they should be optimize oout without major problems bu they are not.
I will se what coudl be. It certainlly looks like it could be better.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JernejL » Mon Jun 07, 2010 6:00 am
The map editor claims that those are the correct files, but i can look into it again to make 100% sure.
You just delete the wall or ground file to have it rebuilt by the game for that sector, you can this way easily diagnose what part it is.
edit: yes it is definetly that set of files.
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Julio Jerez » Tue Jun 08, 2010 12:27 pm
Ok Delfi pleasetry sdk 2.23
I do not think if find them all but this should be much better,
Please see if can remove a lot more internal edges from convex face that were missed before.
Compare to sdk 2.22 and see where they are different.
Ion thing I notice is that the can now start to pile up, I do not know if this is because you traffic algorithm is being mess up by this change.
Please let me know if there is some good or bad difference.
edit:
I just played and I see that the tall building in the secund picture you show is still wrong, Is that building in teh wall mesh?
I like to see why it is that it is no falling all the test. anyway see if this SDK is better.
I will continue to chek why is that, is seem eassy to catch.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JernejL » Tue Jun 08, 2010 3:19 pm
Looks like this is actually my fault, those complex unoptimized walls were my fault, they are fake 2-sided faces, if i make them 1-sided it all works ok:
It looks like i will have to handle this fence geometry different way, since right now it causes other kind of problems too like cars passing sideways thru a fence
The only problem in that case are totally flat slopes, but this seems like a minor problem only:

-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 0 guests