List of usage examples for com.badlogic.gdx.physics.box2d ChainShape ChainShape
public ChainShape()
From source file:com.cafeitvn.myballgame.screen.Box2DMapObjectParser.java
License:Apache License
/** * creates a {@link Fixture} from a {@link MapObject} * @param mapObject the {@link MapObject} which to parse * @return the parsed {@link Fixture}//from w ww. j a v a2s.com */ public Fixture createFixture(MapObject mapObject) { MapProperties properties = mapObject.getProperties(); String type = properties.get("type", String.class); Body body = bodies.get( type.equals(aliases.object) ? mapObject.getName() : properties.get(aliases.body, String.class)); if (!type.equals(aliases.fixture) && !type.equals(aliases.object)) throw new IllegalArgumentException("type of " + mapObject + " is \"" + type + "\" instead of \"" + aliases.fixture + "\" or \"" + aliases.object + "\""); FixtureDef fixtureDef = new FixtureDef(); Shape shape = null; if (mapObject instanceof RectangleMapObject) { shape = new PolygonShape(); Rectangle rectangle = ((RectangleMapObject) mapObject).getRectangle(); rectangle.x *= unitScale; rectangle.y *= unitScale; rectangle.width *= unitScale; rectangle.height *= unitScale; ((PolygonShape) shape).setAsBox(rectangle.width / 2, rectangle.height / 2, new Vector2(rectangle.x - body.getPosition().x + rectangle.width / 2, rectangle.y - body.getPosition().y + rectangle.height / 2), body.getAngle()); } else if (mapObject instanceof PolygonMapObject) { shape = new PolygonShape(); Polygon polygon = ((PolygonMapObject) mapObject).getPolygon(); polygon.setPosition(polygon.getX() * unitScale - body.getPosition().x, polygon.getY() * unitScale - body.getPosition().y); polygon.setScale(unitScale, unitScale); ((PolygonShape) shape).set(polygon.getTransformedVertices()); } else if (mapObject instanceof PolylineMapObject) { shape = new ChainShape(); Polyline polyline = ((PolylineMapObject) mapObject).getPolyline(); polyline.setPosition(polyline.getX() * unitScale - body.getPosition().x, polyline.getY() * unitScale - body.getPosition().y); polyline.setScale(unitScale, unitScale); ((ChainShape) shape).createChain(polyline.getTransformedVertices()); } else if (mapObject instanceof CircleMapObject) { shape = new CircleShape(); Circle circle = ((CircleMapObject) mapObject).getCircle(); circle.setPosition(circle.x * unitScale - body.getPosition().x, circle.y * unitScale - body.getPosition().y); circle.radius *= unitScale; ((CircleShape) shape).setPosition(new Vector2(circle.x, circle.y)); ((CircleShape) shape).setRadius(circle.radius); } else if (mapObject instanceof EllipseMapObject) { Ellipse ellipse = ((EllipseMapObject) mapObject).getEllipse(); if (ellipse.width == ellipse.height) { CircleMapObject circleMapObject = new CircleMapObject(ellipse.x, ellipse.y, ellipse.width / 2); circleMapObject.setName(mapObject.getName()); circleMapObject.getProperties().putAll(mapObject.getProperties()); circleMapObject.setColor(mapObject.getColor()); circleMapObject.setVisible(mapObject.isVisible()); circleMapObject.setOpacity(mapObject.getOpacity()); return createFixture(circleMapObject); } IllegalArgumentException exception = new IllegalArgumentException( "Cannot parse " + mapObject.getName() + " because " + mapObject.getClass().getSimpleName() + "s that are not circles are not supported"); Gdx.app.error(getClass().getSimpleName(), exception.getMessage(), exception); throw exception; } else if (mapObject instanceof TextureMapObject) { IllegalArgumentException exception = new IllegalArgumentException("Cannot parse " + mapObject.getName() + " because " + mapObject.getClass().getSimpleName() + "s are not supported"); Gdx.app.error(getClass().getSimpleName(), exception.getMessage(), exception); throw exception; } else assert false : mapObject + " is a not known subclass of " + MapObject.class.getName(); fixtureDef.shape = shape; fixtureDef.density = (Float) getProperty(properties, aliases.density, fixtureDef.density, Float.class); fixtureDef.filter.categoryBits = (Short) getProperty(properties, aliases.categoryBits, fixtureDef.filter.categoryBits, Short.class); fixtureDef.filter.groupIndex = (Short) getProperty(properties, aliases.groupIndex, fixtureDef.filter.groupIndex, Short.class); fixtureDef.filter.maskBits = (Short) getProperty(properties, aliases.maskBits, fixtureDef.filter.maskBits, Short.class); fixtureDef.friction = (Float) getProperty(properties, aliases.friciton, fixtureDef.friction, Float.class); fixtureDef.isSensor = (Boolean) getProperty(properties, aliases.isSensor, fixtureDef.isSensor, Boolean.class); fixtureDef.restitution = (Float) getProperty(properties, aliases.restitution, fixtureDef.restitution, Float.class); Fixture fixture = body.createFixture(fixtureDef); shape.dispose(); String name = mapObject.getName(); if (fixtures.containsKey(name)) { int duplicate = 1; while (fixtures.containsKey(name + duplicate)) duplicate++; name += duplicate; } fixtures.put(name, fixture); return fixture; }
From source file:com.rubentxu.juegos.core.utils.dermetfan.box2d.Box2DMapObjectParser.java
License:Apache License
/** * creates a {@link Fixture} from a {@link MapObject} * * @param mapObject the {@link MapObject} to parse * @return the parsed {@link Fixture}//w w w . ja v a 2 s . co m */ public Fixture createFixture(MapObject mapObject) { MapProperties properties = mapObject.getProperties(); String type = properties.get("type", String.class); Body body = bodies.get( type.equals(aliases.object) ? mapObject.getName() : properties.get(aliases.body, String.class)); if (!type.equals(aliases.fixture) && !type.equals(aliases.object)) throw new IllegalArgumentException("type of " + mapObject + " is \"" + type + "\" instead of \"" + aliases.fixture + "\" or \"" + aliases.object + "\""); FixtureDef fixtureDef = new FixtureDef(); Shape shape = null; if (mapObject instanceof RectangleMapObject) { shape = new PolygonShape(); Rectangle rectangle = new Rectangle(((RectangleMapObject) mapObject).getRectangle()); rectangle.x *= unitScale; rectangle.y *= unitScale; rectangle.width *= unitScale; rectangle.height *= unitScale; ((PolygonShape) shape).setAsBox(rectangle.width / 2, rectangle.height / 2, new Vector2(rectangle.x - body.getPosition().x + rectangle.width / 2, rectangle.y - body.getPosition().y + rectangle.height / 2), body.getAngle()); } else if (mapObject instanceof PolygonMapObject) { shape = new PolygonShape(); Polygon polygon = ((PolygonMapObject) mapObject).getPolygon(); polygon.setPosition(polygon.getX() * unitScale - body.getPosition().x, polygon.getY() * unitScale - body.getPosition().y); polygon.setScale(unitScale, unitScale); ((PolygonShape) shape).set(polygon.getTransformedVertices()); } else if (mapObject instanceof PolylineMapObject) { shape = new ChainShape(); Polyline polyline = ((PolylineMapObject) mapObject).getPolyline(); polyline.setPosition(polyline.getX() * unitScale - body.getPosition().x, polyline.getY() * unitScale - body.getPosition().y); polyline.setScale(unitScale, unitScale); float[] vertices = polyline.getTransformedVertices(); Vector2[] vectores = new Vector2[vertices.length / 2]; for (int i = 0, j = 0; i < vertices.length; i += 2, j++) { vectores[j].x = vertices[i]; vectores[j].y = vertices[i + 1]; } ((ChainShape) shape).createChain(vectores); } else if (mapObject instanceof CircleMapObject) { shape = new CircleShape(); Circle circle = ((CircleMapObject) mapObject).getCircle(); circle.setPosition(circle.x * unitScale - body.getPosition().x, circle.y * unitScale - body.getPosition().y); circle.radius *= unitScale; ((CircleShape) shape).setPosition(new Vector2(circle.x, circle.y)); ((CircleShape) shape).setRadius(circle.radius); } else if (mapObject instanceof EllipseMapObject) { Ellipse ellipse = ((EllipseMapObject) mapObject).getEllipse(); /* b2ChainShape* chain = (b2ChainShape*)addr; b2Vec2* verticesOut = new b2Vec2[numVertices]; for( int i = 0; i < numVertices; i++ ) verticesOut[i] = b2Vec2(verts[i<<1], verts[(i<<1)+1]); chain->CreateChain( verticesOut, numVertices ); delete verticesOut; */ if (ellipse.width == ellipse.height) { CircleMapObject circleMapObject = new CircleMapObject(ellipse.x, ellipse.y, ellipse.width / 2); circleMapObject.setName(mapObject.getName()); circleMapObject.getProperties().putAll(mapObject.getProperties()); circleMapObject.setColor(mapObject.getColor()); circleMapObject.setVisible(mapObject.isVisible()); circleMapObject.setOpacity(mapObject.getOpacity()); return createFixture(circleMapObject); } IllegalArgumentException exception = new IllegalArgumentException( "Cannot parse " + mapObject.getName() + " because that are not circles are not supported"); Gdx.app.error(getClass().getName(), exception.getMessage(), exception); throw exception; } else if (mapObject instanceof TextureMapObject) { IllegalArgumentException exception = new IllegalArgumentException( "Cannot parse " + mapObject.getName() + " because s are not supported"); Gdx.app.error(getClass().getName(), exception.getMessage(), exception); throw exception; } else assert false : mapObject + " is a not known subclass of " + MapObject.class.getName(); fixtureDef.shape = shape; fixtureDef.density = getProperty(properties, aliases.density, fixtureDef.density); fixtureDef.filter.categoryBits = getProperty(properties, aliases.categoryBits, GRUPO.STATIC.getCategory()); fixtureDef.filter.groupIndex = getProperty(properties, aliases.groupIndex, fixtureDef.filter.groupIndex); fixtureDef.filter.maskBits = getProperty(properties, aliases.maskBits, Box2DPhysicsObject.MASK_STATIC); fixtureDef.friction = getProperty(properties, aliases.friciton, fixtureDef.friction); fixtureDef.isSensor = getProperty(properties, aliases.isSensor, fixtureDef.isSensor); fixtureDef.restitution = getProperty(properties, aliases.restitution, fixtureDef.restitution); Fixture fixture = body.createFixture(fixtureDef); fixture.setUserData(body.getUserData()); shape.dispose(); String name = mapObject.getName(); if (fixtures.containsKey(name)) { int duplicate = 1; while (fixtures.containsKey(name + duplicate)) duplicate++; name += duplicate; } fixtures.put(name, fixture); return fixture; }
From source file:com.siondream.core.physics.MapBodyManager.java
License:Open Source License
private Shape getPolyline(PolylineMapObject polylineObject) { float[] vertices = polylineObject.getPolyline().getTransformedVertices(); Vector2[] worldVertices = new Vector2[vertices.length / 2]; for (int i = 0; i < vertices.length / 2; ++i) { worldVertices[i] = new Vector2(); worldVertices[i].x = vertices[i * 2] / units; worldVertices[i].y = vertices[i * 2 + 1] / units; }//from w w w . ja v a 2s .c o m ChainShape chain = new ChainShape(); chain.createChain(worldVertices); return chain; }
From source file:com.stercore.code.net.dermetfan.utils.libgdx.box2d.Box2DMapObjectParser.java
License:Apache License
/** creates a {@link Fixture} from a {@link MapObject} * @param mapObject the {@link MapObject} to parse * @param body the {@link Body} to create the {@link Fixture Fixtures} on * @return the parsed {@link Fixture} */ public Fixture createFixture(MapObject mapObject, Body body) { if ((mapObject = listener.createFixture(mapObject)) == null) return null; String orientation = findProperty(aliases.orientation, aliases.orthogonal, heritage, mapProperties, layerProperties, mapObject.getProperties()); transform(mat4, orientation);//from ww w.j a v a 2s . c o m Shape shape = null; if (mapObject instanceof RectangleMapObject) { Rectangle rectangle = ((RectangleMapObject) mapObject).getRectangle(); vec3.set(rectangle.x, rectangle.y, 0); vec3.mul(mat4); float x = vec3.x, y = vec3.y, width, height; if (!orientation.equals(aliases.staggered)) { vec3.set(rectangle.width, rectangle.height, 0).mul(mat4); width = vec3.x; height = vec3.y; } else { width = rectangle.width * unitScale; height = rectangle.height * unitScale; } ((PolygonShape) (shape = new PolygonShape())).setAsBox(width / 2, height / 2, vec2.set(x - body.getPosition().x + width / 2, y - body.getPosition().y + height / 2), body.getAngle()); } else if (mapObject instanceof PolygonMapObject || mapObject instanceof PolylineMapObject) { FloatArray vertices = Pools.obtain(FloatArray.class); vertices.clear(); vertices.addAll(mapObject instanceof PolygonMapObject ? ((PolygonMapObject) mapObject).getPolygon().getTransformedVertices() : ((PolylineMapObject) mapObject).getPolyline().getTransformedVertices()); for (int ix = 0, iy = 1; iy < vertices.size; ix += 2, iy += 2) { vec3.set(vertices.get(ix), vertices.get(iy), 0); vec3.mul(mat4); vertices.set(ix, vec3.x - body.getPosition().x); vertices.set(iy, vec3.y - body.getPosition().y); } if (mapObject instanceof PolygonMapObject) ((PolygonShape) (shape = new PolygonShape())).set(vertices.items, 0, vertices.size); else if (vertices.size == 4) ((EdgeShape) (shape = new EdgeShape())).set(vertices.get(0), vertices.get(1), vertices.get(2), vertices.get(3)); else { vertices.shrink(); ((ChainShape) (shape = new ChainShape())).createChain(vertices.items); } Pools.free(vertices); } else if (mapObject instanceof CircleMapObject || mapObject instanceof EllipseMapObject) { if (mapObject instanceof CircleMapObject) { Circle circle = ((CircleMapObject) mapObject).getCircle(); vec3.set(circle.x, circle.y, circle.radius); } else { Ellipse ellipse = ((EllipseMapObject) mapObject).getEllipse(); if (ellipse.width != ellipse.height) throw new IllegalArgumentException("Cannot parse " + mapObject.getName() + " because " + ClassReflection.getSimpleName(mapObject.getClass()) + "s that are not circles are not supported"); vec3.set(ellipse.x + ellipse.width / 2, ellipse.y + ellipse.height / 2, ellipse.width / 2); } vec3.mul(mat4); vec3.sub(body.getPosition().x, body.getPosition().y, 0); CircleShape circleShape = (CircleShape) (shape = new CircleShape()); circleShape.setPosition(vec2.set(vec3.x, vec3.y)); circleShape.setRadius(vec3.z); } else if (mapObject instanceof TextureMapObject) throw new IllegalArgumentException("Cannot parse " + mapObject.getName() + " because " + ClassReflection.getSimpleName(mapObject.getClass()) + "s are not supported"); else assert false : mapObject + " is a not known subclass of " + MapObject.class.getName(); MapProperties properties = mapObject.getProperties(); FixtureDef fixtureDef = new FixtureDef(); fixtureDef.shape = shape; assignProperties(fixtureDef, heritage); assignProperties(fixtureDef, mapProperties); assignProperties(fixtureDef, layerProperties); assignProperties(fixtureDef, properties); Fixture fixture = body.createFixture(fixtureDef); fixture.setUserData(findProperty(aliases.userData, fixture.getUserData(), heritage, mapProperties, layerProperties, properties)); shape.dispose(); fixtures.put(findAvailableName(mapObject.getName(), fixtures), fixture); listener.created(fixture, mapObject); return fixture; }
From source file:com.stercore.code.net.dermetfan.utils.libgdx.box2d.Box2DUtils.java
License:Apache License
/** creates a deep copy of a {@link Shape}<br> * <strong>Note: The {@link ChainShape#setPrevVertex(float, float) previous} and {@link ChainShape#setNextVertex(float, float) next} vertex of a {@link ChainShape} will not be copied since this is not possible due to the API.</strong> * @param shape the {@link Shape} to copy * @return a {@link Shape} exactly like the one passed in */ @SuppressWarnings("unchecked") public static <T extends Shape> T clone(T shape) { T clone;//from ww w . j a v a 2 s . c o m switch (shape.getType()) { case Circle: CircleShape circleClone = (CircleShape) (clone = (T) new CircleShape()); circleClone.setPosition(((CircleShape) shape).getPosition()); break; case Polygon: PolygonShape polyClone = (PolygonShape) (clone = (T) new PolygonShape()), poly = (PolygonShape) shape; float[] vertices = new float[poly.getVertexCount()]; for (int i = 0; i < vertices.length; i++) { poly.getVertex(i, vec2_0); vertices[i++] = vec2_0.x; vertices[i] = vec2_0.y; } polyClone.set(vertices); break; case Edge: EdgeShape edgeClone = (EdgeShape) (clone = (T) new EdgeShape()), edge = (EdgeShape) shape; edge.getVertex1(vec2_0); edge.getVertex2(vec2_1); edgeClone.set(vec2_0, vec2_1); break; case Chain: ChainShape chainClone = (ChainShape) (clone = (T) new ChainShape()), chain = (ChainShape) shape; vertices = new float[chain.getVertexCount()]; for (int i = 0; i < vertices.length; i++) { chain.getVertex(i, vec2_0); vertices[i++] = vec2_0.x; vertices[i] = vec2_0.y; } if (chain.isLooped()) chainClone.createLoop(GeometryUtils.toVector2Array(vertices)); else chainClone.createChain(vertices); break; default: return null; } clone.setRadius(shape.getRadius()); return clone; }
From source file:com.stercore.code.net.dermetfan.utils.libgdx.box2d.Box2DUtils.java
License:Apache License
/** splits the given Shape using the segment described by the two given Vector2s * @param shape the Shape to split//from w w w . j a va 2 s .co m * @param a the first point of the segment * @param b the second point of the segment * @param store the {@link Pair} to store the split Shapes in * @return if the given shape was split */ @SuppressWarnings("unchecked") public static <T extends Shape> boolean split(T shape, Vector2 a, Vector2 b, Pair<T, T> store) { Type type = shape.getType(); if (type == Type.Circle) throw new IllegalArgumentException("shapes of the type " + Type.Circle + " cannot be split since Box2D does not support curved shapes other than circles: " + shape); if (type == Type.Edge) { Vector2 vertex1 = Pools.obtain(Vector2.class), vertex2 = Pools.obtain(Vector2.class), intersection = Pools.obtain(Vector2.class); EdgeShape es = (EdgeShape) shape; es.getVertex1(vertex1); es.getVertex2(vertex2); if (!Intersector.intersectSegments(a, b, vertex1, vertex2, intersection)) { Pools.free(vertex1); Pools.free(vertex2); Pools.free(intersection); return false; } EdgeShape sa = new EdgeShape(), sb = new EdgeShape(); sa.set(vertex1, intersection); sb.set(intersection, vertex2); store.set((T) sa, (T) sb); Pools.free(vertex1); Pools.free(vertex2); Pools.free(intersection); return true; } store.clear(); Vector2 vertices[] = vertices(shape), aa = Pools.obtain(Vector2.class).set(a), bb = Pools.obtain(Vector2.class).set(b); Array<Vector2> aVertices = Pools.obtain(Array.class), bVertices = Pools.obtain(Array.class); aVertices.clear(); bVertices.clear(); if (type == Type.Polygon) { aVertices.add(aa); aVertices.add(bb); GeometryUtils.arrangeClockwise(aVertices); if (GeometryUtils.intersectSegments(a, b, GeometryUtils.toFloatArray(vertices), aVertices.first(), aVertices.peek()) < 2) { Pools.free(aa); Pools.free(bb); Pools.free(aVertices); Pools.free(bVertices); return false; } bVertices.add(aa); bVertices.add(bb); for (Vector2 vertice : vertices) { float det = MathUtils.det(aa.x, aa.y, vertice.x, vertice.y, bb.x, bb.y); if (det < 0) aVertices.add(vertice); else if (det > 0) bVertices.add(vertice); else { aVertices.add(vertice); bVertices.add(vertice); } } GeometryUtils.arrangeClockwise(aVertices); GeometryUtils.arrangeClockwise(bVertices); Vector2[] aVerticesArray = aVertices.toArray(Vector2.class), bVerticesArray = bVertices.toArray(Vector2.class); if (checkPreconditions) { if (aVertices.size >= 3 && aVertices.size <= maxPolygonVertices && bVertices.size >= 3 && bVertices.size <= maxPolygonVertices) { float[] aVerticesFloatArray = GeometryUtils.toFloatArray(aVerticesArray), bVerticesFloatArray = GeometryUtils.toFloatArray(bVerticesArray); if (GeometryUtils.area(aVerticesFloatArray) > minExclusivePolygonArea && GeometryUtils.area(bVerticesFloatArray) > minExclusivePolygonArea) { PolygonShape sa = new PolygonShape(), sb = new PolygonShape(); sa.set(aVerticesFloatArray); sb.set(bVerticesFloatArray); store.set((T) sa, (T) sb); } } } else { PolygonShape sa = new PolygonShape(), sb = new PolygonShape(); sa.set(aVerticesArray); sb.set(bVerticesArray); store.set((T) sa, (T) sb); } } else if (type == Type.Chain) { Vector2 tmp = Pools.obtain(Vector2.class); boolean intersected = false; for (int i = 0; i < vertices.length; i++) { if (!intersected) aVertices.add(vertices[i]); else bVertices.add(vertices[i]); if (!intersected && i + 1 < vertices.length && Intersector.intersectSegments(vertices[i], vertices[i + 1], aa, bb, tmp)) { intersected = true; aVertices.add(tmp); bVertices.add(tmp); } } if (intersected) if (!checkPreconditions || aVertices.size >= 3 && bVertices.size >= 3) { ChainShape sa = new ChainShape(), sb = new ChainShape(); sa.createChain((Vector2[]) aVertices.toArray(Vector2.class)); sb.createChain((Vector2[]) bVertices.toArray(Vector2.class)); store.set((T) sa, (T) sb); } Pools.free(tmp); } Pools.free(aa); Pools.free(bb); Pools.free(aVertices); Pools.free(bVertices); return store.isFull(); }
From source file:com.strategames.engine.gameobject.types.Door.java
License:Open Source License
@Override protected void setupBody(Body body) { Vector2 leftBottom = new Vector2(0, 0); Vector2 rightBottom = new Vector2(WIDTH, 0); Vector2 rightTop = new Vector2(WIDTH, HEIGHT); Vector2 leftTop = new Vector2(0, HEIGHT); ChainShape chain = new ChainShape(); chain.createLoop(new Vector2[] { leftBottom, rightBottom, rightTop, leftTop }); Fixture fixture = body.createFixture(chain, 0.0f); fixture.setSensor(true);//from www .j a v a2 s .c o m }
From source file:com.strategames.engine.gameobject.types.RectangularSensor.java
License:Open Source License
@Override protected void setupBody(Body body) { if (this.start == null) { this.start = new Vector2(0, 0); }// w w w . j av a2s .c om if (this.end == null) { GameEngine game = getGame(); Vector3 worldSize = game.getWorldSize(); this.end = new Vector2(worldSize.x, worldSize.y).add(Wall.WIDTH, Wall.HEIGHT); } Vector2 leftBottom = new Vector2(start.x, start.y); Vector2 rightBottom = new Vector2(end.x, start.y); Vector2 rightTop = new Vector2(end.x, end.y); Vector2 leftTop = new Vector2(start.x, end.y); ChainShape chain = new ChainShape(); chain.createLoop(new Vector2[] { leftBottom, rightBottom, rightTop, leftTop }); Fixture fixture = body.createFixture(chain, 0.0f); fixture.setSensor(true); }
From source file:com.talas777.ZombieLord.LevelObject.java
License:Open Source License
public ChainShape getCollisionBoundary() { if (!collision) return null; ChainShape shape = new ChainShape(); shape.createLoop(this.getCollisionVectors()); return shape; }
From source file:com.talas777.ZombieLord.Levels.Church.java
License:Open Source License
@Override public void applyCollisionBoundaries(World world, float pixels_per_meter) { BodyDef groundBodyDef = new BodyDef(); groundBodyDef.type = BodyDef.BodyType.StaticBody; Body groundBody = world.createBody(groundBodyDef); { // church//from w w w . j av a2 s . co m ChainShape environmentShape = new ChainShape(); Vector2[] vertices = vectorize( new float[] { 439, 439, 477, 477, 566, 566, 563, 470, 470, 442, 442, 425, 425, 440, 440, 603, 603, 538, 538, 505, 505 }, new float[] { 389, 449, 449, 497, 497, 540, 527, 527, 478, 478, 485, 485, 518, 518, 614, 614, 388, 388, 380, 380, 389 }); environmentShape.createLoop(vertices); groundBody.createFixture(environmentShape, 0); environmentShape.dispose(); } }