More work on the engine.
- Added: Animation Features (Delays/reverse playing/etc) - Added: Joystick can now work when no window is focused (per window setting) - Changed: BitUtil functions to with better names.
This commit is contained in:
parent
afa3215abd
commit
099eec4fe4
|
@ -29,7 +29,6 @@ public class NewInputTest {
|
|||
manager.addDevices(Mouse.INSTANCE, Keyboard.INSTANCE, Joystick.INSTANCE, FileDrop.INSTANCE);
|
||||
Window window = manager.builder().title("Testing Engine").build();
|
||||
window.visible(true);
|
||||
//TODO implement window close requests
|
||||
while(!window.shouldClose()) {
|
||||
GLFW.glfwPollEvents();
|
||||
window.beginFrame();
|
||||
|
|
|
@ -1,42 +1,36 @@
|
|||
package speiger.src.coreengine.math;
|
||||
|
||||
import speiger.src.coreengine.math.vector.ints.Vec2i;
|
||||
|
||||
public class BitUtil {
|
||||
public static long toLong(long firstShort, long secondShort) {
|
||||
return (firstShort << 32) | (secondShort & 0xFFFFFFFFL);
|
||||
public static long toLong(long key, long value) {
|
||||
return (key << 32L) | (value & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
public static int toFirstInt(long value) {
|
||||
public static int intKey(long value) {
|
||||
return (int)((value >> 32) & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
public static int toSecondInt(long value) {
|
||||
public static int intValue(long value) {
|
||||
return (int)(value & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
public static long addToLong(long value, long x, long z) {
|
||||
return ((x + toFirstInt(value)) & 0xFFFFFFFFL) << 32 | (((z + toSecondInt(value)) & 0xFFFFFFFFL));
|
||||
public static long intAdd(long source, long key, long value) {
|
||||
return toLong(key + intKey(source), value + intValue(source));
|
||||
}
|
||||
|
||||
public static int toInt(int firstShort, int secondShort) {
|
||||
return (firstShort & 0xFFFF) << 16 | (secondShort & 0xFFFF);
|
||||
public static int toInt(int key, int value) {
|
||||
return (key & 0xFFFF) << 16 | (value & 0xFFFF);
|
||||
}
|
||||
|
||||
public static int toFirstShort(int value) {
|
||||
public static int shortKey(int value) {
|
||||
return (short)(value >> 16 & 0xFFFF);
|
||||
}
|
||||
|
||||
public static int toSecondShort(int value) {
|
||||
public static int shortValue(int value) {
|
||||
return (short)(value & 0xFFFF);
|
||||
}
|
||||
|
||||
public static int addToInt(int value, int x, int z) {
|
||||
return ((x + toFirstShort(value)) & 0xFFFF) << 16 | ((z + toSecondShort(value)) & 0xFFFF);
|
||||
}
|
||||
|
||||
public static int addToInt(int value, Vec2i offset) {
|
||||
return ((offset.x() + toFirstShort(value)) & 0xFFFF) << 16 | ((offset.y() + toSecondShort(value)) & 0xFFFF);
|
||||
public static int shortAdd(int source, int key, int value) {
|
||||
return toInt(key + shortKey(source), value + shortValue(source));
|
||||
}
|
||||
|
||||
public static int pack_2_10_10_10_int_rev(float x, float y, float z, float w) {
|
||||
|
|
|
@ -48,27 +48,27 @@ public class MathUtils {
|
|||
}
|
||||
|
||||
public static byte sign(byte value) {
|
||||
return value > 0 ? 1 : (value < 0 ? -1 : (byte)0);
|
||||
return (byte)Integer.signum(value);
|
||||
}
|
||||
|
||||
public static short sign(short value) {
|
||||
return value > 0 ? 1 : (value < 0 ? -1 : (short)0);
|
||||
return (short)Integer.signum(value);
|
||||
}
|
||||
|
||||
public static int sign(int value) {
|
||||
return value > 0 ? 1 : (value < 0 ? -1 : 0);
|
||||
return Integer.signum(value);
|
||||
}
|
||||
|
||||
public static long sign(long value) {
|
||||
return value > 0 ? 1 : (value < 0 ? -1 : 0);
|
||||
return Long.signum(value);
|
||||
}
|
||||
|
||||
public static float sign(float value) {
|
||||
return value > 0 ? 1F : (value < 0 ? -1F : 0F);
|
||||
return Math.signum(value);
|
||||
}
|
||||
|
||||
public static double sign(double value) {
|
||||
return value > 0 ? 1D : (value < 0 ? -1D : 0D);
|
||||
return Math.signum(value);
|
||||
}
|
||||
|
||||
public static int sub(int key, int value) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import speiger.src.coreengine.math.vector.ints.Vec2i;
|
|||
|
||||
public class ShapeUtil {
|
||||
public static boolean isInCircle(int position, int radius, int testX, int testZ) {
|
||||
return isInCircle(BitUtil.toFirstShort(position), BitUtil.toSecondShort(position), radius, testX, testZ);
|
||||
return isInCircle(BitUtil.shortKey(position), BitUtil.shortValue(position), radius, testX, testZ);
|
||||
}
|
||||
|
||||
public static boolean isInCircle(Vec2i position, int radius, int testX, int testZ) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import speiger.src.coreengine.math.vector.ints.Vec2i;
|
|||
public interface I2DCollision extends Iterable<Vec2i>
|
||||
{
|
||||
public default boolean isMixedCollision() {return false;}
|
||||
public default boolean isColliding(int position){return isColliding(BitUtil.toFirstShort(position), BitUtil.toSecondShort(position));}
|
||||
public default boolean isColliding(int position){return isColliding(BitUtil.shortKey(position), BitUtil.shortValue(position));}
|
||||
public default boolean isColliding(Vec2i pos){return isColliding(pos.x(), pos.y());}
|
||||
public boolean isColliding(int x, int y);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public class GuiAnimation {
|
|||
public void apply(GuiComponent owner, float progress) {
|
||||
for(Entry<Target, IAction> entry : Object2ObjectMaps.fastIterable(actions)) {
|
||||
IAction action = entry.getValue();
|
||||
action.apply(entry.getKey(), Math.min(progress, action.duration()));
|
||||
action.apply(entry.getKey(), owner, Math.min(progress, action.duration()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,41 @@
|
|||
package speiger.src.coreengine.rendering.gui.animation;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.animation.GuiAnimation.Target;
|
||||
import speiger.src.coreengine.rendering.gui.components.base.GuiComponent;
|
||||
|
||||
public interface IAction {
|
||||
public float duration();
|
||||
public void apply(Target target, float progress);
|
||||
public void apply(Target target, GuiComponent component, float progress);
|
||||
public default IAction withPreDelay(float delay) { return this instanceof PreDelayedAction delayed ? new PreDelayedAction(delayed.action(), delay + delayed.delay()) : new PreDelayedAction(this, delay); }
|
||||
public default IAction withPostDelay(float delay) { return this instanceof PostDelayedAction delayed ? new PostDelayedAction(delayed.action(), delay + delayed.delay()) : new PostDelayedAction(this, delay); }
|
||||
public default IAction reverse() { return this instanceof ReversedAction reversed ? reversed.action() : new ReversedAction(this); }
|
||||
|
||||
public record PreDelayedAction(IAction action, float delay) implements IAction {
|
||||
@Override
|
||||
public float duration() { return delay + action.duration(); }
|
||||
@Override
|
||||
public void apply(Target target, GuiComponent component, float progress) {
|
||||
action.apply(target, component, Math.max(progress - delay, 0F));
|
||||
}
|
||||
}
|
||||
|
||||
public record PostDelayedAction(IAction action, float delay) implements IAction {
|
||||
@Override
|
||||
public float duration() { return action.duration() + delay; }
|
||||
@Override
|
||||
public void apply(Target target, GuiComponent component, float progress) {
|
||||
action.apply(target, component, Math.min(progress, action.duration()));
|
||||
}
|
||||
}
|
||||
|
||||
public record ReversedAction(IAction action) implements IAction {
|
||||
@Override
|
||||
public float duration() { return action.duration(); }
|
||||
@Override
|
||||
public void apply(Target target, GuiComponent component, float progress) {
|
||||
action.apply(target, component, action.duration() - progress);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -14,6 +14,8 @@ import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
|
|||
import speiger.src.collections.ints.sets.IntLinkedOpenHashSet;
|
||||
import speiger.src.collections.ints.sets.IntSet;
|
||||
import speiger.src.collections.longs.collections.LongIterator;
|
||||
import speiger.src.collections.longs.sets.LongOpenHashSet;
|
||||
import speiger.src.collections.longs.sets.LongSet;
|
||||
import speiger.src.coreengine.rendering.input.devices.Joystick.JoyStickData;
|
||||
import speiger.src.coreengine.rendering.input.devices.Joystick.JoyStickTask;
|
||||
import speiger.src.coreengine.rendering.input.events.JoystickEvent;
|
||||
|
@ -24,6 +26,7 @@ public class Joystick extends AbstractDevice<JoyStickData, JoyStickTask> {
|
|||
public static final Joystick INSTANCE = new Joystick();
|
||||
WindowManager manager;
|
||||
IntSet presentJoysticks = new IntLinkedOpenHashSet();
|
||||
LongSet alwaysProcessInputs = new LongOpenHashSet();
|
||||
|
||||
public void init(WindowManager manager, EventBus bus) {
|
||||
this.manager = manager;
|
||||
|
@ -31,7 +34,7 @@ public class Joystick extends AbstractDevice<JoyStickData, JoyStickTask> {
|
|||
manager.addCallback(this::plugin, GLFW::glfwSetJoystickCallback);
|
||||
for(int i = 0,m=GLFW.GLFW_JOYSTICK_LAST;i<=m;i++) {
|
||||
if(GLFW.glfwJoystickPresent(i)) {
|
||||
presentJoysticks.add(i);
|
||||
plugin(i, GLFW.GLFW_CONNECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +42,15 @@ public class Joystick extends AbstractDevice<JoyStickData, JoyStickTask> {
|
|||
@Override
|
||||
public void init(EventBus bus) { throw new UnsupportedOperationException("Use init(WindowManager, EventBus) instead"); }
|
||||
|
||||
public void setWindowAlwaysProcessInputs(long windowId, boolean value) {
|
||||
if(value) alwaysProcessInputs.add(windowId);
|
||||
else alwaysProcessInputs.remove(windowId);
|
||||
}
|
||||
|
||||
public boolean isWindowAlwaysProcessingInputs(long windowId) {
|
||||
return alwaysProcessInputs.contains(windowId);
|
||||
}
|
||||
|
||||
private void plugin(int jid, int event) {
|
||||
if(event == GLFW.GLFW_CONNECTED) presentJoysticks.add(jid);
|
||||
else presentJoysticks.remove(jid);
|
||||
|
@ -51,14 +63,14 @@ public class Joystick extends AbstractDevice<JoyStickData, JoyStickTask> {
|
|||
@Override
|
||||
public void reset(long windowId) {}
|
||||
@Override
|
||||
protected JoyStickData createData(long windowId) { return new JoyStickData(); }
|
||||
protected JoyStickData createData(long windowId) { return new JoyStickData(presentJoysticks); }
|
||||
@Override
|
||||
protected void process(JoyStickTask task) { task.process(this); }
|
||||
|
||||
@Override
|
||||
public void processInput(long windowId) {
|
||||
super.processInput(windowId);
|
||||
if(manager.getActiveWindow() != windowId) return;
|
||||
if(manager.getActiveWindow() != windowId && !alwaysProcessInputs.contains(windowId)) return;
|
||||
JoyStickData data = get(windowId);
|
||||
if(data == null) return;
|
||||
for(IntIterator iter = presentJoysticks.iterator();iter.hasNext();) {
|
||||
|
@ -97,6 +109,12 @@ public class Joystick extends AbstractDevice<JoyStickData, JoyStickTask> {
|
|||
|
||||
public static class JoyStickData {
|
||||
Int2ObjectMap<ButtonData> data = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public JoyStickData(IntSet knownJoysticks) {
|
||||
for(IntIterator iter = knownJoysticks.iterator();iter.hasNext();) {
|
||||
data.put(iter.nextInt(), new ButtonData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ButtonData {
|
||||
|
|
|
@ -23,7 +23,7 @@ public class TextureMetadata {
|
|||
public void applyArguments(int texture) {
|
||||
for(int i = 0,m=arguments.size();i<m;i++) {
|
||||
long value = arguments.getLong(i);
|
||||
GL45.glTextureParameteri(texture, BitUtil.toFirstInt(value), BitUtil.toSecondInt(value));
|
||||
GL45.glTextureParameteri(texture, BitUtil.intKey(value), BitUtil.intValue(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ public class TextureMetadata {
|
|||
public Builder removeArgument(int id) {
|
||||
LongList list = metadata.arguments;
|
||||
for(int i = 0,m=list.size();i<m;i++) {
|
||||
if(BitUtil.toFirstInt(list.getLong(i)) == id) {
|
||||
if(BitUtil.intKey(list.getLong(i)) == id) {
|
||||
list.removeLong(i--);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ public class DynamicTexture extends BaseTexture implements IDynamicTexture {
|
|||
Thread thread = Thread.currentThread();
|
||||
for(IntIterator iter = dirtySections.iterator();iter.hasNext() && !thread.isInterrupted();iter.remove()) {
|
||||
int key = iter.nextInt();
|
||||
uploadPixels(BitUtil.toFirstShort(key) * 16, BitUtil.toSecondShort(key) * 16);
|
||||
uploadPixels(BitUtil.shortKey(key) * 16, BitUtil.shortValue(key) * 16);
|
||||
}
|
||||
GLStateTracker.instance().unpack_row_length.setDefault();
|
||||
GLStateTracker.instance().unpack_skip_pixel.setDefault();
|
||||
|
|
|
@ -171,8 +171,8 @@ public class DynamicTexture extends AbstractTexture implements IDynamicTexture
|
|||
{
|
||||
Entry<IntSet> values = iter.next();
|
||||
int key = values.getIntKey();
|
||||
int chunkX = BitUtil.toFirstShort(key) * 16;
|
||||
int chunkZ = BitUtil.toSecondShort(key) * 16;
|
||||
int chunkX = BitUtil.shortKey(key) * 16;
|
||||
int chunkZ = BitUtil.shortValue(key) * 16;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
for(IntIterator subIt = values.getValue().iterator();subIt.hasNext();)
|
||||
|
|
Loading…
Reference in New Issue