Make any face be gravity source for an object (magnet boots)

Senzin

01-11-2012 09:04:59

Hi everybody! ("Hi Doctor Nick!")

Background (optional read):
So I'm in the "How am I going to do that??" stage of designing a new game. You might also call this the exploration and discovery stage. Unfortunately I'm extremely busy so I have very little time to sit down and just try a lot of things until I figure it all out. I have a window of about three weeks coming up in a month or so where I intend to do most of the heavy lifting for this game. So I'd like to have most of my implementation plan worked out ahead of time.

Desired behavior:
I want the gravity for a player to be based on what they are standing on, such that they can walk up walls or on the ceiling. Note that they are not climbing them, but rather are attached as if through gravity or magnetism. Basically, just imagine the player is wearing special magnetic boots. I also want a mechanism through which a player can jump from one surface to another and have them be attached to this new surface. Imagine that the player simultaneously disabled the magnetic boots and jumped, then hit the new surface and enabled the magnetic boots again.

Examples:
Imagine the player is in a hallway on some high floor in a tall building. The floor has caved in and the player cannot jump all the way across. However, the ceiling is perfectly fine. The player jumps to the ceiling and now appears to be hanging from the ceiling. The player then simply walks to the other side of the gap and then drops back down to the floor.

Now, imagine the player is in some room and walks out through a hallway. However, this hallway twists, turns and rotates, and eventually ends up back at the room, but the player is now standing on the ceiling. Taking another path may return the player such that they are walking on the walls.

Some ideas for how to do this:
So for simply walking around, I imagine casting a ray in the direction of the player's down vector. This ray will intersect with a face, say the floor. This face will have a normal. Apply a force (of gravity) to the player in the opposite direction of that normal and orient the player so their up vector matches that normal. In this way, the player can just keep walking around and a force will keep them on whatever face they are standing on, and they will be standing upright relative to that face.

To jump to a new surface, the ray can simply be cast to that surface. An initial impulse can be applied for the jump and once the player is close to the surface, gravity will take over. (There needs to be some consideration on when gravity will take over and when ray casting through the down vector will resume to make sure the player actually ends up at the surface they targeted.)

Bonus:
What I'd REALLY like, but I think it might be too hard, is for the player to appear to hover just above the surface they are on. Such that if they were to jump, when they land they would bob up and down a few times, like a spring or a boat in water. And if the player is moving fast and runs into a ramp, the distance they are above the ground would decrease a bit and eventually even out again, just like how the shocks in a car compress and extend when you go up a ramp or hit a speed bump.

Now it's your turn!:
So that's what I'm trying to do. However, I'm very new to NxOgre and don't know how to cast rays or find what they intersect with and get the normals or any of the other things I described. So I'd greatly appreciate being pointed to whatever classes/objects/functions I may need to start working on this. Also, if you can think of simpler or better ways to achieve this, please let me know.

Senzin

10-11-2012 11:42:38

So I found an afternoon I could spend exploring this problem. I went through the documentation that comes with NxOgre, as well as the wiki, and couldn't find anything about ray casting. I decided to check out the PhysX demos because I remembered one of them had you poking at a cloth with the mouse. I looked at the code, then looked for similar functions and classes in NxOgre, and managed to put together the following code:

Ogre::Ray ogreRay = mCamera->getCameraToViewportRay(0.5, 0.5);
NxOgre::Ray ray;
ray.mOrigin = ogreRay.getOrigin();
ray.mDirection = ogreRay.getDirection();
NxOgre::RaycastHit hit = mScene->raycastClosestShape(ray, NxOgre::Enums::ShapesType_All);

So this works great (although the raycast seems to ignore the cloth I have in my seen, even though the cloth is hit by barrels and things like that).

Is this a good way to learn to use NxOgre, to just look at the PhysX documentation and examples and then look for the matching functions and classes in the NxOgre wrapper? Or is raycast in the NxOgre docs and I just didn't look in the right place?

NoMonkey

12-11-2012 09:23:09

I don't think it is in the documentation of NxOgre but it's in the samples that come with NxOgre (Sample 305).
It basically does the same as you did:
Ogre::Ray ogre_ray = mTrayMgr->getCursorRay(mCamera);

// Convert it into an NxOgre ray.
NxOgre::Ray ray;
ray.mDirection.from(ogre_ray.getDirection());
ray.mOrigin.from(ogre_ray.getOrigin());

// Then cast it!
RaycastHit hit = mScene->raycastClosestShape(ray, NxOgre::Enums::ShapesType_All);


Could you give me some samplecode for cloth? It seems to work for you, doesn't it?

Senzin

13-11-2012 07:34:57

Ah, I've been using NxOgre 1.6 Detritus, as it is the current version, not 1.7 Buggy Swires, so I didn't have those tutorials. I'll have to check them out.... and see if they compile.

However, let's keep discussions about what does or does not compile or crash in the other thread (but the cloth code I used is copy/pasted from tutorial 1001).