Hitbox

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Hitbox

Postby Void » Sat Nov 28, 2020 2:47 pm

Hello.
I am trying to create a server for one game. This is a non-profit project. This project is a hobby for me. At the moment I am trying to add physics to the game. And at the moment I have some difficulties.
A few words about the game. This is a game about heavy vehicles (or armored tank, I'm not sure how it is correct in english). The feature of the game is that all calculations take place on the server.
I am using newton-3.14. I was able to add a physical object. But I need a calculation from the shots. So I decided to split the physical model. One simplified model will be used for physics. Another model is the hitbox. To calculate the shot, I need some data, such as the thickness of the armor, the location of the internal modules and the crew members. Because this physics model is not moving, I decided to use functions to work with static collision (as i remember in static collision i can assign material or index for each individual polygon). I'm not sure what I'm doing right, that's why I'm writing here.
I am creating a collision with the NewtonCreateSceneCollision function. Then NewtonSceneCollisionBeginAddRemove. And in the loop, I add a collision using the NewtonCreateTreeCollisionFromMesh function. Each collision created with the NewtonCreateTreeCollisionFromMesh function has its own material that will be used for the RayCast.

Code: Select all
NewtonCollision *compound = NewtonCreateSceneCollision(newton, 0);
NewtonSceneCollisionBeginAddRemove(compound);

for (size_t i = 0, count = collision_vector.size(); i < count; i++)
{
   NewtonMesh *mesh = collision_vector[i];

   NewtonCollision *collision = NewtonCreateTreeCollisionFromMesh(newton, mesh, 0);
   NewtonMeshDestroy(mesh);

   NewtonCollisionMaterial material;
   ...
   NewtonCollisionSetMaterial(collision, &material);

   NewtonTreeCollisionSetUserRayCastCallback(collision, Cb_TreeRayCast);

   NewtonSceneCollisionAddSubCollision(compound, collision);
   NewtonDestroyCollision(collision);
}

NewtonSceneCollisionEndAddRemove(compound);


I need to somehow list all the surfaces that the raycast crosses. I found the NewtonTreeCollisionSetUserRayCastCallback function. But when I try to raycast (NewtonCollisionRayCast), I get an assert.

newton-3.14\sdk\dgphysics\dgcollisionbvh.cpp
Code: Select all
dgFloat32 dgCollisionBVH::RayHitUser (void* const context, const dgFloat32* const polygon, dgInt32 strideInBytes, const dgInt32* const indexArray, dgInt32 indexCount)
{
   dgAssert (0);

Is this function just for debugging? Or can I use it?

I have commented out the asserts. But when I try to raycast, the callback is called only once (it doesn't matter what I return 1.0 or the intersection parameter). And after that I get an assertion in the function.
newton-3.14\sdk\dgphysics\dgcollisionbvh.cpp
Code: Select all
dgFloat32 dgCollisionBVH::RayCast (const dgVector& localP0, const dgVector& localP1, dgFloat32 maxT, dgContactPoint& contactOut, const dgBody* const body, void* const userData, OnRayPrecastAction preFilter) const
...
dgAssert(ray.m_normal.m_w == dgFloat32(0.0f));

The value of the vector is as if it had not been initialized.
Did I choose the correct collision type?
How can I get all the polygons that the raycast has crossed?
Void
 
Posts: 2
Joined: Tue Mar 03, 2020 8:07 am

Re: Hitbox

Postby Julio Jerez » Sat Nov 28, 2020 8:27 pm

Use the normal ray cast,
That user ray cast was added for a specific user, many may year ago.
To get all hit, you simply collect the hits other callback and return 1.0

The you get all the triangles hit by the ray, the ray do not intersect center clockwise faces.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Hitbox

Postby Void » Sun Nov 29, 2020 1:19 pm

Julio Jerez wrote:Use the normal ray cast

Do you mean to use a standard set of collision primitives? Or not to use a callback?
Julio Jerez wrote:That user ray cast was added for a specific user, many may year ago.

I understood. But for me this is exactly what I need.
Julio Jerez wrote:To get all hit, you simply collect the hits other callback and return 1.0

I did just that. But, as I already wrote, I received an assert.
Julio Jerez wrote:The you get all the triangles hit by the ray, the ray do not intersect center clockwise faces.

I'm not sure I understood you correctly.

The problem with this callback was that the return value from the callback was ignored. I fixed it like this.
Code: Select all
dgFloat32 dgCollisionBVH::RayHitUser (void* const context, const dgFloat32* const polygon, dgInt32 strideInBytes, const dgInt32* const indexArray, dgInt32 indexCount)
{
   //dgAssert (0);
   //dgFloat32 t = dgFloat32 (1.2f);
   dgBVHRay& me = *((dgBVHRay*) context);
   dgVector normal (&polygon[indexArray[indexCount + 1] * (strideInBytes / sizeof (dgFloat32))]);
   normal = normal & dgVector::m_triplexMask;
//dgAssert (0);
   dgFloat32 t = me.PolygonIntersect (normal, me.m_t, polygon, strideInBytes, indexArray, indexCount);
   if (t < dgFloat32(1.0f)) {
      normal = me.m_matrix.RotateVector(normal);
      dgUnsigned32 m_id = me.m_me->GetTagId(indexArray, indexCount);
      t = me.m_me->GetDebugRayCastCallback() (me.m_myBody, me.m_me, t, &normal[0], dgInt32(m_id), me.m_userData);

      if (t < me.m_t) {
         me.m_t = t;
         me.m_normal = normal;
         me.m_id = m_id;
      }
   }
   return t;
}

I'm not sure if this is correct. But I got all the intersections.
Void
 
Posts: 2
Joined: Tue Mar 03, 2020 8:07 am

Re: Hitbox

Postby Julio Jerez » Sun Nov 29, 2020 2:08 pm

I removed the assert.
oh I see what you mean. yes that function dgFloat32 dgCollisionBVH::RayHitUser
will neve return all face hit.
the different between those two functions is that one call a use call back while the normal one does
not.

you can do tow things. one is
1- you can change dgCollisionBVH::RayHitUser so that is always returns 1.0 like this
Code: Select all
dgFloat32 dgCollisionBVH::RayHitUser (void* const context, const dgFloat32* const polygon, dgInt32 strideInBytes, const dgInt32* const indexArray, dgInt32 indexCount)
{
   dgFloat32 t = dgFloat32 (1.2f);
   dgBVHRay& me = *((dgBVHRay*) context);
   dgVector normal (&polygon[indexArray[indexCount + 1] * (strideInBytes / sizeof (dgFloat32))]);
   normal = normal & dgVector::m_triplexMask;

   t = me.PolygonIntersect (normal, me.m_t, polygon, strideInBytes, indexArray, indexCount);
   if (t < dgFloat32 (1.0f)) {
      if (t < me.m_t) {
         me.m_t = t;
         me.m_normal = normal;
         me.m_id = me.m_me->GetTagId(indexArray, indexCount);
      }
      normal = me.m_matrix.RotateVector(normal);
      t = me.m_me->GetDebugRayCastCallback() (me.m_myBody, me.m_me, t, &normal[0], dgInt32 (me.m_me->GetTagId(indexArray, indexCount)), me.m_userData);
   }
// this will make aabb continue reportion more hit alone the line
   return 1.0;
}



in newton 4 this funtionality is exposed, so you can simple get the collision objects dAaabbPolySoup
class ndShapeStaticBVH : public ndShapeStaticMesh, public dAabbPolygonSoup

and do the ray cast there.
newton 4 has a c++ interface that makes these custom changes simpler to make, however newton 4 is at an early stage.
for what you described Newton4 is a better fit since is teh work no longer owns the objects, they nee to be added and remove, plus is work s better are collsion system only.

for now just change the function and return 1. and in your call back you can collect the intersections.

on the one side face comment. what I mean is that the ray cast is like renderers that only draw faces with normal that point to the eye point. in newton, faces with normal pointing away from the direction of the ray are ignored.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
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 42 guests