Replace ShapeRenderer with ShapeDrawer for graph connections

This commit is contained in:
fgnm
2020-09-21 01:06:36 +02:00
parent d1a9a96e92
commit 999ca85e4e
8 changed files with 178 additions and 63 deletions
+28 -1
View File
@@ -2153,7 +2153,7 @@
</p>
</div>
<button class="collapsible">libGDX-graph</button>
<button class="collapsible">libGDX-graph - MIT License</button>
<div class="content">
<p>
MIT License
@@ -2180,6 +2180,33 @@
</p>
</div>
<button class="collapsible">Shape Drawer - MIT License</button>
<div class="content">
<p>
MIT License
Copyright (c) 2019 earlygrey
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.
</p>
</div>
<script>
var coll = document.getElementsByClassName("collapsible");
var i;
+3
View File
@@ -20,6 +20,7 @@ version '0.0.2'
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url 'https://jitpack.io' }
}
ext {
@@ -31,6 +32,7 @@ ext {
spineVersion = '3.8.55.1'
visuiVersion = '1.4.7-SNAPSHOT'
typingLabelVersion = '1.2.0'
shapedrawerVersion = '2.3.0'
packMain = ["art/textures", "assets/style/", "uiskin"]
packSplash = ["art/splash_textures", "assets/splash/", "splash"]
@@ -96,6 +98,7 @@ dependencies {
implementation project(":hyperlap2d-runtime-libgdx")
implementation project(":h2d-libgdx-spine-extension")
implementation "space.earlygrey:shapedrawer:$shapedrawerVersion"
implementation "com.rafaskoberg.gdx:typing-label:$typingLabelVersion"
implementation "com.kotcrab.vis:vis-ui:$visuiVersion"
implementation "com.esotericsoftware.spine:spine-libgdx:$spineVersion"
@@ -31,6 +31,7 @@ import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.ObjectMap;
import games.rednblack.editor.graph.ui.WhitePixel;
import games.rednblack.editor.proxy.CommandManager;
import games.rednblack.editor.proxy.SettingsManager;
import games.rednblack.editor.splash.SplashScreenAdapter;
@@ -69,6 +70,7 @@ public class HyperLap2D implements IProxy, ApplicationListener, Lwjgl3WindowList
@Override
public void create() {
WhitePixel.initializeShared();
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("freetypefonts/DejaVuSans.ttf"));
FreeTypeFontGenerator monoGenerator = new FreeTypeFontGenerator(Gdx.files.internal("freetypefonts/DejaVuSansMono.ttf"));
@@ -227,6 +229,7 @@ public class HyperLap2D implements IProxy, ApplicationListener, Lwjgl3WindowList
@Override
public boolean closeRequested() {
facade.sendNotification(MsgAPI.CHECK_EDITS_ACTION, (Runnable) () -> {
WhitePixel.disposeShared();
sendNotification(MsgAPI.DISPOSE);
VisUI.dispose();
@@ -19,6 +19,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Window;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.DragListener;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.kotcrab.vis.ui.FocusManager;
import games.rednblack.editor.graph.data.FieldType;
import games.rednblack.editor.graph.data.GraphConnection;
@@ -28,6 +29,7 @@ import games.rednblack.editor.graph.data.GraphValidator;
import games.rednblack.editor.graph.data.NodeConnector;
import games.rednblack.editor.graph.data.NodeGroup;
import games.rednblack.editor.graph.property.PropertyBox;
import games.rednblack.editor.graph.ui.WhitePixel;
import games.rednblack.editor.graph.ui.preview.NavigableCanvas;
import com.kotcrab.vis.ui.VisUI;
import com.kotcrab.vis.ui.util.InputValidator;
@@ -36,6 +38,9 @@ import com.kotcrab.vis.ui.util.dialog.InputDialogListener;
import com.kotcrab.vis.ui.widget.MenuItem;
import com.kotcrab.vis.ui.widget.PopupMenu;
import com.kotcrab.vis.ui.widget.VisWindow;
import games.rednblack.editor.utils.poly.PolygonUtils;
import space.earlygrey.shapedrawer.JoinType;
import space.earlygrey.shapedrawer.ShapeDrawer;
import java.awt.BasicStroke;
import java.awt.Shape;
@@ -49,9 +54,10 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
private static final float GROUP_LABEL_HEIGHT = 20f;
private static final float CONNECTOR_LENGTH = 10;
private static final float CONNECTOR_RADIUS = 5;
private static final int LINE_WEIGHT = 4;
private static final Color GROUP_BACKGROUND_COLOR = new Color(1f, 1f, 1f, 0.3f);
private static final Color LINE_COLOR = Color.WHITE;
private static final Color LINE_COLOR = new Color(1, 1, 1,.7f);
private static final Color VALID_CONNECTOR_COLOR = Color.WHITE;
private static final Color INVALID_CONNECTOR_COLOR = Color.RED;
@@ -78,6 +84,8 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
private Map<NodeGroupImpl, Rectangle> nodeGroups = new HashMap<>();
private ShapeRenderer shapeRenderer;
private ShapeDrawer shapeDrawer;
private final Color shapeDrawerColor = new Color();
private NodeConnector drawingFromConnector;
private GraphValidator.ValidationResult<GraphBox<T>, GraphConnection, PropertyBox<T>, T> validationResult = new GraphValidator.ValidationResult<>();
@@ -650,31 +658,20 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
@Override
public void draw(Batch batch, float parentAlpha) {
if (shapeDrawer == null) {
shapeDrawer = new ShapeDrawer(batch, WhitePixel.sharedInstance.textureRegion);
}
validate();
batch.end();
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
drawGroups(batch);
drawConnections(parentAlpha);
Gdx.gl.glDisable(GL20.GL_BLEND);
batch.begin();
drawShapeConnections(parentAlpha);
super.draw(batch, parentAlpha);
}
@Override
public float getX() {
if (parentWindow != null)
return super.getX() + parentWindow.getX();
return super.getX();
}
@Override
public float getY() {
if (parentWindow != null)
return super.getY() + parentWindow.getY();
return super.getY();
}
private void drawGroups(Batch batch) {
if (!nodeGroups.isEmpty()) {
float x = getX();
@@ -701,17 +698,13 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
}
}
private void drawConnections(float parentAlpha) {
private void drawShapeConnections(float parentAlpha) {
float x = getX();
float y = getY();
Vector2 from = new Vector2();
Vector2 to = new Vector2();
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.setColor(LINE_COLOR);
shapeRenderer.getColor().a = parentAlpha;
for (Map.Entry<String, VisWindow> windowEntry : boxWindows.entrySet()) {
String nodeId = windowEntry.getKey();
Window window = windowEntry.getValue();
@@ -723,8 +716,12 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
from.add(x, y);
to.add(x, y);
shapeRenderer.line(from, to);
shapeRenderer.circle(from.x, from.y, CONNECTOR_RADIUS);
shapeDrawerColor.set(VALID_CONNECTOR_COLOR);
shapeDrawerColor.a *= parentAlpha;
shapeDrawer.setColor(shapeDrawerColor);
shapeDrawer.line(from, to);
shapeDrawer.circle(from.x, from.y, CONNECTOR_RADIUS);
}
}
@@ -733,50 +730,35 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
from.add(x, y);
to.add(x, y);
shapeRenderer.line(from, to);
shapeRenderer.circle(from.x, from.y, CONNECTOR_RADIUS);
shapeDrawerColor.set(VALID_CONNECTOR_COLOR);
shapeDrawerColor.a *= parentAlpha;
shapeDrawer.setColor(shapeDrawerColor);
shapeDrawer.line(from, to);
shapeDrawer.circle(from.x, from.y, CONNECTOR_RADIUS);
}
}
for (GraphConnection graphConnection : graphConnections) {
NodeConnector fromNode = getNodeInfo(graphConnection.getNodeFrom(), graphConnection.getFieldFrom());
Window fromWindow = boxWindows.get(fromNode.getNodeId());
GraphBoxOutputConnector<T> output = getGraphBoxById(fromNode.getNodeId()).getOutputs().get(fromNode.getFieldId());
calculateConnection(from, fromWindow, output);
NodeConnector toNode = getNodeInfo(graphConnection.getNodeTo(), graphConnection.getFieldTo());
Window toWindow = boxWindows.get(toNode.getNodeId());
GraphBoxInputConnector<T> input = getGraphBoxById(toNode.getNodeId()).getInputs().get(toNode.getFieldId());
calculateConnection(to, toWindow, input);
boolean error = validationResult.getErrorConnections().contains(graphConnection);
shapeRenderer.setColor(error ? INVALID_CONNECTOR_COLOR : VALID_CONNECTOR_COLOR);
shapeRenderer.getColor().a = parentAlpha;
from.add(x, y);
to.add(x, y);
float xDiff = Math.min(150, Math.abs(from.x - to.x));
shapeRenderer.curve(from.x, from.y, from.x + xDiff, from.y, to.x - xDiff, to.y, to.x, to.y, 50);
}
if (drawingFromConnector != null) {
shapeRenderer.setColor(LINE_COLOR);
shapeRenderer.getColor().a = parentAlpha;
GraphBox<T> drawingFromNode = getGraphBoxById(drawingFromConnector.getNodeId());
Window fromWindow = getBoxWindow(drawingFromConnector.getNodeId());
if (drawingFromNode.isInputField(drawingFromConnector.getFieldId())) {
GraphBoxInputConnector<T> input = drawingFromNode.getInputs().get(drawingFromConnector.getFieldId());
calculateConnection(from, fromWindow, input);
shapeRenderer.line(x + from.x, y + from.y, Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY());
shapeDrawerColor.set(LINE_COLOR);
shapeDrawerColor.a *= parentAlpha;
shapeDrawer.setColor(shapeDrawerColor);
shapeDrawer.line(x + from.x, y + from.y, Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY(), LINE_WEIGHT);
} else {
GraphBoxOutputConnector<T> output = drawingFromNode.getOutputs().get(drawingFromConnector.getFieldId());
calculateConnection(from, fromWindow, output);
shapeRenderer.line(x + from.x, y + from.y, Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY());
shapeDrawerColor.set(LINE_COLOR);
shapeDrawerColor.a *= parentAlpha;
shapeDrawer.setColor(shapeDrawerColor);
shapeDrawer.line(x + from.x, y + from.y, Gdx.input.getX() - parentWindow.getX(), Gdx.graphics.getHeight() - Gdx.input.getY() - parentWindow.getY(), LINE_WEIGHT);
}
}
shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
for (Map.Entry<String, VisWindow> windowEntry : boxWindows.entrySet()) {
String nodeId = windowEntry.getKey();
Window window = windowEntry.getValue();
@@ -795,15 +777,44 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
break;
}
}
shapeRenderer.setColor(isErrorous ? INVALID_CONNECTOR_COLOR : VALID_CONNECTOR_COLOR);
shapeRenderer.getColor().a = parentAlpha;
shapeRenderer.line(from, to);
shapeRenderer.circle(from.x, from.y, CONNECTOR_RADIUS);
shapeDrawerColor.set(isErrorous ? INVALID_CONNECTOR_COLOR : VALID_CONNECTOR_COLOR);
shapeDrawerColor.a *= parentAlpha;
shapeDrawer.setColor(shapeDrawerColor);
shapeDrawer.line(from, to);
shapeDrawer.filledCircle(from.x, from.y, CONNECTOR_RADIUS);
}
}
}
shapeRenderer.end();
for (GraphConnection graphConnection : graphConnections) {
NodeConnector fromNode = getNodeInfo(graphConnection.getNodeFrom(), graphConnection.getFieldFrom());
Window fromWindow = boxWindows.get(fromNode.getNodeId());
GraphBoxOutputConnector<T> output = getGraphBoxById(fromNode.getNodeId()).getOutputs().get(fromNode.getFieldId());
calculateConnection(from, fromWindow, output);
NodeConnector toNode = getNodeInfo(graphConnection.getNodeTo(), graphConnection.getFieldTo());
Window toWindow = boxWindows.get(toNode.getNodeId());
GraphBoxInputConnector<T> input = getGraphBoxById(toNode.getNodeId()).getInputs().get(toNode.getFieldId());
calculateConnection(to, toWindow, input);
boolean error = validationResult.getErrorConnections().contains(graphConnection);
from.add(x, y);
to.add(x, y);
float xDiff = Math.min(150, Math.abs(from.x - to.x));
to.y = from.y - to.y == 0 ? to.y + 1 : to.y;
shapeDrawerColor.set(error ? INVALID_CONNECTOR_COLOR : LINE_COLOR);
shapeDrawerColor.a *= parentAlpha;
shapeDrawer.setColor(shapeDrawerColor);
Array<Vector2> path = PolygonUtils.getCurvedLine(from, to,
PolygonUtils.vector2Pool.obtain().set(from.x + xDiff, from.y),
PolygonUtils.vector2Pool.obtain().set(to.x - xDiff, to.y), 50);
shapeDrawer.path(path, LINE_WEIGHT, JoinType.SMOOTH,true);
PolygonUtils.vector2Pool.freeAll(path);
}
}
private void calculateConnector(Vector2 from, Vector2 to, Window window, GraphBoxOutputConnector<T> connector) {
@@ -20,17 +20,20 @@ public class WhitePixel {
public TextureRegion textureRegion;
public WhitePixel() {
Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGB888);
Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pixmap.setColor(Color.WHITE);
pixmap.fill();
texture = new Texture(pixmap);
texture = new Texture(pixmap, true);
texture.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.MipMapLinearLinear);
textureRegion = new TextureRegion(texture);
}
public void dispose() {
texture.dispose();
texture = null;
textureRegion = null;
if (texture != null) {
texture.dispose();
texture = null;
textureRegion = null;
}
}
}
@@ -0,0 +1,16 @@
package games.rednblack.editor.utils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Pool;
public class Vector2Pool extends Pool<Vector2> {
public Vector2Pool(int capacity) {
super(capacity);
}
@Override
protected Vector2 newObject() {
return new Vector2();
}
}
@@ -20,6 +20,9 @@ package games.rednblack.editor.utils.poly;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pool;
import games.rednblack.editor.utils.Vector2Pool;
import games.rednblack.editor.view.stage.Sandbox;
import java.util.HashSet;
@@ -116,4 +119,52 @@ public class PolygonUtils {
return result;
}
public static Pool<Vector2> vector2Pool = new Vector2Pool(60);
private static final Array<Vector2> tmpResult = new Array<>();
public static Array<Vector2> getCurvedLine(Vector2 from, Vector2 to, Vector2 center1, Vector2 center2, int segments) {
tmpResult.clear();
float subdiv_step = 1f / segments;
float subdiv_step2 = subdiv_step * subdiv_step;
float subdiv_step3 = subdiv_step * subdiv_step * subdiv_step;
float pre1 = 3 * subdiv_step;
float pre2 = 3 * subdiv_step2;
float pre4 = 6 * subdiv_step2;
float pre5 = 6 * subdiv_step3;
float tmp1x = from.x - center1.x * 2 + center2.x;
float tmp1y = from.y - center1.y * 2 + center2.y;
float tmp2x = (center1.x - center2.x) * 3 - from.x + to.x;
float tmp2y = (center1.y - center2.y) * 3 - from.y + to.y;
float fx = from.x;
float fy = from.y;
float dfx = (center1.x - from.x) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
float dfy = (center1.y - from.y) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
float ddfx = tmp1x * pre4 + tmp2x * pre5;
float ddfy = tmp1y * pre4 + tmp2y * pre5;
float dddfx = tmp2x * pre5;
float dddfy = tmp2y * pre5;
while (segments-- > 0) {
tmpResult.add(vector2Pool.obtain().set(fx, fy));
fx += dfx;
fy += dfy;
dfx += ddfx;
dfy += ddfy;
ddfx += dddfx;
ddfy += dddfy;
}
tmpResult.add(vector2Pool.obtain().set(fx, fy));
tmpResult.add(vector2Pool.obtain().set(to.x, to.y));
return tmpResult;
}
}
@@ -73,6 +73,7 @@ public class AboutDialog extends H2DDialog {
contentTable.add(new LinkLabel("- LibGDX Spriter [https://github.com/Trixt0r/gdx-spriter]", "https://github.com/Trixt0r/gdx-spriter")).padLeft(6).left().row();
contentTable.add(new LinkLabel("- Physics Body Editor [https://www.aurelienribon.com]", "https://www.aurelienribon.com")).padLeft(6).left().row();
contentTable.add(new LinkLabel("- Typing Label [https://github.com/rafaskb/typing-label]", "https://github.com/rafaskb/typing-label")).padLeft(6).left().row();
contentTable.add(new LinkLabel("- Shape Drawer [https://github.com/earlygrey/shapedrawer]", "https://github.com/earlygrey/shapedrawer")).padLeft(6).left().row();
contentTable.add("\n").row();
VisTable legalTable = new VisTable();
legalTable.add(new LinkLabel("See Contributors list", "https://github.com/rednblackgames/HyperLap2D/blob/master/AUTHORS"));