All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jbox2d.dynamics.WorldView Maven / Gradle / Ivy

The newest version!
/*
 * The MIT License (MIT)
 *
 * FXGL - JavaFX Game Library
 *
 * Copyright (c) 2015-2017 AlmasB ([email protected])
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package org.jbox2d.dynamics;

import com.almasb.fxgl.core.math.Vec2;
import javafx.scene.paint.Color;
import org.jbox2d.callbacks.DebugDraw;
import org.jbox2d.collision.AABB;
import org.jbox2d.collision.shapes.ChainShape;
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.EdgeShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.JBoxSettings;
import org.jbox2d.common.Transform;
import org.jbox2d.dynamics.contacts.Contact;
import org.jbox2d.dynamics.joints.Joint;
import org.jbox2d.dynamics.joints.PulleyJoint;
import org.jbox2d.particle.ParticleColor;
import org.jbox2d.particle.ParticleSystem;
import org.jbox2d.pooling.arrays.Vec2Array;

/**
 * @author Almas Baimagambetov ([email protected])
 */
public class WorldView {

    private DebugDraw debugDraw;
    private World world;

    private final Transform xf = new Transform();
    private final Vec2 cA = new Vec2();
    private final Vec2 cB = new Vec2();
    private final Vec2Array avs = new Vec2Array();

    public WorldView(World world, DebugDraw debugDraw) {
        this.world = world;
        this.debugDraw = debugDraw;
    }

    /**
     * Call this to draw shapes and other debug draw data.
     */
    public void drawDebugData() {
        Color color = Color.color(0, 0, 0);

        int flags = debugDraw.getFlags();
        boolean wireframe = (flags & DebugDraw.e_wireframeDrawingBit) != 0;

        if ((flags & DebugDraw.e_shapeBit) != 0) {
            for (Body b = world.getBodyList(); b != null; b = b.getNext()) {
                xf.set(b.getTransform());
                for (Fixture f : b.getFixtures()) {
                    if (!b.isActive()) {
                        color = Color.color(0.5f, 0.5f, 0.3f);
                        drawShape(f, xf, color, wireframe);
                    } else if (b.getType() == BodyType.STATIC) {
                        color = Color.color(0.5f, 0.9f, 0.3f);
                        drawShape(f, xf, color, wireframe);
                    } else if (b.getType() == BodyType.KINEMATIC) {
                        color = Color.color(0.5f, 0.5f, 0.9f);
                        drawShape(f, xf, color, wireframe);
                    } else if (!b.isAwake()) {
                        color = Color.color(0.5f, 0.5f, 0.5f);
                        drawShape(f, xf, color, wireframe);
                    } else {
                        color = Color.color(0.9f, 0.7f, 0.7f);
                        drawShape(f, xf, color, wireframe);
                    }
                }
            }
            drawParticleSystem(world.getParticleSystem());
        }

        if ((flags & DebugDraw.e_jointBit) != 0) {
            for (Joint j = world.getJointList(); j != null; j = j.getNext()) {
                drawJoint(j);
            }
        }

        if ((flags & DebugDraw.e_pairBit) != 0) {
            color = Color.color(0.3f, 0.9f, 0.9f);
            for (Contact c = world.getContactManager().m_contactList; c != null; c = c.getNext()) {
                Fixture fixtureA = c.getFixtureA();
                Fixture fixtureB = c.getFixtureB();
                fixtureA.getAABB(c.getChildIndexA()).getCenterToOut(cA);
                fixtureB.getAABB(c.getChildIndexB()).getCenterToOut(cB);
                debugDraw.drawSegment(cA, cB, color);
            }
        }

        if ((flags & DebugDraw.e_aabbBit) != 0) {
            color = Color.color(0.9f, 0.3f, 0.9f);

            for (Body b = world.getBodyList(); b != null; b = b.getNext()) {
                if (!b.isActive()) {
                    continue;
                }

                for (Fixture f : b.getFixtures()) {
                    for (int i = 0; i < f.getProxyCount(); ++i) {
                        FixtureProxy proxy = f.m_proxies[i];
                        AABB aabb = world.getContactManager().m_broadPhase.getFatAABB(proxy.proxyId);
                        if (aabb != null) {
                            Vec2[] vs = avs.get(4);
                            vs[0].set(aabb.lowerBound.x, aabb.lowerBound.y);
                            vs[1].set(aabb.upperBound.x, aabb.lowerBound.y);
                            vs[2].set(aabb.upperBound.x, aabb.upperBound.y);
                            vs[3].set(aabb.lowerBound.x, aabb.upperBound.y);
                            debugDraw.drawPolygon(vs, 4, color);
                        }
                    }
                }
            }
        }

        if ((flags & DebugDraw.e_centerOfMassBit) != 0) {
            for (Body b = world.getBodyList(); b != null; b = b.getNext()) {
                xf.set(b.getTransform());
                xf.p.set(b.getWorldCenter());
                debugDraw.drawTransform(xf);
            }
        }

        if ((flags & DebugDraw.e_dynamicTreeBit) != 0) {
            world.getContactManager().m_broadPhase.drawTree(debugDraw);
        }

        debugDraw.flush();
    }

    private void drawJoint(Joint joint) {
        Body bodyA = joint.getBodyA();
        Body bodyB = joint.getBodyB();
        Transform xf1 = bodyA.getTransform();
        Transform xf2 = bodyB.getTransform();
        Vec2 x1 = xf1.p;
        Vec2 x2 = xf2.p;
        Vec2 p1 = world.getPool().popVec2();
        Vec2 p2 = world.getPool().popVec2();
        joint.getAnchorA(p1);
        joint.getAnchorB(p2);

        Color color = Color.color(0.5f, 0.8f, 0.8f);

        switch (joint.getType()) {
            // jbox2dTODO djm write after writing joints
            case DISTANCE:
                debugDraw.drawSegment(p1, p2, color);
                break;

            case PULLEY: {
                PulleyJoint pulley = (PulleyJoint) joint;
                Vec2 s1 = pulley.getGroundAnchorA();
                Vec2 s2 = pulley.getGroundAnchorB();
                debugDraw.drawSegment(s1, p1, color);
                debugDraw.drawSegment(s2, p2, color);
                debugDraw.drawSegment(s1, s2, color);
            }
            break;
            case CONSTANT_VOLUME:
            case MOUSE:
                // don't draw this
                break;
            default:
                debugDraw.drawSegment(x1, p1, color);
                debugDraw.drawSegment(p1, p2, color);
                debugDraw.drawSegment(x2, p2, color);
        }

        world.getPool().pushVec2(2);
    }

    // NOTE this corresponds to the liquid test, so the debugdraw can draw
    // the liquid particles correctly. They should be the same.
    private static Integer LIQUID_INT = new Integer(1234598372);
    private float liquidLength = .12f;
    private float averageLinearVel = -1;
    private final Vec2 liquidOffset = new Vec2();
    private final Vec2 circCenterMoved = new Vec2();
    private final Color liquidColor = Color.color(.4, .4, 1);

    private final Vec2 center = new Vec2();
    private final Vec2 axis = new Vec2();
    private final Vec2 v1 = new Vec2();
    private final Vec2 v2 = new Vec2();
    private final Vec2Array tlvertices = new Vec2Array();

    private void drawShape(Fixture fixture, Transform xf, Color color, boolean wireframe) {
        switch (fixture.getType()) {
            case CIRCLE: {
                CircleShape circle = (CircleShape) fixture.getShape();

                // Vec2 center = Mul(xf, circle.m_p);
                Transform.mulToOutUnsafe(xf, circle.m_p, center);
                float radius = circle.getRadius();
                xf.q.getXAxis(axis);

                if (fixture.getUserData() != null && fixture.getUserData().equals(LIQUID_INT)) {
                    Body b = fixture.getBody();
                    liquidOffset.set(b.m_linearVelocity);
                    float linVelLength = b.m_linearVelocity.length();
                    if (averageLinearVel == -1) {
                        averageLinearVel = linVelLength;
                    } else {
                        averageLinearVel = .98f * averageLinearVel + .02f * linVelLength;
                    }
                    liquidOffset.mulLocal(liquidLength / averageLinearVel / 2);
                    circCenterMoved.set(center).addLocal(liquidOffset);
                    center.subLocal(liquidOffset);
                    debugDraw.drawSegment(center, circCenterMoved, liquidColor);
                    return;
                }
                if (wireframe) {
                    debugDraw.drawCircle(center, radius, axis, color);
                } else {
                    debugDraw.drawSolidCircle(center, radius, axis, color);
                }
            }
            break;

            case POLYGON: {
                PolygonShape poly = (PolygonShape) fixture.getShape();
                int vertexCount = poly.getVertexCount();
                assert (vertexCount <= JBoxSettings.maxPolygonVertices);
                Vec2[] vertices = tlvertices.get(JBoxSettings.maxPolygonVertices);

                for (int i = 0; i < vertexCount; ++i) {
                    // vertices[i] = Mul(xf, poly.m_vertices[i]);
                    Transform.mulToOutUnsafe(xf, poly.m_vertices[i], vertices[i]);
                }
                if (wireframe) {
                    debugDraw.drawPolygon(vertices, vertexCount, color);
                } else {
                    debugDraw.drawSolidPolygon(vertices, vertexCount, color);
                }
            }
            break;
            case EDGE: {
                EdgeShape edge = (EdgeShape) fixture.getShape();
                Transform.mulToOutUnsafe(xf, edge.m_vertex1, v1);
                Transform.mulToOutUnsafe(xf, edge.m_vertex2, v2);
                debugDraw.drawSegment(v1, v2, color);
            }
            break;
            case CHAIN: {
                ChainShape chain = (ChainShape) fixture.getShape();
                int count = chain.m_count;
                Vec2[] vertices = chain.m_vertices;

                Transform.mulToOutUnsafe(xf, vertices[0], v1);
                for (int i = 1; i < count; ++i) {
                    Transform.mulToOutUnsafe(xf, vertices[i], v2);
                    debugDraw.drawSegment(v1, v2, color);
                    debugDraw.drawCircle(v1, 0.05f, color);
                    v1.set(v2);
                }
            }
            break;
            default:
                break;
        }
    }

    private void drawParticleSystem(ParticleSystem system) {
        boolean wireframe = (debugDraw.getFlags() & DebugDraw.e_wireframeDrawingBit) != 0;
        int particleCount = system.getParticleCount();
        if (particleCount != 0) {
            float particleRadius = system.getParticleRadius();
            Vec2[] positionBuffer = system.getParticlePositionBuffer();
            ParticleColor[] colorBuffer = null;
            if (system.m_colorBuffer.data != null) {
                colorBuffer = system.getParticleColorBuffer();
            }
            if (wireframe) {
                debugDraw.drawParticlesWireframe(positionBuffer, particleRadius, colorBuffer,
                        particleCount);
            } else {
                debugDraw.drawParticles(positionBuffer, particleRadius, colorBuffer, particleCount);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy