mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-03 06:09:09 +08:00
[libgdx] Refactored clipping code to take array, offset, stride, added triangulation and barycentric interpolation of UVs.
This commit is contained in:
parent
b3ac8a7f72
commit
c73971eb4c
@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
package com.esotericsoftware.spine;
|
package com.esotericsoftware.spine;
|
||||||
|
|
||||||
|
import javax.management.BadBinaryOpValueExpException;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
import com.badlogic.gdx.ApplicationAdapter;
|
import com.badlogic.gdx.ApplicationAdapter;
|
||||||
@ -11,29 +13,45 @@ import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
|||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.GL20;
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
||||||
import com.badlogic.gdx.math.Vector3;
|
import com.badlogic.gdx.math.Vector3;
|
||||||
import com.badlogic.gdx.utils.FloatArray;
|
import com.badlogic.gdx.utils.FloatArray;
|
||||||
|
import com.badlogic.gdx.utils.ShortArray;
|
||||||
import com.esotericsoftware.spine.utils.SutherlandHodgmanClipper;
|
import com.esotericsoftware.spine.utils.SutherlandHodgmanClipper;
|
||||||
|
|
||||||
public class SoftwareClippingTest extends ApplicationAdapter {
|
public class SoftwareClippingTest extends ApplicationAdapter {
|
||||||
OrthographicCamera sceneCamera;
|
OrthographicCamera sceneCamera;
|
||||||
ShapeRenderer shapes;
|
ShapeRenderer shapes;
|
||||||
|
PolygonSpriteBatch polyBatcher;
|
||||||
|
Texture image;
|
||||||
|
|
||||||
float[] triangle = {100, 100, 300, 100, 200, 300};
|
float[] triangleOutline = { 100, 100, 300, 100, 200, 300 };
|
||||||
|
float[] triangle = {
|
||||||
|
100, 100, Color.WHITE.toFloatBits(), 0, 1,
|
||||||
|
300, 100, Color.WHITE.toFloatBits(), 1, 1,
|
||||||
|
200, 300, Color.WHITE.toFloatBits(), 0.5f, 0
|
||||||
|
};
|
||||||
|
short[] triangleIndices = { 0, 1, 2 };
|
||||||
FloatArray clippingPolygon = new FloatArray();
|
FloatArray clippingPolygon = new FloatArray();
|
||||||
FloatArray clippedPolygon = new FloatArray();
|
FloatArray clippedPolygon = new FloatArray();
|
||||||
|
|
||||||
|
FloatArray clippedPolygonVertices = new FloatArray();
|
||||||
|
ShortArray clippedPolygonIndices = new ShortArray();
|
||||||
|
|
||||||
boolean isCreatingClippingArea = false;
|
boolean isCreatingClippingArea = false;
|
||||||
Vector3 tmp = new Vector3();
|
Vector3 tmp = new Vector3();
|
||||||
SutherlandHodgmanClipper clipper;
|
SutherlandHodgmanClipper clipper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create () {
|
public void create () {
|
||||||
sceneCamera = new OrthographicCamera();
|
sceneCamera = new OrthographicCamera();
|
||||||
shapes = new ShapeRenderer();
|
shapes = new ShapeRenderer();
|
||||||
|
polyBatcher = new PolygonSpriteBatch();
|
||||||
clipper = new SutherlandHodgmanClipper();
|
clipper = new SutherlandHodgmanClipper();
|
||||||
|
image = new Texture("skin/skin.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -73,11 +91,23 @@ public class SoftwareClippingTest extends ApplicationAdapter {
|
|||||||
private void renderScene () {
|
private void renderScene () {
|
||||||
sceneCamera.update();
|
sceneCamera.update();
|
||||||
shapes.setProjectionMatrix(sceneCamera.combined);
|
shapes.setProjectionMatrix(sceneCamera.combined);
|
||||||
|
polyBatcher.setProjectionMatrix(sceneCamera.combined);
|
||||||
|
|
||||||
|
polyBatcher.begin();
|
||||||
|
polyBatcher.disableBlending();
|
||||||
|
|
||||||
|
if (clippedPolygon.size == 0) {
|
||||||
|
polyBatcher.draw(image, triangle, 0, 15, triangleIndices, 0, 3);
|
||||||
|
} else {
|
||||||
|
polyBatcher.draw(image, clippedPolygonVertices.items, 0, clippedPolygonVertices.size, clippedPolygonIndices.items, 0, clippedPolygonIndices.size);
|
||||||
|
}
|
||||||
|
polyBatcher.end();
|
||||||
|
|
||||||
shapes.begin(ShapeType.Line);
|
shapes.begin(ShapeType.Line);
|
||||||
|
|
||||||
// triangle
|
// triangle
|
||||||
shapes.setColor(Color.GREEN);
|
shapes.setColor(Color.GREEN);
|
||||||
shapes.polygon(triangle);
|
shapes.polygon(triangleOutline);
|
||||||
|
|
||||||
// clipped polygons
|
// clipped polygons
|
||||||
shapes.setColor(Color.RED);
|
shapes.setColor(Color.RED);
|
||||||
@ -146,10 +176,54 @@ public class SoftwareClippingTest extends ApplicationAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void clip () {
|
private void clip () {
|
||||||
FloatArray input = new FloatArray();
|
boolean clipped = clipper.clip(triangle, 0, triangle.length, 5, clippingPolygon, clippedPolygon);
|
||||||
input.addAll(triangle, 0, triangle.length);
|
System.out.println("Clipped: " + clipped);
|
||||||
clippedPolygon.clear();
|
if (clipped) {
|
||||||
System.out.println("Clipped: " + (clipper.clip(input, clippingPolygon, clippedPolygon) != null));
|
clippedPolygonVertices.clear();
|
||||||
|
clippedPolygonIndices.clear();
|
||||||
|
|
||||||
|
float x1 = triangle[0];
|
||||||
|
float y1 = triangle[1];
|
||||||
|
float x2 = triangle[5];
|
||||||
|
float y2 = triangle[6];
|
||||||
|
float x3 = triangle[10];
|
||||||
|
float y3 = triangle[11];
|
||||||
|
|
||||||
|
float d0 = y2 - y3;
|
||||||
|
float d1 = x3 - x2;
|
||||||
|
float d2 = x1 - x3;
|
||||||
|
float d3 = y1 - y3;
|
||||||
|
float d4 = y3 - y1;
|
||||||
|
|
||||||
|
float denom = 1 / (d0 * d2 + d1 * d3);
|
||||||
|
|
||||||
|
// triangulate by creating a triangle fan, duplicate vertices
|
||||||
|
float color = Color.WHITE.toFloatBits();
|
||||||
|
for (int i = 0; i < clippedPolygon.size; i+=2) {
|
||||||
|
float x = clippedPolygon.get(i);
|
||||||
|
float y = clippedPolygon.get(i + 1);
|
||||||
|
|
||||||
|
float a = (d0 * (x - x3) + d1 * (y - y3)) * denom;
|
||||||
|
float b = (d4 * (x - x3) + d2 * (y - y3)) * denom;
|
||||||
|
float c = 1.0f - a - b;
|
||||||
|
|
||||||
|
float u = triangle[3] * a + triangle[8] * b + triangle[13] * c;
|
||||||
|
float v = triangle[4] * a + triangle[9] * b + triangle[14] * c;
|
||||||
|
clippedPolygonVertices.add(x);
|
||||||
|
clippedPolygonVertices.add(y);
|
||||||
|
clippedPolygonVertices.add(color);
|
||||||
|
clippedPolygonVertices.add(u);
|
||||||
|
clippedPolygonVertices.add(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < (clippedPolygon.size >> 1) - 1; i++) {
|
||||||
|
clippedPolygonIndices.add(0);
|
||||||
|
clippedPolygonIndices.add(i);
|
||||||
|
clippedPolygonIndices.add(i + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clippedPolygon.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main (String[] args) {
|
public static void main (String[] args) {
|
||||||
|
|||||||
@ -7,13 +7,26 @@ import com.badlogic.gdx.utils.FloatArray;
|
|||||||
|
|
||||||
public class SutherlandHodgmanClipper {
|
public class SutherlandHodgmanClipper {
|
||||||
Vector2 tmp = new Vector2();
|
Vector2 tmp = new Vector2();
|
||||||
|
final FloatArray scratch = new FloatArray();
|
||||||
|
|
||||||
public FloatArray clip (FloatArray input, FloatArray clippingArea, FloatArray output) {
|
/**
|
||||||
|
* Clips the input triangle against the convex clipping area. If the triangle lies entirely
|
||||||
|
* within the clipping area, false is returned.
|
||||||
|
*/
|
||||||
|
public boolean clip (float[] triangle, int offset, int length, int stride, FloatArray clippingArea, FloatArray output) {
|
||||||
boolean isClockwise = clockwise(clippingArea);
|
boolean isClockwise = clockwise(clippingArea);
|
||||||
|
|
||||||
FloatArray originalOutput = output;
|
FloatArray originalOutput = output;
|
||||||
boolean clipped = false;
|
boolean clipped = false;
|
||||||
|
|
||||||
|
FloatArray input = scratch;
|
||||||
|
input.clear();
|
||||||
|
for (int i = offset; i < offset + length; i+= stride) {
|
||||||
|
input.add(triangle[i]);
|
||||||
|
input.add(triangle[i + 1]);
|
||||||
|
}
|
||||||
|
output.clear();
|
||||||
|
|
||||||
for (int i = 0; i < clippingArea.size; i += 2) {
|
for (int i = 0; i < clippingArea.size; i += 2) {
|
||||||
float edgeX = clippingArea.items[i];
|
float edgeX = clippingArea.items[i];
|
||||||
float edgeY = clippingArea.items[i + 1];
|
float edgeY = clippingArea.items[i + 1];
|
||||||
@ -40,8 +53,8 @@ public class SutherlandHodgmanClipper {
|
|||||||
|
|
||||||
System.out.println("\tinput " + j / 2 + ": (" + inputX + ", " + inputY + ")-(" + inputX2 + ", " + inputY2 + ")");
|
System.out.println("\tinput " + j / 2 + ": (" + inputX + ", " + inputY + ")-(" + inputX2 + ", " + inputY2 + ")");
|
||||||
|
|
||||||
int side = Intersector.pointLineSide(edgeX2, edgeY2, edgeX, edgeY, inputX, inputY);
|
int side = pointLineSide(edgeX2, edgeY2, edgeX, edgeY, inputX, inputY);
|
||||||
int side2 = Intersector.pointLineSide(edgeX2, edgeY2, edgeX, edgeY, inputX2, inputY2);
|
int side2 = pointLineSide(edgeX2, edgeY2, edgeX, edgeY, inputX2, inputY2);
|
||||||
System.out.println("\tv1: " + (side < 0 ? "outside" : "inside" ) + ", v2: " + (side2 < 0 ? "outside" : "inside"));
|
System.out.println("\tv1: " + (side < 0 ? "outside" : "inside" ) + ", v2: " + (side2 < 0 ? "outside" : "inside"));
|
||||||
|
|
||||||
// v1 inside, v2 inside
|
// v1 inside, v2 inside
|
||||||
@ -89,7 +102,7 @@ public class SutherlandHodgmanClipper {
|
|||||||
originalOutput.addAll(output.items, 0, output.size);
|
originalOutput.addAll(output.items, 0, output.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clipped ? output : null;
|
return clipped;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int pointLineSide(float lineX, float lineY, float lineX2, float lineY2, float pointX, float pointY) {
|
private int pointLineSide(float lineX, float lineY, float lineX2, float lineY2, float pointX, float pointY) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user