Nodes, Greometry, Physics & CamNodes

Hi!

I don’t really understand how Nodes, Greometry, Physics & CamNodes are supposed to work together (and also why Geometry doesn’t extend Node), so probably I am using at least one of those in a fundamentally wrong way :wink:

Example: I have a Ball with physics. It is steered by applying torque (from player input). Now the Ball node does not move with the Ball… but it also looks like I shouldn’t p.E. attach a camera node to the Ball Geometry and I guess I’m not supposed to make a Node with physics either…? So… uhm… am I supposed to make nodes of an actor stay with the geometry that has the physics by resetting their coordinates… or what?

Now the Ball node does not move with the Ball

So your ball is a child of the ball node? then correct, it shouldn’t move the parent, if the ball moves. A parent will move all its children, not the other way round.

I think you need to go through the beginner tutorials a few more times, until you understand the full concept of the scene graph.

Couldn’t find anything that helps in the Tutorials or source.

I understand that the ball isn’t supposed to move its parent node (in general, at least). But then how am I supposed to have something (like p.E. a camera) move with the ball (its physics enabled geometry)? Do I attach it to the ball’s node anyway and then in the update loop set its local position from there to follow the geometry manually? If I do it like that, then the ball + cam will be so “far away + totally unrelated” from the ball node after a while that the ball node becomes useless and I could have just as well attached everything directly to the root node.

<cite>@meho said:</cite> Couldn't find anything that helps in the Tutorials or source.

I understand that the ball isn’t supposed to move its parent node (in general, at least). But then how am I supposed to have something (like p.E. a camera) move with the ball (its physics enabled geometry)? Do I attach it to the ball’s node anyway and then in the update loop set its local position from there to follow the geometry manually? If I do it like that, then the ball + cam will be so “far away + totally unrelated” from the ball node after a while that the ball node becomes useless and I could have just as well attached everything directly to the root node.

Then why did you have the ball node in the first place? Or why are you moving the geometry instead of the node?

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:scenegraph_for_dummies

I’m moving the geometry instead of the node, because I’m moving it (the ball) by applying torque (and I guess I shouldn’t be creating a “physics enabled node” because that would be silly?).

And I created the node, because I can’t attach anything to a geometry, but I’d like to have stuff (among other things a camera) move with the ball.

And now I’m not sure what to do with the node and the ball. The easiest solution would probably be not to attach the ball to the node at all, but instead to have the node follow the ball around by changing its position in the update loop. But that solution sounds sort of… like a glitch-magnet to me… or is that how it’s supposed to be done?

(and I guess I shouldn’t be creating a “physics enabled node” because that would be silly?).

Actually doing that is fine. For instance if you have a few geometries in a node, and want a single simple collisionshape around that, you would attach it to the node for instance.

But what you want is some sort of hybrid, having a node with physics and non-physics spatials. Then when a child moves (whether its the physics or non-physics control), you want the rest of the nodes children to follow it. Easiest way would be to have a separate sub-node with everything else in it, and add a control to move it with the ball (essentially what the cam node does)

Oh, thanks! Didn’t realize, stuff like that is “ok”… now I’m just still not sure where to put all the “stuff”.

Is it a very bad idea, to create such “hybrid” objects as an “Actor.class” with its own update method and have the simple update loop over all of those “actors” after they register themselves in a “global” array (in addition to attaching themselves to the root node + their associated collision shape with physicsspace)? Then I can just extend Node, put a “public Geometry the_ball_this_invisible_actor_is_sitting_on” in it and have the “actor node” follow this Geometry inside its own update methode…

If I modify my already existing “Actor.class” like that…: [java]
package mygame;

import com.jme3.asset.TextureKey;
import com.jme3.bullet.collision.shapes.MeshCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.Node;

public class Actor extends Node {
boolean _active = false;
public Shape _shape;
public float _size;
public Material _material;
public Vector3f _angularForce= new Vector3f();
public Vector3f _linearForce= new Vector3f();
public Geometry _body;
public RigidBodyControl _physics;
public float _speed=1.0f;

Actor() {
	this(1.0f);
}

Actor(float size) {
	this(Shape.BALL, size);
}

Actor(Shape shape) {
	this(shape, 1.0f);
}

Actor(Shape shape, Material mat) {
	this(shape, 1.0f, mat);
}

Actor(Shape shape, float size) {
	this (shape, size, World.defaultMat());
}

Actor(Shape shape, float size, Material mat) {
	_size = size;
	_shape= shape;
	_material = mat;
	setShape(shape);
    _body.setMaterial(_material);
	_physics=_body.getControl(RigidBodyControl.class);
	_physics.setDamping(0.5f, 0.5f);
	_physics.setFriction(0.8f);
	World._root.attachChild(this);
	Start();
}

void setSize(float size) {
	_size = size;
}

void setShape(Shape shape) {
	_shape=shape;
    switch (_shape) {	
        case PLANE:
			Box floor = new Box(Vector3f.ZERO, 100, 1f, 100);
			_body = new Geometry("Floor", floor);
			_body.setLocalTranslation(new Vector3f(0f, -3, 0f));
			_body.addControl(new RigidBodyControl(new MeshCollisionShape(_body.getMesh()), 0));                
		break;
			
        case BALL:
			Sphere sphere = new Sphere(16, 16, .5f);
			_body  = new Geometry("Ball", sphere);
			_body .setLocalTranslation(1, 1, 1);
			_body .addControl(new RigidBodyControl(.001f));
			_physics=_body.getControl(RigidBodyControl.class);
			_physics.setMass(1.0f);
			_physics.setRestitution(0.8f);
		break;
			
		case CUBE:
			break;
	}
	attachChild(_body);
	Restart();
}

void update(float tpf) {
	if (_active) {
		_physics.applyTorque(_angularForce.mult(tpf * 100 * _speed));
		_physics.applyCentralForce(_linearForce.mult(tpf * 100 * _speed));
	}
	setLocalTranslation(_body.getLocalTranslation());
}

void Start() {
    if (!World._actors.contains(this)) {
		World.AddActor(this);}
	if (!_active) {
		_active=true;
		World._space.add(_body);
		World._root.attachChild(_body);
	}
}

void Stop() {
	if (_active) {
		_active=false;
		World._space.remove(_body);
		World._root.detachChild(_body);
	}
}

void Destroy() {
	Stop();
    World.RemoveActor(this);
}

void Restart() {
	Stop();
    Start();
}

}[/java]
…It works fine. Fits “great” to my World.class (which most likely is an Abomination in itself already :3). Somehow I can’t shake the feeling that I’m doing this all wrong?

Also I’d guess this probably will kill any cpu pretty soon if I continue to throw around dynamic physics actors like that?

(oops, sry, this looks longer than I thought now that it’s in the browser. This forum needs a preview function ;))

Tried around some more…

While this way of doing it seems to work so far, it also seems to get messier very fast. I’d recommend anyone who does not absolutely want/need to steer with real physics to instead try using some sort of fake “decorative physics object” that’s only for show while really steering the node (if I’m not mistaken, the “vehicle control class” does it like that. I wasn’t quite happy with the result of "normal node moving + decorative fake physics-ball), but for most purposes, that should be enough and a lot less messy.