Skip to content

Commit 9efdf9b

Browse files
committed
refactor: rework grabbed bodies, add trigger interaction, add touch keymapping, minor changes
1 parent 34fecb2 commit 9efdf9b

11 files changed

Lines changed: 118 additions & 36 deletions

File tree

‎common/src/main/java/net/timtaran/interactivemc/body/player/PlayerBodyManager.java‎

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
import net.minecraft.world.entity.player.Player;
1919
import net.minecraft.world.level.Level;
2020
import net.timtaran.interactivemc.body.player.interaction.GrabInteraction;
21+
import net.timtaran.interactivemc.body.player.interaction.TriggerInteraction;
2122
import net.timtaran.interactivemc.body.player.interaction.TriggerState;
2223
import net.timtaran.interactivemc.body.player.packet.S2CGrabResultPacket;
2324
import net.timtaran.interactivemc.body.player.physics.PlayerBodyPartGhostRigidBody;
2425
import net.timtaran.interactivemc.body.player.physics.PlayerBodyPartRigidBody;
2526
import net.timtaran.interactivemc.body.player.store.PlayerBodyDataStore;
26-
import net.timtaran.interactivemc.body.type.IGrabbable;
2727
import net.timtaran.interactivemc.init.InteractiveMC;
2828
import net.timtaran.interactivemc.init.registry.BodyRegistry;
2929
import net.timtaran.interactivemc.network.Networking;
@@ -58,10 +58,12 @@ public class PlayerBodyManager {
5858

5959
private final VxPhysicsWorld world;
6060
private final GrabInteraction grabInteraction;
61+
private final TriggerInteraction triggerInteraction;
6162

6263
private PlayerBodyManager(VxPhysicsWorld world) {
6364
this.world = world;
6465
this.grabInteraction = new GrabInteraction(world, this);
66+
this.triggerInteraction = new TriggerInteraction();
6567
ContactListenerManager.init(world); // todo delete this
6668
}
6769

@@ -331,39 +333,46 @@ public void release(Player player, InteractionHand interactionHand) {
331333

332334
VxBody grabbedBody = world.getBodyManager().getVxBody(playerBodyPartData.grabbedBodyId());
333335
if (grabbedBody != null) {
334-
PlayerBodyDataStore.grabbedBodies.remove(grabbedBody.getBodyId());
336+
// remove only first found body because multiple bodies can grab single body
337+
PlayerBodyDataStore.grabbedBodies.rem(grabbedBody.getBodyId());
335338
}
336339

337340
playerBodies.put(playerBodyPart, new PlayerBodyPartData(playerBodyPartData.bodyPartId(), playerBodyPartData.ghostBodyPartId(), playerBodyPartData.triggerState(), null, null));
341+
if (player instanceof ServerPlayer serverPlayer) {
342+
player.getServer().execute(() ->
343+
Networking.sendToPlayer(
344+
serverPlayer,
345+
new S2CGrabResultPacket(
346+
interactionHand,
347+
null
348+
)
349+
)
350+
);
351+
}
338352
System.out.println("released body");
339353
}
340354

341355
public void updateTriggerState(Player player, InteractionHand interactionHand, TriggerState triggerState) {
342356
PlayerBodyPart playerBodyPart = PlayerBodyPart.fromInteractionHand(interactionHand);
343-
System.out.println("release playerbodypart: " + playerBodyPart);
344357
if (playerBodyPart == null)
345358
return;
346359

347360
EnumMap<PlayerBodyPart, PlayerBodyPartData> playerBodies = PlayerBodyDataStore.playersBodies.get(player.getUUID());
348-
System.out.println("release playerbodies: " + playerBodies);
349361
if (playerBodies == null)
350362
return;
351363

352364
PlayerBodyPartData playerBodyPartData = playerBodies.get(playerBodyPart);
353-
System.out.println("release playerbodypartdata: " + playerBodyPartData);
354365
if (playerBodyPartData == null) {
355366
return;
356367
}
357368

358-
if (playerBodyPartData.grabbedBodyId() == null) {
369+
if (playerBodyPartData.grabbedBodyId() == null || playerBodyPartData.grabConstraintId() == null) {
359370
return;
360371
}
361372

362373
VxBody grabbedBody = world.getBodyManager().getVxBody(playerBodyPartData.grabbedBodyId());
363374

364-
if (grabbedBody instanceof IGrabbable grabbable) {
365-
grabbable.onTriggerStateUpdate(player, playerBodyPart, triggerState);
366-
}
375+
triggerInteraction.updateGrabState(player, grabbedBody, playerBodyPart, triggerState);
367376
}
368377

369378
public void processGrabResult(Player player, PlayerBodyPart playerBodyPart, GrabInteraction.GrabResult grabResult) {
@@ -376,18 +385,15 @@ public void processGrabResult(Player player, PlayerBodyPart playerBodyPart, Grab
376385
if (playerBodyPartData == null) {
377386
return;
378387
}
388+
System.out.println(playerBodyPartData);
379389

380390
playerBodies.put(playerBodyPart, new PlayerBodyPartData(
381391
playerBodyPartData.bodyPartId(), playerBodyPartData.ghostBodyPartId(), playerBodyPartData.triggerState(),
382392
grabResult.grabbedBody() != null ? grabResult.grabbedBody().getPhysicsId() : null,
383393
grabResult.grabConstraint() != null ? grabResult.grabConstraint().getConstraintId() : null
384394
));
385395

386-
387396
if (grabResult.grabbedBody() != null) {
388-
if (PlayerBodyDataStore.grabbedBodies.contains(grabResult.grabbedBody().getBodyId()))
389-
return;
390-
391397
PlayerBodyDataStore.grabbedBodies.add(grabResult.grabbedBody().getBodyId());
392398
}
393399

@@ -401,8 +407,7 @@ public void processGrabResult(Player player, PlayerBodyPart playerBodyPart, Grab
401407
serverPlayer,
402408
new S2CGrabResultPacket(
403409
interactionHand,
404-
grabResult.grabbedBody() == null ? UUID.randomUUID() : grabResult.grabbedBody().getPhysicsId()
405-
// todo: replace (I forgot with what, but random uuid is used here because passing null values causes NPE)
410+
grabResult.grabbedBody() == null ? null : grabResult.grabbedBody().getPhysicsId()
406411
)
407412
)
408413
);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,26 @@
1+
/*
2+
* This file is part of InteractiveMC.
3+
* Licensed under LGPL 3.0.
4+
*/
15
package net.timtaran.interactivemc.body.player.interaction;
26

7+
import net.minecraft.world.entity.player.Player;
8+
import net.timtaran.interactivemc.body.player.PlayerBodyPart;
9+
import net.timtaran.interactivemc.body.type.IGrabbable;
10+
import net.xmx.velthoric.core.body.VxBody;
11+
12+
/**
13+
* Handles the logic for trigger interactions.
14+
*
15+
* @author timtaran
16+
*/
317
public class TriggerInteraction {
18+
public TriggerInteraction() {
19+
}
20+
21+
public void updateGrabState(Player player, VxBody grabbedBody, PlayerBodyPart playerBodyPart, TriggerState triggerState) {
22+
if (grabbedBody instanceof IGrabbable grabbable) {
23+
grabbable.onTriggerStateUpdate(player, playerBodyPart, triggerState);
24+
}
25+
}
426
}

‎common/src/main/java/net/timtaran/interactivemc/body/player/packet/S2CGrabResultPacket.java‎

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import net.minecraft.world.InteractionHand;
99
import net.timtaran.interactivemc.body.player.store.ClientPlayerBodyDataStore;
1010
import net.xmx.velthoric.network.VxByteBuf;
11+
import org.jetbrains.annotations.Nullable;
1112

1213
import java.util.UUID;
1314

@@ -20,8 +21,15 @@
2021
* @author timtaran
2122
*/
2223
public class S2CGrabResultPacket extends HandInteractionPacket {
24+
private static final UUID NULL_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
25+
26+
/**
27+
* Whether the grab was successful or not.
28+
*/
29+
private final boolean isBodyPresent;
30+
2331
/**
24-
* The UUID of the grabbed body, or null if the grab was unsuccessful.
32+
* The UUID of the grabbed body.
2533
*/
2634
private final UUID grabbedBodyUUID;
2735

@@ -31,9 +39,17 @@ public class S2CGrabResultPacket extends HandInteractionPacket {
3139
* @param interactionHand the hand that performed the grab
3240
* @param grabbedBodyUUID the UUID of the grabbed body, or null if grab failed
3341
*/
34-
public S2CGrabResultPacket(InteractionHand interactionHand, UUID grabbedBodyUUID) {
42+
public S2CGrabResultPacket(InteractionHand interactionHand, @Nullable UUID grabbedBodyUUID) {
3543
super(interactionHand);
36-
this.grabbedBodyUUID = grabbedBodyUUID;
44+
45+
if (grabbedBodyUUID == null) {
46+
isBodyPresent = false;
47+
this.grabbedBodyUUID = NULL_UUID;
48+
}
49+
else {
50+
isBodyPresent = true;
51+
this.grabbedBodyUUID = grabbedBodyUUID;
52+
}
3753
}
3854

3955
/**
@@ -43,7 +59,14 @@ public S2CGrabResultPacket(InteractionHand interactionHand, UUID grabbedBodyUUID
4359
* @return a new instance of the grab result packet
4460
*/
4561
public static S2CGrabResultPacket decode(VxByteBuf buf) {
46-
return new S2CGrabResultPacket(buf.readEnum(InteractionHand.class), buf.readUUID());
62+
InteractionHand interactionHand = buf.readEnum(InteractionHand.class);
63+
64+
boolean isBodyPresent = buf.readBoolean();
65+
66+
if (isBodyPresent)
67+
return new S2CGrabResultPacket(interactionHand, buf.readUUID());
68+
else
69+
return new S2CGrabResultPacket(interactionHand, null);
4770
}
4871

4972
/**
@@ -54,7 +77,20 @@ public static S2CGrabResultPacket decode(VxByteBuf buf) {
5477
@Override
5578
public void encode(VxByteBuf buf) {
5679
super.encode(buf);
57-
buf.writeUUID(grabbedBodyUUID);
80+
81+
buf.writeBoolean(isBodyPresent);
82+
83+
if (isBodyPresent)
84+
buf.writeUUID(grabbedBodyUUID);
85+
}
86+
87+
88+
@Nullable
89+
public UUID getGrabbedBodyUUID() {
90+
if (isBodyPresent)
91+
return grabbedBodyUUID;
92+
else
93+
return null;
5894
}
5995

6096
/**
@@ -67,6 +103,6 @@ public void encode(VxByteBuf buf) {
67103
*/
68104
@Override
69105
public void handle(NetworkManager.PacketContext context) {
70-
ClientPlayerBodyDataStore.grabbedBodies.put(getInteractionHand(), grabbedBodyUUID);
106+
ClientPlayerBodyDataStore.grabbedBodies.put(getInteractionHand(), getGrabbedBodyUUID());
71107
}
72108
}

‎common/src/main/java/net/timtaran/interactivemc/body/player/store/ClientPlayerBodyDataStore.java‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ public final class ClientPlayerBodyDataStore {
2626
/**
2727
* Maps from {@link InteractionHand} to the UUID of the grabbed body.
2828
*/
29-
public static EnumMap<InteractionHand, UUID> grabbedBodies = new EnumMap<>(Map.of(
30-
InteractionHand.MAIN_HAND, UUID.randomUUID(),
31-
InteractionHand.OFF_HAND, UUID.randomUUID()
32-
));
29+
public static EnumMap<InteractionHand, UUID> grabbedBodies = new EnumMap<>(InteractionHand.class);
3330

3431
public static EnumMap<InteractionHand, TriggerState> triggerStates = new EnumMap<>(Map.of(
3532
InteractionHand.MAIN_HAND, TriggerState.RELEASE,

‎common/src/main/java/net/timtaran/interactivemc/body/player/store/PlayerBodyDataStore.java‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
*/
55
package net.timtaran.interactivemc.body.player.store;
66

7-
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
8-
import it.unimi.dsi.fastutil.ints.IntSet;
7+
import it.unimi.dsi.fastutil.ints.IntArrayList;
8+
import it.unimi.dsi.fastutil.ints.IntList;
99
import net.timtaran.interactivemc.body.player.PlayerBodyPart;
1010
import net.timtaran.interactivemc.body.player.PlayerBodyPartData;
1111
import org.vivecraft.api.data.VRPose;
@@ -42,7 +42,7 @@ public class PlayerBodyDataStore {
4242
/**
4343
* Contains the Jolt body IDs of all grabbed player bodies for quick lookup during interactions.
4444
*/
45-
public static final IntSet grabbedBodies = new IntOpenHashSet(); // read/write in physics thread
45+
public static final IntList grabbedBodies = new IntArrayList(); // read/write in physics thread
4646

4747
/**
4848
* The VR poses of the players by UUID.

‎common/src/main/java/net/timtaran/interactivemc/init/registry/KeyMapRegistry.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ public class KeyMapRegistry {
3030
KeyMapping.CATEGORY_GAMEPLAY
3131
);
3232

33+
public static final KeyMapping MAIN_TRIGGER_TOUCH_KEYMAPPING = new KeyMapping(
34+
InteractiveMCIdentifier.getTranslationKey("key", "mtouch"),
35+
-1,
36+
KeyMapping.CATEGORY_GAMEPLAY
37+
);
38+
3339
/**
3440
* Main-Hand Grab
3541
*/
@@ -48,6 +54,12 @@ public class KeyMapRegistry {
4854
KeyMapping.CATEGORY_GAMEPLAY
4955
);
5056

57+
public static final KeyMapping OFF_TRIGGER_TOUCH_KEYMAPPING = new KeyMapping(
58+
InteractiveMCIdentifier.getTranslationKey("key", "otouch"),
59+
-1,
60+
KeyMapping.CATEGORY_GAMEPLAY
61+
);
62+
5163
/**
5264
* Off-Hand Grab
5365
*/

‎common/src/main/java/net/timtaran/interactivemc/mixin/bridge/vivecraft/KeyMappingHandlingMixin.java‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public class KeyMappingHandlingMixin {
4848
private void interactivemc$processKeymappings(CallbackInfo ci) {
4949
interactivemc$updateGrabState(InteractionHand.MAIN_HAND, KeyMapRegistry.MAIN_GRAB_KEYMAPPING);
5050
interactivemc$updateGrabState(InteractionHand.OFF_HAND, KeyMapRegistry.OFF_GRAB_KEYMAPPING);
51+
interactivemc$updateTriggerState(InteractionHand.MAIN_HAND, KeyMapRegistry.MAIN_TRIGGER_TOUCH_KEYMAPPING, KeyMapRegistry.MAIN_TRIGGER_KEYMAPPING);
52+
interactivemc$updateTriggerState(InteractionHand.OFF_HAND, KeyMapRegistry.OFF_TRIGGER_TOUCH_KEYMAPPING, KeyMapRegistry.OFF_TRIGGER_KEYMAPPING);
5153
}
5254

5355
/**
@@ -65,8 +67,8 @@ public class KeyMappingHandlingMixin {
6567
if (keyMapping.consumeClick()) {
6668
interactivemc$grab(hand);
6769
} else if (!keyMapping.isDown() && ClientPlayerBodyDataStore.grabbedBodies.get(hand) != null) {
70+
System.out.println("client release");
6871
interactivemc$release(hand);
69-
ClientPlayerBodyDataStore.grabbedBodies.remove(hand); // todo replace with waiting for server response
7072
}
7173
}
7274

@@ -80,7 +82,7 @@ public class KeyMappingHandlingMixin {
8082
@Unique
8183
private static boolean interactivemc$grab(InteractionHand interactionHand) {
8284
boolean isGrabbing = GrabInteraction.canGrabClient(interactionHand);
83-
System.out.println(isGrabbing);
85+
System.out.println("isGrabbing:" + isGrabbing);
8486

8587
Networking.sendToServer(new C2SGrabPacket(interactionHand));
8688
return isGrabbing;
@@ -102,7 +104,7 @@ public class KeyMappingHandlingMixin {
102104

103105
if (pressKeyMapping.consumeClick() || pressKeyMapping.isDown()) {
104106
triggerState = TriggerState.PRESS;
105-
} else if (touchKeyMapping.consumeClick() || pressKeyMapping.isDown()) {
107+
} else if (touchKeyMapping.consumeClick() || touchKeyMapping.isDown()) {
106108
triggerState = TriggerState.TOUCH;
107109
} else {
108110
triggerState = TriggerState.RELEASE;

‎common/src/main/java/net/timtaran/interactivemc/mixin/bridge/vivecraft/KeyMappingRegisterMixin.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ public class KeyMappingRegisterMixin {
4949
)
5050
public void interactivemc$registerKeymappings(CallbackInfo ci) {
5151
hiddenKeyBindingSet.add(KeyMapRegistry.MAIN_TRIGGER_KEYMAPPING);
52+
hiddenKeyBindingSet.add(KeyMapRegistry.MAIN_TRIGGER_TOUCH_KEYMAPPING);
5253
hiddenKeyBindingSet.add(KeyMapRegistry.OFF_TRIGGER_KEYMAPPING);
54+
hiddenKeyBindingSet.add(KeyMapRegistry.OFF_TRIGGER_TOUCH_KEYMAPPING);
5355
hiddenKeyBindingSet.add(KeyMapRegistry.MAIN_GRAB_KEYMAPPING);
5456
hiddenKeyBindingSet.add(KeyMapRegistry.OFF_GRAB_KEYMAPPING);
5557
}

‎common/src/main/java/net/timtaran/interactivemc/network/PacketRegistry.java‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@
99
package net.timtaran.interactivemc.network;
1010

1111
import dev.architectury.networking.NetworkManager;
12-
import net.timtaran.interactivemc.body.player.packet.C2SFrameVRPosePacket;
13-
import net.timtaran.interactivemc.body.player.packet.C2SGrabPacket;
14-
import net.timtaran.interactivemc.body.player.packet.C2SReleasePacket;
15-
import net.timtaran.interactivemc.body.player.packet.S2CGrabResultPacket;
12+
import net.timtaran.interactivemc.body.player.packet.*;
1613
import net.xmx.velthoric.network.IVxNetPacket;
1714
import net.xmx.velthoric.network.VxByteBuf;
1815

@@ -65,6 +62,11 @@ public static void registerPackets() {
6562
C2SReleasePacket::decode
6663
);
6764

65+
registerC2S(
66+
C2STriggerStatePacket.class,
67+
C2STriggerStatePacket::decode
68+
);
69+
6870
// --- Server to Client Packets (S2C) ---
6971
// These packets are sent by the server and handled on the client.
7072

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{
22
"category.interactivemc.vrbindings": "InteractiveMC — VR Bindings",
3-
"key.interactivemc.mtrigger": "Main-Hand Grab",
3+
"key.interactivemc.mtrigger": "Main-Hand Trigger",
4+
"key.interactivemc.mtouch": "Main-Hand Trigger Touch",
45
"key.interactivemc.otrigger": "Off-Hand Trigger",
6+
"key.interactivemc.otouch": "Off-Hand Trigger Touch",
57
"key.interactivemc.mgrab": "Main-Hand Grab",
68
"key.interactivemc.ograb": "Off-Hand Grab"
79
}

0 commit comments

Comments
 (0)