entity raycasting

This commit is contained in:
Bixilon 2021-07-08 00:02:32 +02:00
parent 9a70922138
commit f81e6e116a
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
4 changed files with 60 additions and 12 deletions

View File

@ -27,6 +27,9 @@ import glm_.vec3.Vec3t
class VoxelShape(private val aabbs: MutableList<AABB> = mutableListOf()) : Iterable<AABB> {
constructor(vararg aabbs: AABB) : this(aabbs.toMutableList())
constructor(data: Any, aabbs: List<AABB>) : this() {
when (data) {
is JsonArray -> {

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.input
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.player.Hands
import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.gui.rendering.RenderConstants
@ -50,8 +51,25 @@ class RightClickHandler(
if (raycastHit.distance > RenderConstants.MAX_BLOCK_OUTLINE_RAYCAST_DISTANCE) {
return
}
fun sendInteractionPacket() {
connection.sendPacket(BlockPlaceC2SP(
position = raycastHit.blockPosition,
direction = raycastHit.hitDirection,
cursorPosition = Vec3(raycastHit.hitPosition),
item = connection.player.inventory.getHotbarSlot(),
hand = Hands.MAIN_HAND,
insideBlock = false, // ToDo
))
}
val itemInHand = connection.player.inventory.getHotbarSlot()
if (connection.player.gamemode == Gamemodes.SPECTATOR) {
sendInteractionPacket()
return
}
val usage = if (connection.player.isSneaking) {
BlockUsages.PASS
} else {
@ -70,14 +88,7 @@ class RightClickHandler(
if (usage == BlockUsages.SUCCESS) {
connection.sendPacket(ArmSwingC2SP(Hands.MAIN_HAND))
}
connection.sendPacket(BlockPlaceC2SP(
position = raycastHit.blockPosition,
direction = raycastHit.hitDirection,
cursorPosition = Vec3(raycastHit.hitPosition),
item = connection.player.inventory.getHotbarSlot(),
hand = Hands.MAIN_HAND,
insideBlock = false, // ToDo
))
sendInteractionPacket()
}
BlockUsages.PASS -> {
// use item or place block

View File

@ -17,6 +17,7 @@ import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.player.LocalPlayerEntity
import de.bixilon.minosoft.data.registries.VoxelShape
import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.gui.rendering.RenderConstants
@ -37,6 +38,7 @@ import de.bixilon.minosoft.modding.event.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.packets.c2s.play.BlockBreakC2SP
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.decide
import de.bixilon.minosoft.util.Previous
import glm_.func.cos
import glm_.func.rad
@ -277,9 +279,30 @@ class Camera(
entityTarget = raycast(eyePosition, cameraFront, blocks = false, fluids = false, entities = true) as EntityRaycastHit?
}
private fun raycastEntity(origin: Vec3d, direction: Vec3d): EntityRaycastHit? {
var currentHit: EntityRaycastHit? = null
for (entity in connection.world.entities) {
if (entity is LocalPlayerEntity) {
continue
}
val hit = VoxelShape(entity.cameraAABB).raycast(origin, direction)
if (!hit.hit) {
continue
}
if ((currentHit?.distance ?: Double.MAX_VALUE) < hit.distance) {
continue
}
currentHit = EntityRaycastHit(origin + direction * hit.distance, hit.distance, hit.direction, entity)
}
return currentHit
}
private fun raycast(origin: Vec3d, direction: Vec3d, blocks: Boolean, fluids: Boolean, entities: Boolean): RaycastHit? {
if (!blocks && !fluids && entities) {
return null // ToDo: Raycast entities
// only raycast entities
return raycastEntity(origin, direction)
}
val currentPosition = Vec3d(origin)
@ -287,6 +310,7 @@ class Camera(
return (origin - currentPosition).length()
}
var hit: RaycastHit? = null
for (i in 0..RAYCAST_MAX_STEPS) {
val blockPosition = currentPosition.floor
val blockState = connection.world[blockPosition]
@ -305,7 +329,7 @@ class Camera(
if (!fluids) {
continue
}
return FluidRaycastHit(
hit = FluidRaycastHit(
currentPosition,
distance,
voxelShapeRaycastResult.direction,
@ -313,23 +337,32 @@ class Camera(
blockPosition,
blockState.block.fluid,
)
break
}
if (!blocks) {
continue
}
return BlockRaycastHit(
hit = BlockRaycastHit(
currentPosition,
distance,
voxelShapeRaycastResult.direction,
blockState,
blockPosition,
)
break
} else {
currentPosition += direction * (VecUtil.getDistanceToNextIntegerAxisInDirection(currentPosition, direction) + 0.001)
}
}
return null
if (entities) {
val entityRaycastHit = raycastEntity(origin, direction) ?: return hit
hit ?: return null
return (entityRaycastHit.distance < hit.distance).decide(entityRaycastHit, hit)
}
return hit
}
companion object {

View File

@ -48,4 +48,5 @@ class Previous<T>(value: T, private val interpolator: ((previous: Previous<T>, d
fun interpolate(): T {
return interpolator!!(this, (System.currentTimeMillis() - lastChangeTime))
}
}