use of org.terasology.math.geom.Vector3f in project Terasology by MovingBlocks.
the class KinematicCharacterMover method move.
private MoveResult move(final Vector3f startPosition, final Vector3f moveDelta, final float stepHeight, final float slopeFactor, final CharacterCollider collider) {
steppedUpDist = 0;
stepped = false;
Vector3f position = new Vector3f(startPosition);
boolean hitTop = false;
boolean hitBottom = false;
boolean hitSide;
// Actual upwards movement
if (moveDelta.y > 0) {
hitTop = moveDelta.y - moveUp(moveDelta.y, collider, position) > physics.getEpsilon();
}
hitSide = moveHorizontal(new Vector3f(moveDelta.x, 0, moveDelta.z), collider, position, slopeFactor, stepHeight);
if (moveDelta.y < 0 || steppedUpDist > 0) {
float dist = (moveDelta.y < 0) ? moveDelta.y : 0;
dist -= steppedUpDist;
hitBottom = moveDown(dist, slopeFactor, collider, position);
}
if (!hitBottom && stepHeight > 0) {
Vector3f tempPos = new Vector3f(position);
hitBottom = moveDown(-stepHeight, slopeFactor, collider, tempPos);
// Don't apply step down if nothing to step onto
if (hitBottom) {
position.set(tempPos);
}
}
return new MoveResult(position, hitSide, hitBottom, hitTop);
}
use of org.terasology.math.geom.Vector3f in project Terasology by MovingBlocks.
the class KinematicCharacterMover method checkMode.
/**
* Checks whether a character should change movement mode (from being underwater or in a ladder). A higher and lower point of the
* character is tested for being in water, only if both points are in water does the character count as swimming.
* <br><br>
* Sends the OnEnterLiquidEvent and OnLeaveLiquidEvent events.
*
* @param movementComp The movement component of the character.
* @param state The current state of the character.
*/
private void checkMode(final CharacterMovementComponent movementComp, final CharacterStateEvent state, final CharacterStateEvent oldState, EntityRef entity, boolean firstRun, boolean isCrouching) {
// If we are ghosting or we can't move, the mode cannot be changed.
if (!state.getMode().respondToEnvironment) {
return;
}
Vector3f worldPos = state.getPosition();
Vector3f top = new Vector3f(worldPos);
Vector3f bottom = new Vector3f(worldPos);
top.y += 0.5f * movementComp.height;
bottom.y -= 0.5f * movementComp.height;
final boolean topUnderwater = worldProvider.getBlock(top).isLiquid();
final boolean bottomUnderwater = worldProvider.getBlock(bottom).isLiquid();
final boolean newSwimming = !topUnderwater && bottomUnderwater;
final boolean newDiving = topUnderwater && bottomUnderwater;
boolean newClimbing = false;
if (isClimbingAllowed(newSwimming, newDiving)) {
Vector3i finalDir;
finalDir = findClimbable(movementComp, worldPos, newSwimming, newDiving);
if (finalDir != null) {
newClimbing = true;
state.setClimbDirection(finalDir);
}
}
updateMode(state, newSwimming, newDiving, newClimbing, isCrouching);
}
use of org.terasology.math.geom.Vector3f in project Terasology by MovingBlocks.
the class KinematicCharacterMover method climb.
private void climb(final CharacterStateEvent state, CharacterMoveInputEvent input, Vector3f desiredVelocity) {
if (state.getClimbDirection() == null) {
return;
}
Vector3f tmp;
Vector3i climbDir3i = state.getClimbDirection();
Vector3f climbDir3f = climbDir3i.toVector3f();
Quat4f rotation = new Quat4f(TeraMath.DEG_TO_RAD * state.getYaw(), 0, 0);
tmp = new Vector3f(0.0f, 0.0f, -1.0f);
rotation.rotate(tmp, tmp);
float angleToClimbDirection = tmp.angle(climbDir3f);
boolean clearMovementToDirection = !state.isGrounded();
boolean jumpOrCrouchActive = desiredVelocity.y != 0;
// facing the ladder or looking down or up
if (angleToClimbDirection < Math.PI / 4.0 || Math.abs(input.getPitch()) > 60f) {
if (jumpOrCrouchActive) {
desiredVelocity.x = 0;
desiredVelocity.z = 0;
clearMovementToDirection = false;
} else {
float pitchAmount = state.isGrounded() ? 45f : 90f;
float pitch = input.getPitch() > 30f ? pitchAmount : -pitchAmount;
rotation = new Quat4f(TeraMath.DEG_TO_RAD * state.getYaw(), TeraMath.DEG_TO_RAD * pitch, 0);
rotation.rotate(desiredVelocity, desiredVelocity);
}
// looking sidewards from ladder
} else if (angleToClimbDirection < Math.PI * 3.0 / 4.0) {
float rollAmount = state.isGrounded() ? 45f : 90f;
tmp = new Vector3f();
rotation.rotate(climbDir3f, tmp);
float leftOrRight = tmp.x;
float plusOrMinus = (leftOrRight < 0f ? -1.0f : 1.0f) * (climbDir3i.x != 0 ? -1.0f : 1.0f);
if (jumpOrCrouchActive) {
rotation = new Quat4f(TeraMath.DEG_TO_RAD * state.getYaw(), 0, 0);
} else {
rotation = new Quat4f(TeraMath.DEG_TO_RAD * input.getYaw(), 0f, TeraMath.DEG_TO_RAD * rollAmount * plusOrMinus);
}
rotation.rotate(desiredVelocity, desiredVelocity);
// facing away from ladder
} else {
rotation = new Quat4f(TeraMath.DEG_TO_RAD * state.getYaw(), 0, 0);
rotation.rotate(desiredVelocity, desiredVelocity);
clearMovementToDirection = false;
}
// clear out movement towards or away from the ladder
if (clearMovementToDirection) {
if (climbDir3i.x != 0) {
desiredVelocity.x = 0f;
}
if (climbDir3i.z != 0) {
desiredVelocity.z = 0f;
}
}
}
use of org.terasology.math.geom.Vector3f in project Terasology by MovingBlocks.
the class ServerCharacterPredictionSystem method onTeleport.
@ReceiveEvent(components = { CharacterMovementComponent.class, LocationComponent.class, AliveCharacterComponent.class })
public void onTeleport(CharacterTeleportEvent event, EntityRef entity) {
CircularBuffer<CharacterStateEvent> stateBuffer = characterStates.get(entity);
CharacterStateEvent lastState = stateBuffer.getLast();
CharacterStateEvent newState = new CharacterStateEvent(lastState);
newState.setPosition(new Vector3f(event.getTargetPosition()));
newState.setTime(time.getGameTimeInMs());
stateBuffer.add(newState);
characterMovementSystemUtility.setToState(entity, newState);
}
use of org.terasology.math.geom.Vector3f in project Terasology by MovingBlocks.
the class CoreCommands method spawnBlock.
/**
* Spawns a block in front of the player
* @param sender Sender of command
* @param blockName String containing name of block to spawn
* @return String containg final message
*/
@Command(shortDescription = "Spawns a block in front of the player", helpText = "Spawns the specified block as a " + "item in front of the player. You can simply pick it up.", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION)
public String spawnBlock(@Sender EntityRef sender, @CommandParam("blockName") String blockName) {
ClientComponent clientComponent = sender.getComponent(ClientComponent.class);
LocationComponent characterLocation = clientComponent.character.getComponent(LocationComponent.class);
Vector3f spawnPos = characterLocation.getWorldPosition();
Vector3f offset = characterLocation.getWorldDirection();
offset.scale(3);
spawnPos.add(offset);
BlockFamily block = blockManager.getBlockFamily(blockName);
if (block == null) {
return "";
}
BlockItemFactory blockItemFactory = new BlockItemFactory(entityManager);
EntityRef blockItem = blockItemFactory.newInstance(block);
blockItem.send(new DropItemEvent(spawnPos));
return "Spawned block.";
}
Aggregations