<!-- math -->
<include name="math/Bezier.java"/>
+ <include name="math/Bresenham2.java"/>
<include name="math/BSpline.java"/>
<include name="math/CatmullRomSpline.java"/>
<include name="math/Circle.java"/>
--- /dev/null
+package com.badlogic.gdx.math;
+
+import com.badlogic.gdx.utils.Array;
+import com.badlogic.gdx.utils.Pool;
+
+/**
+ * Returns a list of {@link Vector2} instances at integer coordinates for
+ * a line in 2D, using the Bresenham algorithm.<p>
+ *
+ * Instances of this class own the returned array of vectors and the vectors
+ * themselves to avoid garbage collection as much as possible. Calling
+ * {@link #line(Vector2, Vector2)} or {@link #line(float, float, float, float)} will
+ * result in the reuse of the previously returned array and vectors.
+ * @author badlogic
+ *
+ */
+public class Bresenham2 {
+ private final Array<Vector2> points = new Array<Vector2>();
+ private final Pool<Vector2> pool = new Pool<Vector2>() {
+ @Override
+ protected Vector2 newObject () {
+ return new Vector2();
+ }
+ };
+
+ /**
+ * Returns a list of {@link Vector2} instances along the given line, at integer coordinates.
+ * The input coordinates are cast to integers using a floor operation.
+ * @param start the start of the line
+ * @param end the end of the line
+ * @return the list of points on the line at integer coordinates
+ */
+ public Array<Vector2> line(Vector2 start, Vector2 end) {
+ return line(start.x, start.y, end.y, end.y);
+ }
+
+ /**
+ * Returns a list of {@link Vector2} instances along the given line, at integer coordinates.
+ * The input coordinates are cast to integers using a floor operation.
+ * @param startX the start x coordinate of the line
+ * @param startY the start y coordinate of the line
+ * @param endX the end x coordinate of the line
+ * @param endY the end y coordinate of the line
+ * @return the list of points on the line at integer coordinates
+ */
+ public Array<Vector2> line(float startX, float startY, float endX, float endY) {
+ pool.freeAll(points);
+ points.clear();
+ line(startX, startY, endX, endY, pool, points);
+ return points;
+ }
+
+ /**
+ * Returns a list of {@link Vector2} instances along the given line, at integer coordinates.
+ * The input coordinates are cast to integers using a floor operation.
+ * @param startX the start x coordinate of the line
+ * @param startY the start y coordinate of the line
+ * @param endX the end x coordinate of the line
+ * @param endY the end y coordinate of the line
+ * @param pool the pool from which Vector2 instances are fetched
+ * @param output the output array, will be cleared in this method
+ * @return the list of points on the line at integer coordinates
+ */
+ public Array<Vector2> line(float startX, float startY, float endX, float endY, Pool<Vector2> pool, Array<Vector2> output) {
+ int x1 = (int)startX;
+ int y1 = (int)startY;
+ int x2 = (int)endX;
+ int y2 = (int)endY;
+
+ int w = x2 - x1;
+ int h = y2 - y1;
+ int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
+ if(w < 0) {
+ dx1 = -1;
+ dx2 = -1;
+ } else if(w > 0) {
+ dx1 = 1;
+ dx2 = 1;
+ }
+ if(h < 0) dy1 = -1; else if(h > 0) dy1 = 1;
+ int longest = Math.abs(w);
+ int shortest = Math.abs(h);
+ if(longest <= shortest) {
+ longest = Math.abs(h);
+ shortest = Math.abs(w);
+ if(h < 0) dy2 = -1; else if(h > 0) dy2 = 1;
+ dx2 = 0;
+ }
+ int numerator = longest >> 1;
+ for(int i = 0; i <= longest; i++) {
+ Vector2 point = pool.obtain();
+ point.set(x1, y1);
+ output.add(point);
+ numerator += shortest;
+ if(numerator > longest) {
+ numerator -= longest;
+ x1 += dx1;
+ y1 += dy1;
+ } else {
+ x1 += dx2;
+ y1 += dy2;
+ }
+ }
+ return output;
+ }
+}
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;\r
import com.badlogic.gdx.math.Vector2;\r
import com.badlogic.gdx.scenes.scene2d.Stage;\r
+import com.badlogic.gdx.tests.Bresenham2Test;\r
import com.badlogic.gdx.tests.MeshShaderTest;\r
import com.badlogic.gdx.tests.TimerTest;\r
import com.badlogic.gdx.tests.g3d.Basic3DSceneTest;\r
// new SharedLibraryLoader("../../extensions/gdx-controllers/gdx-controllers-desktop/libs/gdx-controllers-desktop-natives.jar").load("gdx-controllers-desktop");\r
// new SharedLibraryLoader("../../gdx/libs/gdx-natives.jar").load("gdx");\r
\r
- GdxTest test = new VoxelTest();\r
+ GdxTest test = new Bresenham2Test();\r
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();\r
config.useGL20 = test.needsGL20();\r
config.width = 1024;\r
--- /dev/null
+package com.badlogic.gdx.tests;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.GL20;
+import com.badlogic.gdx.graphics.Pixmap;
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.graphics.Pixmap.Format;
+import com.badlogic.gdx.graphics.g2d.SpriteBatch;
+import com.badlogic.gdx.math.Bresenham2;
+import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.tests.utils.GdxTest;
+
+public class Bresenham2Test extends GdxTest {
+ SpriteBatch batch;
+ Texture result;
+
+ @Override
+ public void create () {
+ Pixmap pixmap = new Pixmap(512, 512, Format.RGBA8888);
+ pixmap.setColor(Color.WHITE);
+
+ Bresenham2 bresenham = new Bresenham2();
+ for(Vector2 point: bresenham.line(0, 0, 512, 512)) pixmap.drawPixel((int)point.x, (int)point.y);
+ for(Vector2 point: bresenham.line(512, 0, 0, 512)) pixmap.drawPixel((int)point.x, (int)point.y);
+ for(Vector2 point: bresenham.line(0, 0, 512, 256)) pixmap.drawPixel((int)point.x, (int)point.y);
+ for(Vector2 point: bresenham.line(512, 0, 0, 256)) pixmap.drawPixel((int)point.x, (int)point.y);
+
+ result = new Texture(pixmap);
+ batch = new SpriteBatch();
+ }
+
+ @Override
+ public void render () {
+ Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
+ batch.begin();
+ batch.draw(result, 0, 0);
+ batch.end();
+ }
+}
DefaultShader.defaultCullFace = GL20.GL_FRONT;
GLES10Shader.defaultCullFace = GL20.GL_FRONT;
camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
- camera.near = 1;
+ camera.near = 0.5f;
camera.far = 1000;
controller = new FirstPersonCameraController(camera);
Gdx.input.setInputProcessor(controller);
TextureRegion[][] tiles = TextureRegion.split(texture, 32, 32);
MathUtils.random.setSeed(0);
- voxelWorld = new VoxelWorld(tiles[0], 10, 4, 10);
+ voxelWorld = new VoxelWorld(tiles[0], 20, 4, 20);
PerlinNoiseGenerator.generateVoxels(voxelWorld, 0, 63, 10);
-// voxelWorld.setCube(0, 0, 0, 16, 16, 16, (byte)1);
float camX = voxelWorld.voxelsX / 2f;
float camZ = voxelWorld.voxelsZ / 2f;
- float camY = voxelWorld.getHighest(camX, camZ);
+ float camY = voxelWorld.getHighest(camX, camZ) + 1.5f;
camera.position.set(camX, camY, camZ);
}
controller.update();
spriteBatch.begin();
- font.draw(spriteBatch, "fps: " + Gdx.graphics.getFramesPerSecond(), 0, 20);
+ font.draw(spriteBatch, "fps: " + Gdx.graphics.getFramesPerSecond() + ", #visible chunks: " + voxelWorld.renderedChunks + "/" + voxelWorld.numChunks, 0, 20);
spriteBatch.end();
}
public final int voxelsX;
public final int voxelsY;
public final int voxelsZ;
+ public int renderedChunks;
+ public int numChunks;
private final TextureRegion[] tiles;
public VoxelWorld(TextureRegion[] tiles, int chunksX, int chunksY, int chunksZ) {
this.chunksX = chunksX;
this.chunksY = chunksY;
this.chunksZ = chunksZ;
+ this.numChunks = chunksX * chunksY * chunksZ;
this.voxelsX = chunksX * CHUNK_SIZE_X;
this.voxelsY = chunksY * CHUNK_SIZE_Y;
this.voxelsZ = chunksZ * CHUNK_SIZE_Z;
@Override
public void getRenderables (Array<Renderable> renderables, Pool<Renderable> pool) {
+ renderedChunks = 0;
for(int i = 0; i < chunks.length; i++) {
VoxelChunk chunk = chunks[i];
Mesh mesh = meshes[i];
mesh.setVertices(vertices, 0, numVerts * VoxelChunk.VERTEX_SIZE);
dirty[i] = false;
}
+ if(numVertices[i] == 0) continue;
Renderable renderable = pool.obtain();
renderable.material = materials[i];
renderable.mesh = mesh;
renderable.meshPartSize = numVertices[i];
renderable.primitiveType = GL20.GL_TRIANGLES;
renderables.add(renderable);
+ renderedChunks++;
}
}
}
ExternalMusicTest.class, SoftKeyboardTest.class, DirtyRenderingTest.class, YDownTest.class,\r
ScreenCaptureTest.class, BitmapFontTest.class, LabelScaleTest.class, GamepadTest.class, NetAPITest.class, TideMapAssetManagerTest.class, TideMapDirectLoaderTest.class, TiledMapAssetManagerTest.class, TiledMapBench.class,\r
RunnablePostTest.class, Vector2dTest.class, SuperKoalio.class, NinePatchTest.class, Basic3DSceneTest.class, Animation3DTest.class,\r
- ModelTest.class, Basic3DTest.class, ShaderTest.class, SkeletonTest.class, HexagonalTiledMapTest.class, FogTest.class, TimerTest.class));\r
+ ModelTest.class, Basic3DTest.class, ShaderTest.class, SkeletonTest.class, HexagonalTiledMapTest.class, FogTest.class, TimerTest.class, Bresenham2Test.class));\r
\r
public static List<String> getNames () {\r
List<String> names = new ArrayList<String>(tests.size());\r