@@ 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();
+ }
+
+}