How to add a collision with an sphere object

Hello guys…



I have, in my game, a laboratory model that is something like a semi-sphere (having a front and back door), and I want to know what I have to do to not let the camera go through the walls?

I have tried to use something with "BoundingCollisionResults", but it not worked because I need to get in the semi-sphere (in this case, my lab), and when I get in the lab, using BoundingCollisionResults, the collision is detected…



what I need to do???  :?  :?

I saw this solution somewhere on the forum and tried it myself, works good. Simply cast a ray from the object your camera is following to the camera, and if an intersection occurs between the camera and the object, move the camera to that intersection point. This will keep the camera in.



I'll post my implementation if you want it, short and works great.

thanks  :smiley:

but I think that you understood a little diferent…

I have a FirstPersonHandler, and I want to get into the lab (the semi-sphere oval), but I don’t want that my person go through the wall without opening the door (part of the semi-sphere), then, to do this I need to do some collisions right?

to make a simple collision with another wall (that is  a simple box), I have used BoundingCollisionResults and to detect the collision I have added a simple box in the location of my camera, then, when the cam gets closer to the simple wall (my box), the collision is detected…



but to do this with a semi-sphere object I think i’ll need to use TriangleCollisionResults (but I would like to use the same box attached to the camera to detect collision with the triangles of my lab), but it’s still not working, because when I get inside the lab (the semi-sphere model), far from the walls, the collision is detected, like if I’m using BoundingBox ( because the BoundingBox surround the entire lab)…



what I have to do now???  :’(  :?

Let me see if I understand correct.



Your walking up to the lab and the only point of entry is through the door. You say your collision isn't detected until your already inside the semi-sphere, using bounds collision. This sounds like your bounds is smaller than the actual lab, if you can get inside.



But to do what you want to I beleive you will need to use triangle collisions. What you can do is check for bounding collision first, and once you get to or get inside the bounds you can check for triangle collision between the camera box and the semi-sphere.



Is this what you were thinking? If so I can show you a step-by-step approach to this, its not too difficult.

no, the collision is detect also outside of the lab, but I don want to that collision is detect when I get inside the lab…



here's my code…



in my initgame:

//Controle de Colis

Bounding collisions occur as long as you are within the bounds, not just the edge or face of the bounds. Say your semi-sphere has a bounding box around it, from the moment you touch and as long as you are within the bounding box of the semi-sphere, it will report collisions.



Another thing to consider, I believe triangle collisions report bounding collisions as well. The only difference is it wont store any triangle data. So the only way to tell if a triangle collision has actually occurred (and not just a bounds collision, even though your testing for triangle collisions) is to test the CollisionData.getTargetTris().size() > 0. If you are inside the bounds, triangle collision will say you are colliding, so check the getTargetTris().size() for each collision reported.



Does this help?

in my update method I added the following:

// Colision Control!!!
            res_tricolisao.clear();
            //gets only the walls of lab (semi-sphere object)
          //no_colisao.calculateCollisions(((Node)((Node)laboratorios.getChild(0)).getChild(0)).getChild(3), res_tricolisao);
            no_colisao.findCollisions(laboratorios, res_tricolisao);
          if(res_tricolisao.getNumber() > 0) {
             dados_colide = res_tricolisao.getCollisionData(0);
             //System.out.println("Dados clide: " + dados_colide.getTargetTris());
             if(dados_colide.getTargetTris().size() > 0)
                System.out.println("Opaaa, houve colisao com labs!");
          }



AND NOW IT WORKS.... only when my camera box hit my wall box the system prints "Opaaa, houve colisao com labs!"... Yeah... thanks man!!!!!!!!!!!!!!!!!!!!!!!!!!!  :D  :D  :D  :wink:

Now, do you have any idea of how make my cam stay on his last position before hitting the wall (to not let the cam go through the wall???)

Great! I'm glad it worked out for you. I was trying to figure this stuff out just a couple weeks ago.



What I'm doing in my app is storing the location before I call input.update() and if I have a collision after input.update() I calculate the distance from my previous location to the collision and put it there. So you can go right up to the wall it but if you go through, it puts you back. This all happens during update.



My collision code has some more math to it to allow you to slide along the surface even if your against it, so you don't stick to it. I'll share it with you if you're interested.

I will be very thankfull if you send this code to my…

I think that will help me a lot…



thanks a lot man…  :D  :wink:

collisions is one of my many weaknesses I be thankful if you decided to post it :slight_smile: :roll:



sorry for the hijack

Sure, I'm away right now, but I should have it up this time tomorrow.

This is kinda how it works:


thanks man before this the best idea I had was to use a physicsnode constrained to a joint on one end and my player on the update its position when a collision occurs between the physicsnode and the scene as proposed by Irrisor, being a novice I wasn't very clear on how to get it all working seemlessly, your code might be a good substitute until I figure the physics thing out.



the whole playernode updates the physicsnode and flips roles when collision occurs baffles me :// :frowning: I just don't know how to turn  it into code that works the way I need it to. 

@nymon: Consider adding this code to the wiki as a mini tutorial or code sample (preferrably the first.)

I'd be more than happy to. I'll feel more comfortable with my code in a day or two.



I'm putting together a test case to find out why it fails when it does. Right now my only lead is maybe triangle results isn't returning more then the the first object triangles when more than one object is involved. Anyone else experienced this? Or can they at least confirm that triangle collision does in fact work in this case?



Anyway, I should have a complete working example of both the bug and the collision test this weekend.  A tut sounds like a good idea.

This has been corrected, and the correction is reflected in the above code snippet…


NOTICE:

After building a test case for this I have discovered a fatal flaw. This doesn't work for anything that is rotated, in other words, the collision surface must be alinged with one of the axis planes. Its just a math error, so I should be able to fix this by sunday. I beleive this will also fix the other known bug.

If anyone decides to use this before I can correct it, it gives you a good place to start from. I need this to work ASAP, so it shouldn't be too long.

man, I think that's right, but remember that I put a box in the same position of my cam, to detect collision (I think that is not possible to detect collision directly with the cam), but when the collision is detect only my box is translated, but not my cam… it's more important to me to make my cam translate, not the box representing the cam…  :smiley:



here's what I make:


protected void beforeInputUpdate()
        {
           prevLoc.set(cam.getLocation());
        }
       
        // Sobrescreve o m

Because the box is actually involved in the collision and not the camera, the box is what gets set back, like you were saying. I imagine you have it setup so the input handler moves the camera and you update the collision box to the location of the camera.This keeps them in sync. But when a collision occurs, the box gets moved like it should but the camera doesn't. The solution should be quite easy. Whenever there is a true collision and the box get moved by the collision code, then move the camera to the new box location. So really they take turns updating themselves. Make sure you have the collision box and camera in the same location before checking for collision.



Try this order:

Input moves camera

camera sets box location

collision moves box

box sets camera location



As far as the post earlier, It has something to do with the normals not calculated correctly do to the rotation of the object collided with. I started another thread soliciting help with the calculation, and as soon as I get this fixed it should be great.



As long as the stuff your running into hasn't had its local rotation changed from default, you shouldn't notice any problems.

man now it's "working"… I just got some times the following error while colliding with the wall:

java.lang.ArrayIndexOutOfBoundsException: 133 <-- (this number changes)
   at ecas.Ecas.getCollisionNormal(Ecas.java:479)
   at ecas.Ecas.checaColisao(Ecas.java:451)
   at ecas.Ecas.simpleUpdate(Ecas.java:231)
   at sistema.SistemaBasico.update(SistemaBasico.java:88)
   at com.jme.app.BaseGame.start(Unknown Source)
   at ecas.Ecas.main(Ecas.java:114)



I added the colision to one of my labs (semi-sphere objects)... in the walls everything goes ok, but its not working on the labs door... (part of semi-sphere), I can go through the door (my labs model have two childs , the walls, and the door)

But I'll try to fix it...
About the rotation error, yeah, there is a bug... I tried to do this collision with my fence model, that has a rotation, it's not working  :D
If you got the problem, please post here...  ;)  :wink:

Thanks a lot... your help was very important to my game...  :D

Got the solution right here (and I'll also correct the code above).



In the method getCollisionNormal() replace this line:

normal.addLocal(t.getNormal());



with this line:

normal.addLocal(triData.getTargetMesh().getLocalRotation().mult(t.getNormal()));



And you should be able to rotate stuff and not suffer.



About your error…

I would occasionaly get the same thing during an animation when I was updating the model bounds constantly for a test. If have update your model bounds every update or so that might be the culprit. Otherwise I'll have to think on it.



Make this change first and tell me how it all works out!