Package com.aqpproject.physics.gdx

Source Code of com.aqpproject.physics.gdx.PhysicsGDX

/*
* AQP Project
* http://http://code.google.com/p/aqp-project/
* Alexandre Gomez - Clément Troesch - Fabrice Latterner
*/
package com.aqpproject.physics.gdx;

import com.aqpproject.game.Singleton;
import com.aqpproject.physics.Physics;
import com.aqpproject.tools.Segment2D;
import com.aqpproject.tools.Vector2D;
import com.aqpproject.visualisation.Visualisation;
import com.aqpproject.worldmodel.WorldModel;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Shape.Type;
import com.badlogic.gdx.physics.box2d.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
* GDX Physics component
*
* @author Alexandre, Clement, Fabrice
*/
public class PhysicsGDX implements Physics {

    @Override
    public void initialize() {

        m_world = new World(new Vector2(0, 0), true);
        m_bodies = new HashMap<>();
        m_mapBodies = new ArrayList<>();
        m_segments = new HashMap<>();
        m_debugSegments = new ArrayList<>();
        m_bodiesSizes = new HashMap<>();
        m_active = false;
        m_positionsToModify = new HashMap<>();
        m_velocitiesToModify = new HashMap<>();
        m_rotationToModify = new HashMap<>();
        m_isPaused = false;

        m_world.setContactListener(new ContactListener() {

            @Override
            public void beginContact(Contact cntct) {
                WorldManifold wm = cntct.getWorldManifold();
                Singleton.getWorldModel().startContact(cntct.getFixtureA().getBody().getUserData().toString(), cntct.getFixtureB().getBody().getUserData().toString(), toVector2D(wm.getNormal()), toVector2D(wm.getPoints()[0]).scale(PIXELS_PER_METERS));

            }

            @Override
            public void endContact(Contact cntct) {
                WorldManifold wm = cntct.getWorldManifold();
                Singleton.getWorldModel().stopContact(cntct.getFixtureA().getBody().getUserData().toString(), cntct.getFixtureB().getBody().getUserData().toString(), toVector2D(wm.getNormal()), toVector2D(wm.getPoints()[0]).scale(PIXELS_PER_METERS));
            }

            @Override
            public void preSolve(Contact cntct, Manifold mnfld) {
            }

            @Override
            public void postSolve(Contact cntct, ContactImpulse ci) {
            }
        });
    }

    @Override
    public void destroy() {
    }

    @Override
    public void createBody(String name, Vector2D position, float rotation, Vector2D size, float density, float linearDamping, float angularDamping) {

        /*
         * BodyDef Creation
         */
        BodyDef bodydef = new BodyDef();
        bodydef.type = BodyDef.BodyType.DynamicBody;
        bodydef.position.set(position.x / PIXELS_PER_METERS, position.y / PIXELS_PER_METERS);
        bodydef.awake = false;
        Body body = m_world.createBody(bodydef);
        body.setUserData(name);

        /*
         * Shape creation
         */
        PolygonShape shape = new PolygonShape();
        Vector2 pos = new Vector2(size.x / (2.f * PIXELS_PER_METERS), size.y / (2.f * PIXELS_PER_METERS));
        shape.setAsBox(size.x / (2.f * PIXELS_PER_METERS), size.y / (2.f * PIXELS_PER_METERS), pos, 0);

        m_bodiesSizes.put(name, new Vector2D(size));

        /*
         * Body Creation
         */
        body.createFixture(shape, density);
        shape.dispose();

        body.setLinearVelocity(0, 0);
        body.setLinearDamping(linearDamping);
        body.setAngularDamping(angularDamping);

        body.setTransform(position.x / PIXELS_PER_METERS, position.y / PIXELS_PER_METERS, (float) (rotation * Math.PI / 180f));

        m_bodies.put(name, body);

    }

    @Override
    public void createMapBodies() {

        for (int x = 0; x < Singleton.getVisualisation().getMapWidth(); x++) {
            for (int y = 0; y < Singleton.getVisualisation().getMapHeight(); y++) {

                int id = Singleton.getVisualisation().getTile(Visualisation.MAP_LAYER.STATIC_OBJECTS, new Vector2D(x * 64, y * 64));
                String code = "" + id;

                if (m_segments.containsKey(code)) {
                    ArrayList<Segment2D> segments = m_segments.get(code);

                    for (Segment2D seg : segments) {

                        /*
                         * BodyDef Creation
                         */
                        BodyDef bodydef = new BodyDef();
                        bodydef.type = BodyDef.BodyType.StaticBody;
                        Body body = m_world.createBody(bodydef);
                        body.setUserData("StaticBody");

                        /*
                         * Shape creation
                         */
                        EdgeShape shape = new EdgeShape();
                        Vector2 first = toVector2(new Vector2D(seg.getFirst()).translate((x) * 64, (y) * 64).scale(1.f / PIXELS_PER_METERS));
                        Vector2 second = toVector2(new Vector2D(seg.getSecond()).translate((x) * 64, (y) * 64).scale(1.f / PIXELS_PER_METERS));
                        shape.set(first, second);

                        /*
                         * Body Creation
                         */
                        body.createFixture(shape, 0);
                        shape.dispose();

                        m_debugSegments.add(new Segment2D(new Vector2D(seg.getFirst()).translate((x) * 64, (y) * 64), new Vector2D(seg.getSecond()).translate((x) * 64, (y) * 64)));


                        m_mapBodies.add(body);
                    }

                }


            }
        }



    }

    @Override
    public void deleteBody(String name) {
        m_world.destroyBody(m_bodies.get(name));
        m_bodies.remove(name);
    }

    @Override
    public void deleteMapBodies() {
        while (!m_mapBodies.isEmpty()) {
            m_world.destroyBody(m_mapBodies.get(0));
            m_mapBodies.remove(0);
        }
    }

    @Override
    public void applyLinearForce(String name, Vector2D vel) {
        m_bodies.get(name).applyForceToCenter(toVector2(new Vector2D(vel).scale(1.f / PIXELS_PER_METERS)));
    }

    @Override
    public void applyAngularForce(String name, float vel) {
        m_bodies.get(name).applyTorque(vel);
    }

    @Override
    public Vector2D getBodyPosition(String name) {
        return toVector2D(m_bodies.get(name).getPosition()).scale(PIXELS_PER_METERS);
    }

    @Override
    public void setBodyPosition(String name, Vector2D position) {
        Vector2 pos = toVector2(new Vector2D(position).scale(1.f / PIXELS_PER_METERS));
        float rotation = m_bodies.get(name).getAngle();
        m_bodies.get(name).setTransform(pos, rotation);
    }

    @Override
    public void resetBody(String name, Vector2D position, Vector2D velocity, float rotation) {
        m_positionsToModify.put(name, position);
        m_velocitiesToModify.put(name, velocity);
        m_rotationToModify.put(name, rotation);
    }

    private void updateBodyPosition() {
        while (!m_positionsToModify.isEmpty()) {
            String name = m_positionsToModify.keySet().iterator().next();
            Vector2D position = m_positionsToModify.remove(name);
            Vector2D velocity = m_velocitiesToModify.remove(name);
            float rotation = m_rotationToModify.remove(name);
            if (m_bodies.containsKey(name)) {
                Vector2 pos = toVector2(new Vector2D(position).scale(1.f / PIXELS_PER_METERS));
//                float rotation = m_bodies.get(name).getAngle();
                m_bodies.get(name).setTransform(pos, rotation);
                m_bodies.get(name).setLinearVelocity(toVector2(new Vector2D(velocity).scale(1.f / PIXELS_PER_METERS)));
            }
        }
    }

    @Override
    public Vector2D getBodyCenter(String name) {
        Body body = m_bodies.get(name);
        Vector2D size = m_bodiesSizes.get(name);
        return toVector2D(body.getTransform().mul(new Vector2(size.x / (PIXELS_PER_METERS * 2.f), size.y / (PIXELS_PER_METERS * 2.f)))).scale(PIXELS_PER_METERS);
    }

    @Override
    public float getBodyRotation(String name) {
        return (float) (m_bodies.get(name).getAngle() * 180.f / Math.PI);
    }

    @Override
    public Vector2D getLinearVelocity(String name) {
        return toVector2D(m_bodies.get(name).getLinearVelocity()).scale(PIXELS_PER_METERS);
    }

    @Override
    public void setLinearVelocity(String name, Vector2D velocity) {
        m_bodies.get(name).setLinearVelocity(toVector2(new Vector2D(velocity).scale(1.f / PIXELS_PER_METERS)));
    }

    @Override
    public void setDampling(String name, float linearDamping, float angularDamping) {
        m_bodies.get(name).setLinearDamping(linearDamping);
        m_bodies.get(name).setAngularDamping(angularDamping);
    }

    @Override
    public void update() {
        if (m_active && !m_isPaused) {
            updateBodyPosition();
            m_world.step(1.f / WorldModel.UPDATE_RATE, 8, 8);
        }
    }

    @Override
    public void loadPhysicsTiles(String path) throws ParserConfigurationException, IOException, SAXException {
        File file = new File(path);
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = builder.parse(file);
        doc.getDocumentElement().normalize();

        Element root = doc.getDocumentElement();
        NodeList children = root.getChildNodes();

        for (int i = 0; i < children.getLength(); i++) {
            Node n = children.item(i);
            if (n.getNodeType() == Node.ELEMENT_NODE) {
                Element e = (Element) n;
                String id = e.getAttribute("id");
                m_segments.put(id, new ArrayList<Segment2D>());
                for (int j = 0; j < e.getChildNodes().getLength(); j++) {
                    if (e.getChildNodes().item(j).getNodeType() == Node.ELEMENT_NODE) {
                        Element seg = (Element) e.getChildNodes().item(j);
                        int x1 = Integer.parseInt(seg.getAttribute("x1"));
                        int y1 = 64 - Integer.parseInt(seg.getAttribute("y1"));
                        int x2 = Integer.parseInt(seg.getAttribute("x2"));
                        int y2 = 64 - Integer.parseInt(seg.getAttribute("y2"));
                        m_segments.get(id).add(new Segment2D(x1, y1, x2, y2));
                    }
                }
            }

        }
    }

    @Override
    public ArrayList<Segment2D> getDebugSegments() {
        ArrayList<Segment2D> result = new ArrayList<>();
        result.addAll(m_debugSegments);

        if (m_bodies != null) {
            for (String s : m_bodies.keySet()) {
                ArrayList<Vector2> vertices = new ArrayList<>();
                Body body = m_bodies.get(s);
                for (Fixture fixture : body.getFixtureList()) {

                    if (fixture != null && fixture.getType() == Type.Polygon) {
                        PolygonShape shape = (PolygonShape) fixture.getShape();
                        for (int i = 0; i < shape.getVertexCount(); i++) {
                            Vector2 vec = new Vector2();
                            shape.getVertex(i, vec);
                            vertices.add(body.getTransform().mul(vec));
                        }

                        for (int i = 0; i < vertices.size(); i++) {
                            Vector2D a;
                            Vector2D b;
                            if (i == vertices.size() - 1) {
                                a = toVector2D(vertices.get(i)).scale(PIXELS_PER_METERS);
                                b = toVector2D(vertices.get(0)).scale(PIXELS_PER_METERS);;
                            } else {
                                a = toVector2D(vertices.get(i)).scale(PIXELS_PER_METERS);;
                                b = toVector2D(vertices.get(i + 1)).scale(PIXELS_PER_METERS);;
                            }
                            result.add(new Segment2D(a, b));
                        }

                    }
                }


            }

        }

        return result;

    }

    @Override
    public void setActive(boolean value) {
        m_active = value;
    }

    @Override
    public boolean isWorldLocked() {
        return m_world.isLocked();
    }

    @Override
    public void setPause(boolean pause) {
        m_isPaused = pause;
    }

    @Override
    public boolean isPaused() {
        return m_isPaused;
    }

    /////////////////////////////////////////
    // Statics
    /////////////////////////////////////////
    private static Vector2D toVector2D(Vector2 v) {
        return new Vector2D(v.x, v.y);
    }

    private static Vector2 toVector2(Vector2D v) {
        return new Vector2(v.x, v.y);
    }

    public void setRotation(String s, float r) {
        m_bodies.get(s).setTransform(m_bodies.get(s).getPosition().x, m_bodies.get(s).getPosition().y, (float) (r * Math.PI) / 180.0f);
    }

    public void setBodyActive(String s, boolean b) {
        if (m_bodies.containsKey(s)) {
            m_bodies.get(s).setActive(b);

        }
    }
    /////////////////////////////////////////
    // Attributes
    /////////////////////////////////////////
    private World m_world;
    private HashMap<String, Body> m_bodies;
    private HashMap<String, Vector2D> m_bodiesSizes;
    private ArrayList<Body> m_mapBodies;
    private HashMap<String, ArrayList<Segment2D>> m_segments;
    private static int PIXELS_PER_METERS = 100;
    private ArrayList<Segment2D> m_debugSegments;
    private boolean m_active;
    private HashMap<String, Vector2D> m_positionsToModify;
    private HashMap<String, Vector2D> m_velocitiesToModify;
    private HashMap<String, Float> m_rotationToModify;
    private boolean m_isPaused;
}
TOP

Related Classes of com.aqpproject.physics.gdx.PhysicsGDX

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.