feat(renderer): enhance G2DDrawControl with visible area management and optimize intersection checks in SpatialUtils2
This commit is contained in:
@@ -29,11 +29,12 @@ import de.extio.game_engine.renderer.model.RenderingBo;
|
||||
import de.extio.game_engine.renderer.model.RenderingBoLayer;
|
||||
import de.extio.game_engine.renderer.model.bo.ControlRenderingBo;
|
||||
import de.extio.game_engine.renderer.model.bo.HorizontalAlignment;
|
||||
import de.extio.game_engine.renderer.model.color.RgbaColor;
|
||||
import de.extio.game_engine.resource.StaticResource;
|
||||
import de.extio.game_engine.spatial2.SpatialUtils2;
|
||||
import de.extio.game_engine.spatial2.model.Area2;
|
||||
import de.extio.game_engine.spatial2.model.ImmutableCoordI2;
|
||||
import de.extio.game_engine.renderer.model.color.RgbaColor;
|
||||
import de.extio.game_engine.spatial2.model.MutableCoordI2;
|
||||
|
||||
@Conditional(G2DRendererCondition.class)
|
||||
@Component
|
||||
@@ -67,6 +68,12 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen
|
||||
|
||||
private String tooltip;
|
||||
|
||||
private Area2 visibleArea = null;
|
||||
|
||||
private Area2 controlArea = null;
|
||||
|
||||
private final Area2 tempArea = new Area2(MutableCoordI2.create(), MutableCoordI2.create());
|
||||
|
||||
public G2DDrawControl() {
|
||||
super(RenderingBoLayer.UI0);
|
||||
}
|
||||
@@ -137,13 +144,33 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderingBo withVisibleArea(final int x, final int y, final int width, final int height) {
|
||||
if (this.visibleArea == null ||
|
||||
this.visibleArea.getPosition().getX() != x ||
|
||||
this.visibleArea.getPosition().getY() != y ||
|
||||
this.visibleArea.getDimension().getX() != width ||
|
||||
this.visibleArea.getDimension().getY() != height) {
|
||||
|
||||
this.visibleArea = new Area2(ImmutableCoordI2.create(x, y), ImmutableCoordI2.create(width, height));
|
||||
super.withVisibleArea(x, y, width, height);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(final Graphics2D graphics, final double scaleFactor, final boolean force) {
|
||||
if (visibleAreaX != 0 || visibleAreaY != 0 || visibleAreaWidth != 0 || visibleAreaHeight != 0) {
|
||||
final var controlArea = new Area2(ImmutableCoordI2.create(this.x, this.y), ImmutableCoordI2.create(this.width, this.height));
|
||||
final var visibleArea = new Area2(ImmutableCoordI2.create(this.visibleAreaX, this.visibleAreaY), ImmutableCoordI2.create(this.visibleAreaWidth, this.visibleAreaHeight));
|
||||
final var intersection = SpatialUtils2.intersectAreas(controlArea, visibleArea);
|
||||
if (intersection == null) {
|
||||
if (this.controlArea == null ||
|
||||
this.controlArea.getPosition().getX() != this.x ||
|
||||
this.controlArea.getPosition().getY() != this.y ||
|
||||
this.controlArea.getDimension().getX() != this.width ||
|
||||
this.controlArea.getDimension().getY() != this.height) {
|
||||
|
||||
this.controlArea = new Area2(ImmutableCoordI2.create(this.x, this.y), ImmutableCoordI2.create(this.width, this.height));
|
||||
}
|
||||
if (!SpatialUtils2.intersectAreasMutable(this.controlArea, this.visibleArea, this.tempArea)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -347,6 +374,8 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen
|
||||
this.visible = o.visible;
|
||||
this.enabled = o.enabled;
|
||||
this.tooltip = o.tooltip;
|
||||
this.visibleArea = o.visibleArea;
|
||||
this.controlArea = o.controlArea;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,6 +395,8 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen
|
||||
this.visible = false;
|
||||
this.enabled = true;
|
||||
this.tooltip = null;
|
||||
this.visibleArea = null;
|
||||
this.controlArea = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package de.extio.game_engine.spatial2;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -188,19 +187,16 @@ public final class SpatialUtils2 {
|
||||
*/
|
||||
// @Deprecated
|
||||
public static RectI2 intersectRectangles(final RectI2 r0, final RectI2 r1) {
|
||||
final CoordI2 size0 = ImmutableCoordI2.create(r0.getC1().getX() - r0.getC0().getX(), r0.getC1().getY() - r0.getC0().getY());
|
||||
final CoordI2 size1 = ImmutableCoordI2.create(r1.getC1().getX() - r1.getC0().getX(), r1.getC1().getY() - r1.getC0().getY());
|
||||
final var rect0 = new Rectangle(r0.getC0().getX(), r0.getC0().getY(), size0.getX(), size0.getY());
|
||||
final var rect1 = new Rectangle(r1.getC0().getX(), r1.getC0().getY(), size1.getX(), size1.getY());
|
||||
|
||||
final var intersection = rect0.intersection(rect1);
|
||||
if (intersection.isEmpty()) {
|
||||
final Area2 a0 = new Area2(r0.getC0(), r0.getC1().toImmutableCoordI2().substract(r0.getC0()));
|
||||
final Area2 a1 = new Area2(r1.getC0(), r1.getC1().toImmutableCoordI2().substract(r1.getC0()));
|
||||
final Area2 intersection = new Area2(MutableCoordI2.create(), MutableCoordI2.create());
|
||||
final boolean intersects = SpatialUtils2.intersectAreasMutable(a0, a1, intersection);
|
||||
if (!intersects) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new RectI2(
|
||||
ImmutableCoordI2.create((int) intersection.getX(), (int) intersection.getY()),
|
||||
ImmutableCoordI2.create((int) (intersection.getX() + intersection.getWidth()), (int) (intersection.getY() + intersection.getHeight())));
|
||||
intersection.getPosition().toImmutableCoordI2(),
|
||||
intersection.getPosition().toImmutableCoordI2().add(intersection.getDimension().toImmutableCoordI2()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,17 +206,50 @@ public final class SpatialUtils2 {
|
||||
* @return The intersected area if r0 and r1 overlap, else null
|
||||
*/
|
||||
public static Area2 intersectAreas(final HasPositionAndDimension2 a0, final HasPositionAndDimension2 a1) {
|
||||
final var rect0 = new Rectangle(a0.getPosition().getX(), a0.getPosition().getY(), a0.getDimension().getX(), a0.getDimension().getY());
|
||||
final var rect1 = new Rectangle(a1.getPosition().getX(), a1.getPosition().getY(), a1.getDimension().getX(), a1.getDimension().getY());
|
||||
|
||||
final var intersection = rect0.intersection(rect1);
|
||||
if (intersection.isEmpty()) {
|
||||
final Area2 intersection = new Area2(MutableCoordI2.create(), MutableCoordI2.create());
|
||||
final boolean intersects = SpatialUtils2.intersectAreasMutable(a0, a1, intersection);
|
||||
if (!intersects) {
|
||||
return null;
|
||||
}
|
||||
intersection.setPosition(intersection.getPosition().toImmutableCoordI2());
|
||||
intersection.setDimension(intersection.getDimension().toImmutableCoordI2());
|
||||
return intersection;
|
||||
}
|
||||
|
||||
return new Area2(
|
||||
ImmutableCoordI2.create((int) intersection.getX(), (int) intersection.getY()),
|
||||
ImmutableCoordI2.create((int) intersection.getWidth(), (int) intersection.getHeight()));
|
||||
/**
|
||||
* Intersects 2 areas and writes the result into a mutable result area
|
||||
* @param r0 Area 0
|
||||
* @param r1 Area 1
|
||||
* @param mutableResult Area to write the result into. The position and dimension will be modified in-place and must be mutable.
|
||||
* @return true if there is no intersection, false otherwise
|
||||
*/
|
||||
public static boolean intersectAreasMutable(final HasPositionAndDimension2 a0, final HasPositionAndDimension2 a1, final HasPositionAndDimension2 mutableResult) {
|
||||
int tx1 = a0.getPosition().getX();
|
||||
int ty1 = a0.getPosition().getY();
|
||||
final int rx1 = a1.getPosition().getX();
|
||||
final int ry1 = a1.getPosition().getY();
|
||||
long tx2 = tx1 + a0.getDimension().getX();
|
||||
long ty2 = ty1 + a0.getDimension().getY();
|
||||
final long rx2 = rx1 + a1.getDimension().getX();
|
||||
final long ry2 = ry1 + a1.getDimension().getY();
|
||||
if (tx1 < rx1) {
|
||||
tx1 = rx1;
|
||||
}
|
||||
if (ty1 < ry1) {
|
||||
ty1 = ry1;
|
||||
}
|
||||
if (tx2 > rx2) {
|
||||
tx2 = rx2;
|
||||
}
|
||||
if (ty2 > ry2) {
|
||||
ty2 = ry2;
|
||||
}
|
||||
tx2 = Math.max(Integer.MIN_VALUE, tx2 - tx1);
|
||||
ty2 = Math.max(Integer.MIN_VALUE, ty2 - ty1);
|
||||
|
||||
mutableResult.getPosition().setXY(tx1, ty1);
|
||||
mutableResult.getDimension().setXY((int) tx2, (int) ty2);
|
||||
return (tx2 > 0) && (ty2 > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user