added Box2DControllerTest
A => core/src/net/dermetfan/someLibgdxTests/screens/Box2DControllerTest.java +188 -0
@@ 0,0 1,188 @@ 
+package net.dermetfan.someLibgdxTests.screens;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.InputAdapter;
+import com.badlogic.gdx.InputMultiplexer;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
+import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
+import com.badlogic.gdx.math.MathUtils;
+import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.physics.box2d.Body;
+import com.badlogic.gdx.physics.box2d.BodyDef;
+import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
+import com.badlogic.gdx.physics.box2d.EdgeShape;
+import com.badlogic.gdx.physics.box2d.PolygonShape;
+import com.badlogic.gdx.physics.box2d.joints.MouseJointDef;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.InputListener;
+import com.badlogic.gdx.scenes.scene2d.Stage;
+import com.badlogic.gdx.scenes.scene2d.ui.Container;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+import com.badlogic.gdx.scenes.scene2d.ui.Skin;
+import com.badlogic.gdx.scenes.scene2d.utils.UIUtils;
+import net.dermetfan.gdx.physics.box2d.Box2DUtils;
+import net.dermetfan.gdx.physics.box2d.MouseJointAdapter;
+import net.dermetfan.gdx.physics.box2d.PositionController;
+import net.dermetfan.gdx.physics.box2d.RotationController;
+import net.dermetfan.someLibgdxTests.Assets;
+
+public class Box2DControllerTest extends Box2DScreen {
+
+	private final MouseJointAdapter mouseJointAdapter;
+
+	private final Stage stage = new Stage();
+	private final Label info;
+
+	private final Body body;
+	private final Vector2 dest = new Vector2(), rotDest = new Vector2();
+
+	private final PositionController.PD positionController = new PositionController.PD(2000, 200, dest);
+	private final RotationController.PD rotationController = new RotationController.PD(2000, 200, -MathUtils.PI / 2, rotDest);
+
+	private final ShapeRenderer sr = new ShapeRenderer();
+
+	public Box2DControllerTest() {
+		renderer.setDrawVelocities(true);
+
+		info = new Label("", Assets.manager.get(Assets.uiskin, Skin.class));
+		Container<Label> infoContainer = new Container<>(info);
+		infoContainer.setFillParent(true);
+		infoContainer.top().left().pad(5);
+		stage.addActor(infoContainer);
+
+		stage.addListener(new InputListener() {
+			@Override
+			public boolean scrolled(InputEvent event, float x, float y, int amount) {
+				amount = MathUtils.clamp(amount, -1, 1);
+				if(UIUtils.ctrl()) {
+					if(UIUtils.shift())
+						rotationController.setGainD(rotationController.getGainD().floatValue() - amount);
+					else
+						rotationController.setGainP(rotationController.getGainP().floatValue() - amount);
+				} else {
+					if(UIUtils.shift())
+						positionController.getGainD().sub(amount, amount);
+					else
+						positionController.getGainP().sub(amount, amount);
+				}
+				return true;
+			}
+		});
+
+		BodyDef bodyDef = new BodyDef();
+		bodyDef.position.y = -5;
+
+		EdgeShape groundShape = new EdgeShape();
+		groundShape.set(-50, 0, 50, 0);
+		Body ground = world.createBody(bodyDef);
+		ground.createFixture(groundShape, 1);
+		groundShape.dispose();
+
+		Box2DUtils.reset(bodyDef);
+		bodyDef.type = BodyType.DynamicBody;
+
+		Vector2[] vertices = new Vector2[6];
+		for (int i = 0; i < 6; i++) {
+			float angle = -i/6f * 360 * MathUtils.degreesToRadians;
+			vertices[i] = new Vector2(MathUtils.sin(angle), MathUtils.cos(angle));
+		}
+		vertices[0].set(0, 4);
+		PolygonShape shape = new PolygonShape();
+		shape.set(vertices);
+		body = world.createBody(bodyDef);
+		body.createFixture(shape, 1);
+		shape.dispose();
+
+		PositionController.setUserDataAccessor(arg -> arg instanceof PositionController ? (PositionController) arg : arg instanceof Controllers ? ((Controllers) arg).positionController : null);
+		RotationController.setUserDataAccessor(arg -> arg instanceof RotationController ? (RotationController) arg : arg instanceof Controllers ? ((Controllers) arg).rotationController : null);
+
+		body.setUserData(new Controllers(positionController, rotationController));
+
+		MouseJointDef mouseJointDef = new MouseJointDef();
+		mouseJointDef.collideConnected = true;
+		mouseJointDef.maxForce = 5000;
+		mouseJointDef.bodyA = ground;
+		mouseJointAdapter = new MouseJointAdapter(mouseJointDef, true, viewport.getCamera());
+	}
+
+	private static class Controllers {
+
+		PositionController positionController;
+
+		RotationController rotationController;
+
+		public Controllers() {}
+
+		public Controllers(PositionController positionController, RotationController rotationController) {
+			this.positionController = positionController;
+			this.rotationController = rotationController;
+		}
+
+	}
+
+	@Override
+	public void show() {
+		Gdx.input.setInputProcessor(new InputMultiplexer(stage, new InputAdapter() {
+			@Override
+			public boolean touchDown(int screenX, int screenY, int pointer, int button) {
+				if(UIUtils.right()) {
+					Vector2 v = UIUtils.ctrl() ? rotDest : dest;
+					viewport.unproject(v.set(screenX, screenY));
+					return true;
+				}
+				return false;
+			}
+
+			@Override
+			public boolean touchDragged(int screenX, int screenY, int pointer) {
+				if(UIUtils.right()) {
+					Vector2 v = UIUtils.ctrl() ? rotDest : dest;
+					viewport.unproject(v.set(screenX, screenY));
+					return true;
+				}
+				return false;
+			}
+		}, mouseJointAdapter));
+	}
+
+	@Override
+	public void render(float delta) {
+		body.applyForceToCenter(world.getGravity().scl(-1 * body.getMass()), true);
+		PositionController.applyForceToCenter(world, true);
+		RotationController.applyTorque(world, true);
+		super.render(delta);
+		info.setText("dest: right button, rotDest: ctrl + right button\n"
+				+ "position: p: scroll, d: shift + scroll\n"
+				+ "rotation: p: ctrl + scroll, d: ctrl + shift + scroll\n"
+				+ '\n'
+				+ "position: p = " + positionController.getGainP() + ", d = " + positionController.getGainD() + '\n'
+				+ "rotation: p = " + rotationController.getGainP() + ", d = " + rotationController.getGainD() + '\n'
+				+ '\n'
+				+ "gravity: " + world.getGravity() + '\n'
+				+ "mass: " + body.getMass());
+		stage.act(delta);
+		stage.draw();
+		sr.setProjectionMatrix(viewport.getCamera().combined);
+		sr.begin(ShapeType.Filled);
+		sr.setColor(Color.GREEN);
+		sr.circle(dest.x, dest.y, .1f, 10);
+		sr.setColor(Color.YELLOW);
+		sr.circle(rotDest.x, rotDest.y, .1f, 10);
+		sr.end();
+	}
+
+	@Override
+	public void resize(int width, int height) {
+		super.resize(width, height);
+		stage.getViewport().update(width, height, true);
+	}
+
+	@Override
+	public void dispose() {
+		super.dispose();
+		stage.dispose();
+		sr.dispose();
+	}
+
+}

          
M core/src/net/dermetfan/someLibgdxTests/screens/Menu.java +1 -0
@@ 152,6 152,7 @@ public class Menu extends ScreenAdapter 
 		names.add("ArrangeVerticesTest");
 		names.add("IntersectSegmentConvexPolygonTest");
 		names.add("DragAndDropTutorial");
+		names.add("Box2DControllerTest");
 		names.sort();
 
 		final List<String> tests = new List<>(skin);