Singularity or Gravitational Vertex

I’ve noticed that in JME3, when setting gravity it is done as a sort of “down” vector orthogonal to a given plane.

Is there a way to add a single vertex/spatial to the scene graph (or PhysicsSpace) as a gravitational singularity… hence all inherited objects of the singularity would be pulled toward it?

This would lead to creating the stereotypical “walk around a moon” physics. The idea would then be to construct a spherical terrain as the “floor.”

Thanks,

Chenz

1 Like

When I was trying to do space game, i was thinking about it too.

Is it much different than computing & applying central force each physics tick?

How can I get stable (enough so player does not notice if he leave game runnig reasonable time) simulation of orbiting objects?

a] around static mass

b] 2 objects orbiting each other

for 2 bodies:

Only thing that I managed to think of, is computing analyticaly trajectory, make it move along it as long as no other force is applyed.

for n bodies:

If one is much more significant than others, use 2 bodies solution, otherwise use leave it be affected each step (player does not know correct answer, so he cannot be sure it is wrong, as long as its not wrong MUCH.

But I havent implemented anything yet, because

1. I don’t know whether it is right direction
2. I cannot get into the right mood lately

Yeah, you can set the gravity for each object. So by changing it dynamically based on the location relative to the singularity you can.

I guess I was hoping, more of that dynamic-ness could be handled by the game engine. Oh well.

Its a very simple control that you only have to write once. Just use a GhostControl and check the overlapping objects, then set the gravity based on the location of the object and vortex? Thats 10 lines of code, whats so hard about that?

Yeah, gravity simply is a vector thats applied to the body on each update so its exactly what you all need really.

normen said:
Its a very simple control that you only have to write once. Just use a GhostControl and check the overlapping objects, then set the gravity based on the location of the object and vortex? Thats 10 lines of code, whats so hard about that?

I agree its a one time control.... I'm just new to game dev physics and that 10 lines will take me awhile to figure out. Thanks for the pointer about using a Control though, I was hunting for a "physics listener."
normen said:
Its a very simple control that you only have to write once. Just use a GhostControl and check the overlapping objects, then set the gravity based on the location of the object and vortex? Thats 10 lines of code, whats so hard about that?

I threw this together just before hitting the road... no testing or building it yet. Is this the kind of thing you were referring to?

[java]public class MyCustomControl extends GhostControl implements PhysicsTickListener
{
Vector3f gravity_location;

@override
public void physicsTick(PhysicsSpace space, float f){
// Get overlapping objects
List<PhysicsCollisionObject> obj_list = this.getOverlappingObjects();

// Iterate through each object
for(Iterator<PhysicsCollisionObject> i = obj_list.iterator(); i.hasNext(); ) {
PhysicsCollisionObject obj_entry = (PhysicsCollisionObject) i.next();
Vector3f location = obj_entry.getUserObject().getLocation();

// Determine new gravity vector
Vector3f new_gravity = new Vector3f(
gravity_location.getX() - location.getX(),
gravity_location.getY() - location.getY(),
gravity_location.getZ() - location.getZ());

obj_entry.setGravity(new_gravity);
}

System.out.println("Item Count = " + obj_list.size());
}
}[/java]

Thanks,
Chenz

Alright… so for those who are interested… this works:

[java]package jme3test.helloworld;

import com.jme3.bullet.control.GhostControl;

import com.jme3.math.Vector3f;

import com.jme3.bullet.collision.PhysicsCollisionObject;

import java.util.List;

import java.util.Iterator;

import com.jme3.scene.Spatial;

import com.jme3.bullet.collision.shapes.CollisionShape;

import com.jme3.bullet.control.RigidBodyControl;

/**

*

• @author chenz

*/

public class GravityControl extends GhostControl

{

Vector3f gravity_location;

float gravity;

GravityControl(CollisionShape s)

{

super(s);

this.gravity_location = Vector3f.ZERO;

}

GravityControl(CollisionShape s, Vector3f vec)

{

super(s);

this.gravity_location = vec;

}

void setGravity(float g) {

this.gravity = g;

}

public void update(float tpf) {

super.update(tpf);

if (!enabled) {

return;

}

if (getOverlappingCount() > 0) {

List<PhysicsCollisionObject> objects = getOverlappingObjects();

for (Iterator<PhysicsCollisionObject> it = objects.iterator(); it.hasNext() {

PhysicsCollisionObject physicsCollisionObject = it.next();

Spatial targetEntity = (Spatial) physicsCollisionObject.getUserObject();

if (targetEntity != null && targetEntity.getUserData("CollisionObject") != null) {

RigidBodyControl field =

(RigidBodyControl) targetEntity.getUserData("CollisionObject");

Vector3f location = targetEntity.getWorldTranslation();

Vector3f new_gravity = new Vector3f(

gravity_location.getX() - location.getX(),

gravity_location.getY() - location.getY(),

gravity_location.getZ() - location.getZ()).normalize();

field.setGravity(new_gravity.mult(this.gravity));

}

}

}

}

}

[/java]
1 Like