Point gravity black hole gravity source

Hello!



I have searched in the forum by keyword gravity and read tens topic… and found many examples about my problem for jme1 & jme2 but not for jme3.



So, I want to create custom gravity point. I’m creating the earth and I need users stay on the earth… gravity should be right in the center of the sphere but I can’t get in how ???



I know about http://code.google.com/p/jbullet-jme/





Maybe someone can write few line sample code ? please :slight_smile:

You just update the gravtitation vector each frame based on the location relative to the center. So something like rigidBody.setGravity(planetCenter-objectLocation)

Yep, I knew it :slight_smile: Thank you.



I was hoping that there were already optimized classes

My task: User that moving on the sphere.



I’m using CharacterControl.



I need to know how to apply dynamic vector



The problem is: CharacterControl always falls down. I can’t change setGravity vector.



Please help monkeys 8) :wink: :slight_smile:





My code is:



public void simpleInitApp() {

userNode = new Node(“user”);



bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);



/*

  • The Earth’s physics

    /

    map = new Earth(assetManager);

    //CollisionShape sceneShape = CollisionShapeFactory.createMeshShape((Node) map);

    SphereCollisionShape sceneShape = new SphereCollisionShape(10f);

    earthRigid = new RigidBodyControl(sceneShape, 0);

    map.addControl(earthRigid);





    /

  • Character physics

    */

    CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);

    player = new CharacterControl(capsuleShape, 0.05f);



    player.setPhysicsLocation(new Vector3f(0, map.radius()*2, 0));

    //player.setJumpSpeed(10);

    //player.setFallSpeed(10);

    player.setGravity(speed);

    rootNode.attachChild(map);



    bulletAppState.getPhysicsSpace().add(earthRigid);

    bulletAppState.getPhysicsSpace().add(player);





    }













    public void simpleUpdate(float tpf) {

    Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);

    Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);



    walkDirection.set(0, 0, 0);

    if (left) { walkDirection.addLocal(camLeft); }

    if (right) { walkDirection.addLocal(camLeft.negate()); }

    if (up) { walkDirection.addLocal(camDir); }

    if (down) { walkDirection.addLocal(camDir.negate()); }

    player.setWalkDirection(walkDirection);

    cam.setLocation(player.getPhysicsLocation());



    bulletAppState.getPhysicsSpace().setGravity(map.getLocalTranslation().subtract(player.getPhysicsLocation()));



    }

Doesn’t work with CharacterControl.

Maybe you could simulate gravity by applying a force to your object that is pointed in the right direction. That’s all gravity is anyway, right?



Edit: Also, the force needs to be proportional to the mass of each object.

Just use setGravity(), its in fact nothing else than a force each tick as you say. Also gravity does not need to be proportional for every object.

Normen , I need to direct the gravity for my CharacterControl in the center of the sphere. (Like my CharacterControl on the Earth)



without this my CharacterControl goes down, but it should stay on the surface.

I have estimated JavaDoc API and Source code and I can’t see any easy way to do it.



>Just use setGravity()

from JavaDoc: public void setGravity(float value)



So it will only change the force, not a direction.





Maybe you could simulate gravity by applying a force to your object that is pointed in the right direction.

suddenastronaut Can you link me to any method in CharacterControl ? Can’t see anything like impulse, force etc





Many THANKS!

@normen said:
Doesn't work with CharacterControl.

normen, yes I understand. but can you suggest any other way as core developer ? :slight_smile:

That I am a core developer doesn’t mean that I have to solve your problems or write your games.

Either you are interested in physically “realistic” movement and you use RigidBodies or you just simulate the movement by moving a kinematic RigidBody. Just do a PhysicsSpace.rayTest downwards to check where it collides with the planet and put it there. Or look at the source of the character in bullet and try to do the same (its using a ghost object and kinematic object to check for collisions).

That I am a core developer doesn’t mean that I have to solve your problems or write your games.


Note that I have asked suggestion but not solve my problems etc :) anyway NP

For PhysicsSpace.rayTest and ghost object, kinematic object many thanks!


BTW I have found maybe bug maybe something other... can you help me ?

For example:
1. Copy&Paste https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:beginner:hello_terrain
2. Go to the map corner
3. You will see easy map vibration.

For example 2:
1. Copy&Paste https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:beginner:hello_physics
2. Add CharacterControl
3. Go to the map corner
4. You will see hard map vibration.

I think for others samples this is true too.

Thanks

UPDATE* - But if I use CollisionShapeFactory - vibration is almost invisible.



http://www.youtube.com/watch?v=1P2EAbiNud8



[java]package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import java.util.ArrayList;
import java.util.List;
import jme3tools.converters.ImageToAwt;

/**
* This demo shows a terrain with collision detection,
* that you can walk around in with a first-person perspective.
* This code combines HelloCollision and HelloTerrain.
*/
public class Main extends SimpleApplication implements ActionListener {

private BulletAppState bulletAppState;
private RigidBodyControl landscape;
private CharacterControl player;
private Vector3f walkDirection = new Vector3f();
private boolean left = false, right = false, up = false, down = false;
private TerrainQuad terrain;
private Material mat_terrain;

public static void main(String[] args) {
Main app = new Main();
app.start();
}

@Override
public void simpleInitApp() {
/** Set up Physics */
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);

flyCam.setMoveSpeed(100);
setUpKeys();

/** 1. Create terrain material and load four textures into it. */
mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");

/** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */
mat_terrain.setTexture("Alpha", assetManager.loadTexture( "Textures/Terrain/splat/alphamap.png"));

/** 1.2) Add GRASS texture into the red layer (Tex1). */
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
grass.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex1", grass);
mat_terrain.setFloat("Tex1Scale", 64f);

/** 1.3) Add DIRT texture into the green layer (Tex2) */
Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
dirt.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex2", dirt);
mat_terrain.setFloat("Tex2Scale", 32f);

/** 1.4) Add ROAD texture into the blue layer (Tex3) */
Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
rock.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex3", rock);
mat_terrain.setFloat("Tex3Scale", 128f);

/** 2. Create the height map */
AbstractHeightMap heightmap = null;
Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
heightmap = new ImageBasedHeightMap(
ImageToAwt.convert(heightMapImage.getImage(), false, true, 0));
heightmap.load();

/** 3. We have prepared material and heightmap.
* Now we create the actual terrain:
* 3.1) Create a TerrainQuad and name it "my terrain".
* 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65.
* 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513.
* 3.4) As LOD step scale we supply Vector3f(1,1,1).
* 3.5) We supply the prepared heightmap itself.
*/
terrain = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap());

/** 4. We give the terrain its material, position & scale it, and attach it. */
terrain.setMaterial(mat_terrain);
terrain.setLocalTranslation(0, -100, 0);
terrain.setLocalScale(2f, 1f, 2f);
rootNode.attachChild(terrain);

/** 5. The LOD (level of detail) depends on were the camera is: */
List<Camera> cameras = new ArrayList<Camera>();
cameras.add(getCamera());
TerrainLodControl control = new TerrainLodControl(terrain, cameras);
terrain.addControl(control);

/** 6. Add physics: */
// We set up collision detection for the scene by creating a
// compound collision shape and a static RigidBodyControl with mass zero.*/
CollisionShape terrainShape = CollisionShapeFactory.createMeshShape((Node) terrain);
landscape = new RigidBodyControl(terrainShape, 0);
terrain.addControl(landscape);

// We set up collision detection for the player by creating
// a capsule collision shape and a CharacterControl.
// The CharacterControl offers extra settings for
// size, stepheight, jumping, falling, and gravity.
// We also put the player in its starting position.
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
player = new CharacterControl(capsuleShape, 0.05f);
player.setJumpSpeed(20);
player.setFallSpeed(30);
player.setGravity(30);
player.setPhysicsLocation(new Vector3f(0, 10, 0));

// We attach the scene and the player to the rootnode and the physics space,
// to make them appear in the game world.
bulletAppState.getPhysicsSpace().add(terrain);
bulletAppState.getPhysicsSpace().add(player);

}
/** We over-write some navigational key mappings here, so we can
* add physics-controlled walking and jumping: */
private void setUpKeys() {
inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, "Left");
inputManager.addListener(this, "Right");
inputManager.addListener(this, "Up");
inputManager.addListener(this, "Down");
inputManager.addListener(this, "Jump");
}

/** These are our custom actions triggered by key presses.
* We do not walk yet, we just keep track of the direction the user pressed. */
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Left")) {
if (value) { left = true; } else { left = false; }
} else if (binding.equals("Right")) {
if (value) { right = true; } else { right = false; }
} else if (binding.equals("Up")) {
if (value) { up = true; } else { up = false; }
} else if (binding.equals("Down")) {
if (value) { down = true; } else { down = false; }
} else if (binding.equals("Jump")) {
player.jump();
}
}

/**
* This is the main event loop--walking happens here.
* We check in which direction the player is walking by interpreting
* the camera direction forward (camDir) and to the side (camLeft).
* The setWalkDirection() command is what lets a physics-controlled player walk.
* We also make sure here that the camera moves with player.
*/
@Override
public void simpleUpdate(float tpf) {
Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
walkDirection.set(0, 0, 0);
if (left) { walkDirection.addLocal(camLeft); }
if (right) { walkDirection.addLocal(camLeft.negate()); }
if (up) { walkDirection.addLocal(camDir); }
if (down) { walkDirection.addLocal(camDir.negate()); }
player.setWalkDirection(walkDirection);
cam.setLocation(player.getPhysicsLocation());
}
}[/java]