A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by Julio Jerez » Wed Nov 20, 2013 3:38 pm
a larger than 1.0 means that the ray did not hit anything in a range from 0.0 to 1.0
why 1.2? I do not know I fuond it a nice value,
all it matters is that is larger than 1.0 and you can use the same return value to decide if it hit something or not.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by PJani » Fri Nov 22, 2013 12:22 pm
I was wondering is there anyway i could make a hack at least for now to detect if some body goes out of loaded part?
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by Julio Jerez » Fri Nov 22, 2013 2:38 pm
can you rephrase the question? I do not undestand.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by PJani » Tue Nov 26, 2013 7:38 am
Hmm i will ask this way...is there anyway to detect if some body gets out of the loaded world/chunks/usermeshes? I would need this hack just for the presentation.
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by Julio Jerez » Tue Nov 26, 2013 8:49 am
if these are user mesh, you can put and aabb around then, and trap on AABB.
basically you put a last reference used counter, on each object.
on each frame you increment a global frame counter.
them on each newton update,
in the OnAABB callback of you user define collision, you update the other object counter to the global counter.
you can iterate over each dynamics object, then on after the update, each any body that has a recently used counter lower that the global counter was outside the world.
you can get the locations of those object and upload the necessary zones.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Layla » Tue Nov 26, 2013 9:00 am
did you manage to look into if there's a problem casting convex against a user mesh? I need it for my game for solving camera collisions against the level. Otherwise I need to figure out the math to get the closest intersection of a sphere swept against a voxel world (which would be a better way of doing it)
-
Layla
-
- Posts: 54
- Joined: Sat Sep 28, 2013 11:56 am
by Julio Jerez » Tue Nov 26, 2013 2:07 pm
no, no yet, I forget this, I see if I do it this weekend.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Julio Jerez » Wed Nov 27, 2013 11:03 am
I am working on this now.
tell me are you placing your user mesh on a scene collision? because that the part that I am aware is no complete.
the rest is no different that collision tree, highfield, it should work.
can you please remind me who you are using it.
Meantime time I will complete the user define method for scene collision with user defined collision sub collisions
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Layla » Wed Nov 27, 2013 11:34 am
https://gist.github.com/aylaylay/4767046ab713447ba878Here's my user collision code, obviously not compilable but it should give you a rough idea of what I'm doing. I'm just adding any faces that are inside the collision bounds. This is just my attempt at editing the plane collision for a voxel world, I know it could be much better but user collisions still confuse me.
Physics work fine on it but casting a sphere convex shape against it fails all of the time. The user collision is not placed in a scene collision.
I think I'm using NewtonWorldConvexCast correctly because I'm using it for camera collisions and it works on everything but not the user mesh for the map.
-
Layla
-
- Posts: 54
- Joined: Sat Sep 28, 2013 11:56 am
by Julio Jerez » Wed Nov 27, 2013 12:11 pm
Oh ok, I see why is that.
I'w try to emulate your code same into the demos
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Layla » Wed Nov 27, 2013 12:25 pm
Have you tried just adding a user plane to the convex cast demo? That doesn't work for me either but maybe I'm not adding it correctly.
The cast just passes through the plane as if it's not there.
-
Layla
-
- Posts: 54
- Joined: Sat Sep 28, 2013 11:56 am
by Julio Jerez » Sat Nov 30, 2013 12:07 pm
Ok Layla. I added the continues collsion part to the user mesh
look at the file ..\newton-dynamics\applications\demosSandbox\sdkDemos\toolBox\UserPlaneCollision.cpp
see if you understand it.
basically the collision call back take tow parameters, the second parameter is only non null when the call come forcontineus collision.
then when you do is that you call function.
NewtonUserMeshCollisionContinueOveralapText (collideDesc, continueCollisionHandle, &me->m_minBox[0], &me->m_maxBox[0]))
this is the same function that the internal engine uses for trivial rejection.
in that example sine the plane has onel one polygon, I simple call wit the aabb of that polygon
in your example you need to have a special data structure to do a efficient test.
since you are using a voxel, it should be eassy.
basically you text the AABB of the voxel, and if that passes, then you find of the 8 subsectors that have cells,
then you test the aabb of each non empty subsector, until you reach the resolution of the Voxel.
when you reach the resolution that mean that cell is visible by the continue collision and you build that face.
this should be very, very fact, and only pass those cells on the path of the continue collision motion.
Test the ConvexCast demo, it place the plane collision for casting.
if you can not figure out, let me know and I can modify you call implement that algorithm.
for that I also nee to see this file #include "UserGridCollision.h"
but you should be able to figure out.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Layla » Sat Nov 30, 2013 1:10 pm
I don't really understand the changes. I think it might be better to just handle sweeping a sphere against a voxel grid without going through newton, my math isn't that great but it should be able to be solved without building any kind of polygon mesh like the user collision does. And when I say voxel I just mean a simple uniform grid, each cell either has a block or it doesn't, there's no 8 sub sections or anything like that.
-
Layla
-
- Posts: 54
- Joined: Sat Sep 28, 2013 11:56 am
by Julio Jerez » Sat Nov 30, 2013 2:10 pm
The subsections are implicit in the voxel structure. here is a pseudo code of how you should modify you function for contine collision
- Code: Select all
void UserGridCollision::CollideCallbackDescrete(NewtonUserMeshCollisionCollideDesc* const collideDesc)
{
// this is your same original function
}
// this is fo continue collsion
void UserGridCollision::CollideCallbackContinue(NewtonUserMeshCollisionCollideDesc* const collideDesc, const void* const continueHandle)
{
// get the aabb
dVector p0(collideDesc->m_boxP0[0], collideDesc->m_boxP0[1], collideDesc->m_boxP0[2]);
dVector p1(collideDesc->m_boxP1[0], collideDesc->m_boxP1[1], collideDesc->m_boxP1[2]);
// translate the box to target
dVector transtionDist (collideDesc->m_boxDistanceTravel[0], collideDesc->m_boxDistanceTravel[1], collideDesc->m_boxDistanceTravel[2]);
dVector q0(p0 + transtionDist);
dVector q1(p1 + transtionDist);
p0.m_x = dMin (p0.m_x, q0.m_x);
p0.m_y = dMin (p0.m_y, q0.m_y);
p0.m_z = dMin (p0.m_z, q0.m_z);
p1.m_x = dMax (p1.m_x, q1.m_x);
p1.m_y = dMax (p1.m_y, q1.m_y);
p1.m_z = dMax (p1.m_z, q1.m_z);
collideDesc->m_faceCount = 0;
collideDesc->m_vertexStrideInBytes = sizeof(dVector);
collideDesc->m_faceIndexCount = &m_faceIndices[0];
collideDesc->m_faceVertexIndex = &m_indexArray[0];
collideDesc->m_vertex = &m_collisionVertex[0][0];
// int collisionVertexIndex = 0;
// dVector* polygon;
// min voxel position
Vector3i minBlock((int)p0.m_x, (int)p0.m_y, (int)p0.m_z);
// max voxel position
Vector3i maxBlock((int)ceil(p1.m_x), (int)ceil(p1.m_y), (int)ceil(p1.m_z));
int stack;
Vector3i stackPool[64][2];
stackPool[0][0] = minBlock;
stackPool[0][1] = maxBlock;
stack = 1;
while (stack)
{
stack --;
Vector3i minBlock (stackPool[stack][0]);
Vector3i maxBlock (stackPool[stack][1]);
//see this cell is visible to the collision path
dVector p0 (minBlock.m_x, minBlock.m_y, minBlock.m_z, 0.0f);
dVector p1 (maxBlock.m_x, maxBlock.m_y, maxBlock.m_z, 0.0f);
if (NewtonUserMeshCollisionContinueOveralapTest (collideDesc, continueHandle, &p0[0], &p1[0])) {
if (minBlock.m_x == maxBlock.m_x) {
if (minBlock.m_y == maxBlock.m_y) {
if (minBlock.m_z == maxBlock.m_z) {
//here we found a visible cell, submit this face
} else {
// split alone z axis
int z = (minBlock.m_z + maxBlock.m_z) / 2;
stackPool[stack][0] = minBlock;
stackPool[stack][1] = Vector3i(minBlock.m_x, minBlock.m_y, z);
stack ++;
dAssert (stack < 64);
stackPool[stack][0] = Vector3i(minBlock.m_x, minBlock.m_y, z + 1);
stackPool[stack][1] = maxBlock;
stack ++;
dAssert (stack < 64);
}
} else {
if (minBlock.m_z == maxBlock.m_z) {
// split alone y only
int y = (minBlock.m_y + maxBlock.m_y) / 2;
stackPool[stack][0] = minBlock;
stackPool[stack][1] = Vector3i(minBlock.m_x, y, minBlock.m_z);
stack ++;
dAssert (stack < 64);
stackPool[stack][0] = Vector3i(minBlock.m_x, y + 1, minBlock.m_z);
stackPool[stack][1] = maxBlock;
stack ++;
dAssert (stack < 64);
} else {
// slit alone y and z
int y = (minBlock.m_y + maxBlock.m_y) / 2;
int z = (minBlock.m_z + maxBlock.m_z) / 2;
stackPool[stack][0] = minBlock;
stackPool[stack][1] = Vector3i(minBlock.m_x, y, z);
stack ++;
dAssert (stack < 64);
stackPool[stack][0] = Vector3i(minBlock.m_x, y + 1, z);
stackPool[stack][1] = Vector3i(minBlock.m_x, maxBlock.m_y, z);
stack ++;
dAssert (stack < 64);
stackPool[stack][0] = Vector3i(minBlock.m_x, minBlock.m_y, z);
stackPool[stack][1] = Vector3i(minBlock.m_x, y, maxBlock.m_z);
stack ++;
dAssert (stack < 64);
stackPool[stack][0] = Vector3i(minBlock.m_x, y + 1, z + 1);
stackPool[stack][1] = maxBlock;
stack ++;
dAssert (stack < 64);
}
}
} else {
// x's are different
if (minBlock.m_y == maxBlock.m_y) {
if (minBlock.m_z == maxBlock.m_z) {
// split alone x axis
int x = (minBlock.m_x + maxBlock.m_x) / 2;
stackPool[stack][0] = minBlock;
stackPool[stack][1] = Vector3i(x, minBlock.m_y, minBlock.m_z);
stack ++;
dAssert (stack < 64);
stackPool[stack][0] = Vector3i(x + 1, minBlock.m_y, minBlock.m_z);
stackPool[stack][1] = maxBlock;
stack ++;
dAssert (stack < 64);
} else {
// split alone x and z axis
int x = (minBlock.m_y + maxBlock.m_y) / 2;
int z = (minBlock.m_z + maxBlock.m_z) / 2;
stackPool[stack][0] = minBlock;
stackPool[stack][1] = Vector3i(x, minBlock.m_y, z);
stack ++;
dAssert (stack < 64);
stackPool[stack][0] = Vector3i(x + 1, minBlock.m_y, z);
stackPool[stack][1] = Vector3i(minBlock.m_x, maxBlock.m_y, z);
stack ++;
dAssert (stack < 64);
stackPool[stack][0] = Vector3i(minBlock.m_x, minBlock.m_y, z);
stackPool[stack][1] = Vector3i(x, minBlock.m_y, maxBlock.m_z);
stack ++;
dAssert (stack < 64);
stackPool[stack][0] = Vector3i(x + 1, minBlock.m_y, z + 1);
stackPool[stack][1] = maxBlock;
stack ++;
dAssert (stack < 64);
}
} else {
if (minBlock.m_z == maxBlock.m_z) {
// split alone x, and y
int x = (minBlock.m_x + maxBlock.m_x) / 2;
int y = (minBlock.m_y + maxBlock.m_y) / 2;
//....
} else {
// slit alone x, y and z
int x = (minBlock.m_x + maxBlock.m_x) / 2;
int y = (minBlock.m_y + maxBlock.m_y) / 2;
int z = (minBlock.m_z + maxBlock.m_z) / 2;
//...
// here you push the 8 quadrant on the stack
}
}
}
}
}
}
static void UserGridCollision::CollideCallback(NewtonUserMeshCollisionCollideDesc* const collideDesc, const void* const continueHandle)
{
UserGridCollision* const me = (UserGridCollision*)collideDesc->m_userData;
if (continueHandle) {
me->CollideCallbackContinue(collideDesc, continueHandle);
} else {
me->CollideCallbackDescrete(collideDesc);
}
}
it is important you do the way I say because otherwise you will have many severe performance problems if you simple sweep a sphere again the cells.
this above code has a contact time cost per cell, while the naïve sweep will heve a o(n^3) cost, and will one be efficient on very short sweeps.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 1 guest