package org.andengine.extension.physics.box2d; import static org.andengine.extension.physics.box2d.util.constants.PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT; import java.util.List; import org.andengine.entity.primitive.Line; import org.andengine.entity.shape.IAreaShape; import org.andengine.entity.shape.IShape; import org.andengine.extension.physics.box2d.util.constants.PhysicsConstants; import org.andengine.util.Constants; import org.andengine.util.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.CircleShape; import com.badlogic.gdx.physics.box2d.Filter; import com.badlogic.gdx.physics.box2d.Fixture; import com.badlogic.gdx.physics.box2d.FixtureDef; import com.badlogic.gdx.physics.box2d.PolygonShape; /** * (c) 2010 Nicolas Gramlich * (c) 2011 Zynga Inc. * * @author Nicolas Gramlich * @since 13:59:03 - 15.07.2010 */ public class PhysicsFactory { // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== // =========================================================== // Constructors // =========================================================== // =========================================================== // Getter & Setter // =========================================================== // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== public static FixtureDef createFixtureDef(final float pDensity, final float pElasticity, final float pFriction) { return PhysicsFactory.createFixtureDef(pDensity, pElasticity, pFriction, false); } public static FixtureDef createFixtureDef(final float pDensity, final float pElasticity, final float pFriction, final boolean pSensor) { final FixtureDef fixtureDef = new FixtureDef(); fixtureDef.density = pDensity; fixtureDef.restitution = pElasticity; fixtureDef.friction = pFriction; fixtureDef.isSensor = pSensor; return fixtureDef; } public static FixtureDef createFixtureDef(final float pDensity, final float pElasticity, final float pFriction, final boolean pSensor, final short pCategoryBits, final short pMaskBits, final short pGroupIndex) { final FixtureDef fixtureDef = new FixtureDef(); fixtureDef.density = pDensity; fixtureDef.restitution = pElasticity; fixtureDef.friction = pFriction; fixtureDef.isSensor = pSensor; final Filter filter = fixtureDef.filter; filter.categoryBits = pCategoryBits; filter.maskBits = pMaskBits; filter.groupIndex = pGroupIndex; return fixtureDef; } public static Body createBoxBody(final PhysicsWorld pPhysicsWorld, final IAreaShape pAreaShape, final BodyType pBodyType, final FixtureDef pFixtureDef) { return PhysicsFactory.createBoxBody(pPhysicsWorld, pAreaShape, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } public static Body createBoxBody(final PhysicsWorld pPhysicsWorld, final IAreaShape pAreaShape, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { final float[] sceneCenterCoordinates = pAreaShape.getSceneCenterCoordinates(); final float centerX = sceneCenterCoordinates[Constants.VERTEX_INDEX_X]; final float centerY = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y]; return PhysicsFactory.createBoxBody(pPhysicsWorld, centerX, centerY, pAreaShape.getWidthScaled(), pAreaShape.getHeightScaled(), pAreaShape.getRotation(), pBodyType, pFixtureDef, pPixelToMeterRatio); } public static Body createBoxBody(final PhysicsWorld pPhysicsWorld, final float pCenterX, final float pCenterY, final float pWidth, final float pHeight, final BodyType pBodyType, final FixtureDef pFixtureDef) { return PhysicsFactory.createBoxBody(pPhysicsWorld, pCenterX, pCenterY, pWidth, pHeight, 0, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } public static Body createBoxBody(final PhysicsWorld pPhysicsWorld, final float pCenterX, final float pCenterY, final float pWidth, final float pHeight, final float pRotation, final BodyType pBodyType, final FixtureDef pFixtureDef) { return PhysicsFactory.createBoxBody(pPhysicsWorld, pCenterX, pCenterY, pWidth, pHeight, pRotation, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } public static Body createBoxBody(final PhysicsWorld pPhysicsWorld, final float pCenterX, final float pCenterY, final float pWidth, final float pHeight, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { return PhysicsFactory.createBoxBody(pPhysicsWorld, pCenterX, pCenterY, pWidth, pHeight, 0, pBodyType, pFixtureDef, pPixelToMeterRatio); } public static Body createBoxBody(final PhysicsWorld pPhysicsWorld, final float pCenterX, final float pCenterY, final float pWidth, final float pHeight, final float pRotation, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { final BodyDef boxBodyDef = new BodyDef(); boxBodyDef.type = pBodyType; boxBodyDef.position.x = pCenterX / pPixelToMeterRatio; boxBodyDef.position.y = pCenterY / pPixelToMeterRatio; final Body boxBody = pPhysicsWorld.createBody(boxBodyDef); final PolygonShape boxPoly = new PolygonShape(); final float halfWidth = pWidth * 0.5f / pPixelToMeterRatio; final float halfHeight = pHeight * 0.5f / pPixelToMeterRatio; boxPoly.setAsBox(halfWidth, halfHeight); pFixtureDef.shape = boxPoly; boxBody.createFixture(pFixtureDef); boxPoly.dispose(); boxBody.setTransform(boxBody.getWorldCenter(), MathUtils.degToRad(pRotation)); return boxBody; } public static Body createCircleBody(final PhysicsWorld pPhysicsWorld, final IAreaShape pAreaShape, final BodyType pBodyType, final FixtureDef pFixtureDef) { return PhysicsFactory.createCircleBody(pPhysicsWorld, pAreaShape, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } public static Body createCircleBody(final PhysicsWorld pPhysicsWorld, final IAreaShape pAreaShape, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { final float[] sceneCenterCoordinates = pAreaShape.getSceneCenterCoordinates(); final float centerX = sceneCenterCoordinates[Constants.VERTEX_INDEX_X]; final float centerY = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y]; return PhysicsFactory.createCircleBody(pPhysicsWorld, centerX, centerY, pAreaShape.getWidthScaled() * 0.5f, pAreaShape.getRotation(), pBodyType, pFixtureDef, pPixelToMeterRatio); } public static Body createCircleBody(final PhysicsWorld pPhysicsWorld, final float pCenterX, final float pCenterY, final float pRadius, final BodyType pBodyType, final FixtureDef pFixtureDef) { return createCircleBody(pPhysicsWorld, pCenterX, pCenterY, pRadius, 0, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } public static Body createCircleBody(final PhysicsWorld pPhysicsWorld, final float pCenterX, final float pCenterY, final float pRadius, final float pRotation, final BodyType pBodyType, final FixtureDef pFixtureDef) { return createCircleBody(pPhysicsWorld, pCenterX, pCenterY, pRadius, pRotation, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } public static Body createCircleBody(final PhysicsWorld pPhysicsWorld, final float pCenterX, final float pCenterY, final float pRadius, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { return createCircleBody(pPhysicsWorld, pCenterX, pCenterY, pRadius, 0, pBodyType, pFixtureDef, pPixelToMeterRatio); } public static Body createCircleBody(final PhysicsWorld pPhysicsWorld, final float pCenterX, final float pCenterY, final float pRadius, final float pRotation, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { final BodyDef circleBodyDef = new BodyDef(); circleBodyDef.type = pBodyType; circleBodyDef.position.x = pCenterX / pPixelToMeterRatio; circleBodyDef.position.y = pCenterY / pPixelToMeterRatio; circleBodyDef.angle = MathUtils.degToRad(pRotation); final Body circleBody = pPhysicsWorld.createBody(circleBodyDef); final CircleShape circlePoly = new CircleShape(); pFixtureDef.shape = circlePoly; final float radius = pRadius / pPixelToMeterRatio; circlePoly.setRadius(radius); circleBody.createFixture(pFixtureDef); circlePoly.dispose(); return circleBody; } public static Body createLineBody(final PhysicsWorld pPhysicsWorld, final Line pLine, final FixtureDef pFixtureDef) { return PhysicsFactory.createLineBody(pPhysicsWorld, pLine, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } public static Body createLineBody(final PhysicsWorld pPhysicsWorld, final Line pLine, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { final float[] sceneCoordinates = pLine.convertLocalToSceneCoordinates(0, 0); final float x1 = sceneCoordinates[Constants.VERTEX_INDEX_X]; final float y1 = sceneCoordinates[Constants.VERTEX_INDEX_Y]; pLine.convertLocalToSceneCoordinates(pLine.getX2() - pLine.getX1(), pLine.getY2() - pLine.getY1()); final float x2 = sceneCoordinates[Constants.VERTEX_INDEX_X]; final float y2 = sceneCoordinates[Constants.VERTEX_INDEX_Y]; return PhysicsFactory.createLineBody(pPhysicsWorld, x1, y1, x2, y2, pFixtureDef, pPixelToMeterRatio); } public static Body createLineBody(final PhysicsWorld pPhysicsWorld, final float pX1, final float pY1, final float pX2, final float pY2, final FixtureDef pFixtureDef) { return PhysicsFactory.createLineBody(pPhysicsWorld, pX1, pY1, pX2, pY2, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } public static Body createLineBody(final PhysicsWorld pPhysicsWorld, final float pX1, final float pY1, final float pX2, final float pY2, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { final BodyDef lineBodyDef = new BodyDef(); lineBodyDef.type = BodyType.StaticBody; final Body boxBody = pPhysicsWorld.createBody(lineBodyDef); final PolygonShape linePoly = new PolygonShape(); linePoly.setAsEdge(new Vector2(pX1 / pPixelToMeterRatio, pY1 / pPixelToMeterRatio), new Vector2(pX2 / pPixelToMeterRatio, pY2 / pPixelToMeterRatio)); pFixtureDef.shape = linePoly; boxBody.createFixture(pFixtureDef); linePoly.dispose(); return boxBody; } /** * @param pPhysicsWorld * @param pShape * @param pVertices are to be defined relative to the center of the pShape and have the {@link PhysicsConstants#PIXEL_TO_METER_RATIO_DEFAULT} applied. * @param pBodyType * @param pFixtureDef * @return */ public static Body createPolygonBody(final PhysicsWorld pPhysicsWorld, final IShape pShape, final Vector2[] pVertices, final BodyType pBodyType, final FixtureDef pFixtureDef) { return PhysicsFactory.createPolygonBody(pPhysicsWorld, pShape, pVertices, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } /** * @param pPhysicsWorld * @param pShape * @param pVertices are to be defined relative to the center of the pShape. * @param pBodyType * @param pFixtureDef * @return */ public static Body createPolygonBody(final PhysicsWorld pPhysicsWorld, final IShape pShape, final Vector2[] pVertices, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { final BodyDef boxBodyDef = new BodyDef(); boxBodyDef.type = pBodyType; final float[] sceneCenterCoordinates = pShape.getSceneCenterCoordinates(); boxBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / pPixelToMeterRatio; boxBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / pPixelToMeterRatio; final Body boxBody = pPhysicsWorld.createBody(boxBodyDef); final PolygonShape boxPoly = new PolygonShape(); boxPoly.set(pVertices); pFixtureDef.shape = boxPoly; boxBody.createFixture(pFixtureDef); boxPoly.dispose(); return boxBody; } /** * @param pPhysicsWorld * @param pShape * @param pTriangleVertices are to be defined relative to the center of the pShape and have the {@link PhysicsConstants#PIXEL_TO_METER_RATIO_DEFAULT} applied. * @param pBodyType * @param pFixtureDef * @return */ public static Body createTrianglulatedBody(final PhysicsWorld pPhysicsWorld, final IShape pShape, final List<Vector2> pTriangleVertices, final BodyType pBodyType, final FixtureDef pFixtureDef) { return PhysicsFactory.createTrianglulatedBody(pPhysicsWorld, pShape, pTriangleVertices, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); } /** * @param pPhysicsWorld * @param pShape * @param pTriangleVertices are to be defined relative to the center of the pShape and have the {@link PhysicsConstants#PIXEL_TO_METER_RATIO_DEFAULT} applied. * The vertices will be triangulated and for each triangle a {@link Fixture} will be created. * @param pBodyType * @param pFixtureDef * @return */ public static Body createTrianglulatedBody(final PhysicsWorld pPhysicsWorld, final IShape pShape, final List<Vector2> pTriangleVertices, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { final Vector2[] TMP_TRIANGLE = new Vector2[3]; final BodyDef boxBodyDef = new BodyDef(); boxBodyDef.type = pBodyType; final float[] sceneCenterCoordinates = pShape.getSceneCenterCoordinates(); boxBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / pPixelToMeterRatio; boxBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / pPixelToMeterRatio; final Body boxBody = pPhysicsWorld.createBody(boxBodyDef); final int vertexCount = pTriangleVertices.size(); for(int i = 0; i < vertexCount; /* */) { final PolygonShape boxPoly = new PolygonShape(); TMP_TRIANGLE[2] = pTriangleVertices.get(i++); TMP_TRIANGLE[1] = pTriangleVertices.get(i++); TMP_TRIANGLE[0] = pTriangleVertices.get(i++); boxPoly.set(TMP_TRIANGLE); pFixtureDef.shape = boxPoly; boxBody.createFixture(pFixtureDef); boxPoly.dispose(); } return boxBody; } // =========================================================== // Methods // =========================================================== // =========================================================== // Inner and Anonymous Classes // =========================================================== }