mirror of
https://github.com/Minestom/Minestom.git
synced 2024-09-27 14:13:24 +02:00
Use eye height difference when setting direction using Entity#lookAt(Entity) (#900)
This commit is contained in:
parent
73fed47040
commit
97abccce0c
@ -329,11 +329,16 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the view of the entity so that it looks in a direction to the given position.
|
||||
* Changes the view of the entity so that it looks in a direction to the given position if
|
||||
* it is different from the entity's current position.
|
||||
*
|
||||
* @param position the position to look at.
|
||||
*/
|
||||
public void lookAt(@NotNull Pos position) {
|
||||
if (this.position.samePoint(position)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vec delta = position.sub(getPosition()).asVec().normalize();
|
||||
setView(
|
||||
PositionUtils.getLookYaw(delta.x(), delta.z()),
|
||||
@ -348,7 +353,8 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
||||
*/
|
||||
public void lookAt(@NotNull Entity entity) {
|
||||
Check.argCondition(entity.instance != instance, "Entity can look at another entity that is within it's own instance");
|
||||
lookAt(entity.position);
|
||||
double eyeHeightDifference = entity.getEyeHeight() - getEyeHeight();
|
||||
lookAt(entity.position.withY(entity.position.y() + eyeHeightDifference));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,169 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.api.Env;
|
||||
import net.minestom.server.api.EnvTest;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@EnvTest
|
||||
public class EntityViewDirectionIntegrationTest {
|
||||
private static final float EPSILON = 0.01f;
|
||||
|
||||
@Test
|
||||
public void viewYawAndPitch(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var entity = new Entity(EntityType.ZOMBIE);
|
||||
entity.setInstance(instance, new Pos(0, 40, 0)).join();
|
||||
entity.setView(0, 0);
|
||||
assertEquals(0, entity.getPosition().yaw());
|
||||
assertEquals(0, entity.getPosition().pitch());
|
||||
|
||||
entity.setView(90, 0);
|
||||
assertEquals(90, entity.getPosition().yaw());
|
||||
assertEquals(0, entity.getPosition().pitch());
|
||||
|
||||
entity.setView(0, 42);
|
||||
assertEquals(0, entity.getPosition().yaw());
|
||||
assertEquals(42, entity.getPosition().pitch());
|
||||
|
||||
entity.setView(37, 26);
|
||||
assertEquals(37, entity.getPosition().yaw());
|
||||
assertEquals(26, entity.getPosition().pitch());
|
||||
|
||||
// check for NaN values
|
||||
entity.setView(Float.NaN, 0);
|
||||
assertTrue(Float.isNaN(entity.getPosition().yaw()));
|
||||
assertEquals(0, entity.getPosition().pitch());
|
||||
|
||||
entity.setView(0, Float.NaN);
|
||||
assertEquals(0, entity.getPosition().yaw());
|
||||
assertTrue(Float.isNaN(entity.getPosition().pitch()));
|
||||
|
||||
entity.setView(Float.NaN, Float.NaN);
|
||||
assertTrue(Float.isNaN(entity.getPosition().yaw()));
|
||||
assertTrue(Float.isNaN(entity.getPosition().pitch()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookAtPos(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var entity = new Entity(EntityType.ZOMBIE);
|
||||
entity.setInstance(instance, new Pos(0, 40, 0)).join();
|
||||
|
||||
// look at itself, direction should not change
|
||||
float prevYaw = entity.getPosition().yaw();
|
||||
float prevPitch = entity.getPosition().pitch();
|
||||
entity.lookAt(entity.getPosition());
|
||||
assertEquals(prevYaw, entity.getPosition().yaw());
|
||||
assertEquals(prevPitch, entity.getPosition().pitch());
|
||||
|
||||
entity.lookAt(new Pos(16, 40, 16));
|
||||
assertEquals(-45f, entity.getPosition().yaw());
|
||||
assertEquals(0f, entity.getPosition().pitch(), EPSILON);
|
||||
|
||||
entity.lookAt(new Pos(-16, 40, 56));
|
||||
assertEquals(15.94f, entity.getPosition().yaw(), EPSILON);
|
||||
assertEquals(0f, entity.getPosition().pitch(), EPSILON);
|
||||
|
||||
entity.lookAt(new Pos(48, 36, 48));
|
||||
assertEquals(-45f, entity.getPosition().yaw(), EPSILON);
|
||||
assertEquals(4.76f, entity.getPosition().pitch(), EPSILON);
|
||||
|
||||
entity.lookAt(new Pos(48, 36, -17));
|
||||
assertEquals(-109.50f, entity.getPosition().yaw(), EPSILON);
|
||||
// should have the same pitch as the previous position
|
||||
assertEquals(4.76f, entity.getPosition().pitch(), EPSILON);
|
||||
|
||||
entity.lookAt(new Pos(0, 87, 0));
|
||||
// looking from below, not checking the yaw
|
||||
assertEquals(-90f, entity.getPosition().pitch(), EPSILON);
|
||||
|
||||
entity.lookAt(new Pos(-25, 42, 4));
|
||||
assertEquals(80.90f, entity.getPosition().yaw(), EPSILON);
|
||||
assertEquals(-4.57f, entity.getPosition().pitch(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookAtEntitySameType(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
// same type, same eye height
|
||||
var e1 = new Entity(EntityType.ZOMBIE);
|
||||
var e2 = new Entity(EntityType.ZOMBIE);
|
||||
e1.setInstance(instance, new Pos(0, 40, 0)).join();
|
||||
e2.setInstance(instance, new Pos(0, 40, 0)).join();
|
||||
|
||||
// look at an entity with the same eye height and same position,
|
||||
// direction should not change
|
||||
float prevYaw = e1.getPosition().yaw();
|
||||
float prevPitch = e1.getPosition().pitch();
|
||||
e1.lookAt(e2);
|
||||
assertEquals(prevYaw, e1.getPosition().yaw());
|
||||
assertEquals(prevPitch, e1.getPosition().pitch());
|
||||
|
||||
e2.teleport(new Pos(0, 50, 0)).join();
|
||||
e1.lookAt(e2);
|
||||
// e2 is above e1, the pich should be negative
|
||||
assertEquals(-90f, e1.getPosition().pitch(), EPSILON);
|
||||
|
||||
e2.teleport(new Pos(0, 10, 0)).join();
|
||||
e1.lookAt(e2);
|
||||
// e2 is below e1, the pich should be positive
|
||||
assertEquals(90f, e1.getPosition().pitch(), EPSILON);
|
||||
|
||||
e2.teleport(new Pos(16, 40, 16)).join();
|
||||
e1.lookAt(e2);
|
||||
assertEquals(-45f, e1.getPosition().yaw(), EPSILON);
|
||||
// e2 has the same y as e1, the pich should be 0
|
||||
assertEquals(0f, e1.getPosition().pitch(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookAtEntityDifferentType(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
// same type, same eye height
|
||||
var e1 = new Entity(EntityType.ZOMBIE);
|
||||
// a chicken has a lower eye height than a zombie
|
||||
var e2 = new Entity(EntityType.CHICKEN);
|
||||
e1.setInstance(instance, new Pos(0, 40, 0)).join();
|
||||
e2.setInstance(instance, new Pos(0, 40, 0)).join();
|
||||
|
||||
e1.lookAt(e2);
|
||||
// e2 eyes are below e1, the pich should be positive
|
||||
assertEquals(90f, e1.getPosition().pitch(), EPSILON);
|
||||
|
||||
double eyeDifference = e1.getEyeHeight() - e2.getEyeHeight();
|
||||
assertTrue(eyeDifference > 0);
|
||||
var pos = new Pos(0, e1.getPosition().y() + eyeDifference, 0);
|
||||
e2.teleport(pos).join();
|
||||
// e2 eyes are in the same position as e1, direction should not change
|
||||
float prevYaw = e1.getPosition().yaw();
|
||||
float prevPitch = e1.getPosition().pitch();
|
||||
e1.lookAt(e2);
|
||||
assertEquals(prevYaw, e1.getPosition().yaw());
|
||||
assertEquals(prevPitch, e1.getPosition().pitch());
|
||||
|
||||
pos = new Pos(10, e1.getPosition().y() + eyeDifference, 10);
|
||||
e2.teleport(pos).join();
|
||||
e1.lookAt(e2);
|
||||
// e2 eyes are at the same height as e1's, the pitch should be 0
|
||||
assertEquals(0f, e1.getPosition().pitch(), EPSILON);
|
||||
|
||||
e2.teleport(new Pos(-16, 40, -16)).join();
|
||||
e1.lookAt(e2);
|
||||
assertEquals(135f, e1.getPosition().yaw(), EPSILON);
|
||||
assertEquals(3.79f, e1.getPosition().pitch(), EPSILON);
|
||||
|
||||
e2.teleport(new Pos(8, 50, -32)).join();
|
||||
e1.lookAt(e2);
|
||||
assertEquals(-165.96f, e1.getPosition().yaw(), EPSILON);
|
||||
assertEquals(-15.60f, e1.getPosition().pitch(), EPSILON);
|
||||
|
||||
e2.teleport(new Pos(0, 30, -2)).join();
|
||||
e1.lookAt(e2);
|
||||
assertEquals(-180f, e1.getPosition().yaw(), EPSILON);
|
||||
assertEquals(79.75f, e1.getPosition().pitch(), EPSILON);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user