Game Development Community

How should I implement gravity wells?

by Jim Rowley · in Torque Game Engine · 06/24/2003 (10:40 am) · 23 replies

I'm thinking of implementing gravity wells in my torque based space game. I have two current thoughts on how to implement them. One, have my spacevehicle class search through the server list of gravity well objects and add in the physical forces for each in its updateForces function. Two, have the gravity well objects themselves search a radius and alter the forces on each object within their pull. Which approach would be most cost-effective if I generally have many spacevehicle objects and few gravity wells in the world?
Page «Previous 1 2
#1
06/24/2003 (3:13 pm)
You might calculate a grid containing the forces at each location and then update things based on their position in the grid. Mark the grid with a special value if the squares are close enough to the vortices that the approximation would break down.

Poof, near-constant time calculation of the forces. Of course, you have to pay for it with memory ;)

If anything, I think the former approach of the two you listed would be more efficient.
#2
06/24/2003 (3:16 pm)
I'm sure there is support for this already found in Physical Zones

so check those out.

if the support does not exhist there.
then that is the place to add it.
#3
06/24/2003 (4:18 pm)
Physical zones wouldn't be the best solution for this.

Triggers on the other hand would be more appropriate. You could create a trigger that for every tick while inside the trigger, applies an impulse force in the direction of the gravity well tied to that trigger.
#4
06/24/2003 (4:37 pm)
..
hmm but a Physical Zone is practically a trigger.
except it has a place to store grav, speed and direction.

indeed it doesnt have the neat callbacks all setup.

but you really should be doing the work in the object anyhow.

where you would have to operate the zone on your own,
by first finding if your in it then reacting.

*shrug*

Edit:
do vehicles hit trigger's now?
#5
06/24/2003 (5:05 pm)
I implemented gravity wells in my own game last week. Here's what I did. I added a gravity point variable and a gravity strength variable to the player class, and exposed functions to scripting to change them. When the strength is something other than 0, the player is sucked to the gravity point with however much strength is specified (if negative, it's a repulsion well). Then in scripting, I added a datablock for a magnet trigger, with custom entry and exit scripts. These scripts set the gravity point and strength using a dynamic data field (specified in mission editor). In the mission editor, I simply place a trigger using the custom datablock, then add the dynamic field that the gravity well script uses. Works beautifully... if you need more of a push, let me know.

[edit] Note that this exact method will only allow one gravity well at one time, though the setup could be easily adapted to allow for multiple wells [/edit]
#6
06/24/2003 (9:48 pm)
Can you set triggers and/or physical zones to work with a spherical radius? I used a physical zone to negate all gravity to mimic space, but if I recall correctly, the zone is cubic. I guess I can go look, hehe... Thanks for all your suggestions, I'll try to remember to let you know what I wind up doing. I want the physics to work for things like setting objects in orbit.

Further note- If I remember correctly I believe that the UpdateForces function for flyingvehicle (which my spacevehicle is derived from) currently only adds in the physical force for one physical zone that you're in. I want my game to allow multiple gravity influences, so I'll have to check that out as well.
#7
06/25/2003 (1:04 am)
By default I'm quite sure a sphere boundary is not supported. One way you could kinda hack it in without major changes is to set the trigger box to bound the sphere you want, and when a ship moves into the trigger box, you check the ship's distance, and only if it's in range you update it.

Otherwise you can modify the source to check based on distance rather than "in bounding box" for physical zones and triggers. I came across the functions that check that kind of thing, though I can't remember them off the top of my head. They weren't too terribly difficult to trace back to.

Good luck!
#8
06/25/2003 (9:55 am)
The method I suggested above would let you have an arbitrary number of point sources and a large number of freely moving objects. You could have objects intrinsically posess gravity, as opposed to manually setting bounding zones. On the other hand, it would take a bit of work. ;)
#9
07/08/2003 (11:56 pm)
I thought I would let you know that I wound up implementing the gravity wells using the first idea I mentioned above, and it is working beautifully. I have my spaceVehicle class iterate through a GravityWells Mission Group for any shapebase objects and then use that object mass to calculate the gravity force on the 'vehicle' within my spaceVehicle::updateForces() method. I've done simulations with about 40 asteroids (spaceVehicles) and 2-4 gravity wells and its all working great. Thanks for your suggestions, they have helped to stretch my understanding of Torque a little more.
#10
07/09/2003 (2:28 am)
Um. Will this become a resource?

Just a thought. :P

Alex
#11
07/09/2003 (2:37 am)
Cool, Jim! I've had plans to do the same thing for some time. Glad to hear it worked out.
#12
07/10/2003 (7:45 pm)
My addition to FlyingVehicle::updateForces is simple, I'll post it here.

The requirement for this code is that you have a MissionGroup you name GravityWells and it contains the ShapeBase objects which will be gravity sources. Those objects must have a mass assigned in their datablocks (generally large in order to pull on flyingVehicles).

This code simulates Newton's law of universal gravitation on the flyingvehicle. I'm using it for a space-based game and I've coded it so that it will not exert gravity on flyingvehicle objects within the GravityWells group because I'm currenlty using flyingvehicles as gravity wells too.

Insert this code in the updateForces method just before the last two lines which read
mRigid.force = force;
mRigid.torque = torque;

// JGR - add in forces from gravity wells (shapebase objects in group GravityWells)
if (isServerObject())
{
   SimGroup *gravGroup = dynamic_cast<SimGroup*>(Sim::findObject("GravityWells"));
   if (gravGroup && this->getGroup() != gravGroup) // no grav to other grav shapes
	for (SimGroup::iterator itr = gravGroup->begin(); itr != gravGroup->end(); itr++) 
	{
		ShapeBase * pSB = dynamic_cast<ShapeBase*>(*itr);
		if (pSB) {
			Point3F gravPos = pSB->getPosition();
			VectorF distVec = gravPos - massCenter;
			F32 dist = distVec.len();
			if (dist) {
				distVec.normalize();
				F32 mass = static_cast<ShapeBaseData*>(pSB->getDataBlock())->mass;
				force += distVec * (6.67E-11 * mass * mRigid.mass) / (dist * dist);
				setMaskBits(PositionMask);
			}
		}
	}
}
#13
07/20/2003 (12:16 pm)
*sigh*
I'm still working with this gravity code and still having a few problems with it. Its working, yet not quite right yet. The code I listed above was having some issues because it was trying to update client vehicle forces but the "GravityWells" group which holds the objects to exert gravity is only created in the mission file and on the server.... I'll post my corrections when I complete this.

Note * - the code above has been edited and works, but it now only updates the forces on server objects and then tells the server to update the client positions through the network... I'm still working on a better solution. I want the clients to calculate the same forces as the server to minimize network requirements, but the ghosted gravity well objects are not associated with the server "gravitywells" mission group, so the code has a problem when a flyingvehicle is used as a gravitywell right now.
#15
07/21/2003 (9:31 am)
Hehe, yes, he has, it's the above snipit I posted there ;))
should have added a comment that Jim is the author, maybe ;)
#16
07/21/2003 (10:32 am)
Lol. Wow, I'm famous.

Stefan, please note that I've edited the original code a little... the original one on tork.zenkel.com has a bug where the force is not correct... without parenthesis in the proper line the forces are effectively created without taking distance into consideration. Gravity works sorta cool that way, but it wasn't accurate... The code also works better if it only acts on serverobjects and then updates positionmask to let the clients know about it (for now). I'm trying to write it in a better way for the clients to perform the same calculation so that they can simulate the ghost vehicles accurately. I'll continue to post things here as I figure this out.
#17
07/21/2003 (10:39 am)
Ooops, I thought it was too much of a coincidence, damn :)
--> here we have a guy looking for gravity wells ideas, and boom, there is something about it in the Snipits DB, posted by Beffy who hadn't yet posted to this thread...
I bow my head in shame ;)
#18
07/21/2003 (10:48 am)
Hehe, no problem, Nicolas ;)
Jim: I've updated the code on our site and added your name :)
#19
07/21/2003 (11:02 am)
Gracias senior, but the code I see via the link above doesn't match my current version :p
#20
07/21/2003 (11:18 am)
Jim, I'd recommend doing it so that your gravity well is simply an object that applies a given force if the centroid of the object (any object) is within a distance of the gravity center (actually use the magnitude squared to save a bit of calculation).

You do it for the gravity well rather than the object, because as you say, if you have more objects, they'd all be checking, rather than for the few gravity objects doing the check (so basically you want the thing thats rarer to do the checking in general)

Create a simobject thats just a gravity sphere (kinda like a spawnsphere, try deriving from that?) and place that in the universe. If you want to get a bit more funky, try making a sphere-tree, which will maybe be overkill depending on the numbers of objects.

I'm planning on using a sphere tree for my collisions, so adding gravity objects into that is relatively painless for me.

Phil.
Page «Previous 1 2