Package org.terasology.logic.characters

Source Code of org.terasology.logic.characters.CharacterStateEvent

/*
* Copyright 2013 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.terasology.logic.characters;

import org.terasology.math.Vector3i;
import org.terasology.registry.CoreRegistry;
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.logic.location.LocationComponent;
import org.terasology.network.BroadcastEvent;
import org.terasology.network.NetworkEvent;
import org.terasology.physics.engine.CharacterCollider;
import org.terasology.physics.engine.PhysicsEngine;

import javax.vecmath.Quat4f;
import javax.vecmath.Vector3f;

/**
* @author Immortius
*/
@BroadcastEvent
public class CharacterStateEvent extends NetworkEvent {
    private long time;
    private int sequenceNumber;
    private Vector3f position = new Vector3f();
    private Quat4f rotation = new Quat4f(0, 0, 0, 1);
    private MovementMode mode = MovementMode.WALKING;
    private boolean grounded;
    private Vector3f velocity = new Vector3f();
    private float yaw;
    private float pitch;
    private float footstepDelta;
    private Vector3i climbDirection;

    protected CharacterStateEvent() {
    }

    public CharacterStateEvent(CharacterStateEvent previous) {
        this.time = previous.time;
        this.position.set(previous.position);
        this.rotation.set(previous.rotation);
        this.mode = previous.mode;
        this.grounded = previous.grounded;
        this.velocity.set(previous.velocity);
        this.sequenceNumber = previous.sequenceNumber + 1;
        this.pitch = previous.pitch;
        this.yaw = previous.yaw;
        this.footstepDelta = previous.footstepDelta;
        this.climbDirection = previous.climbDirection;
    }

    public CharacterStateEvent(
            long time,
            int sequenceNumber,
            Vector3f position,
            Quat4f rotation,
            Vector3f velocity,
            float yaw,
            float pitch,
            MovementMode mode,
            boolean grounded) {
        this.time = time;
        this.position.set(position);
        this.rotation.set(rotation);
        this.velocity.set(velocity);
        this.mode = mode;
        this.grounded = grounded;
        this.sequenceNumber = sequenceNumber;
        this.pitch = pitch;
        this.yaw = yaw;
    }

    public long getTime() {
        return time;
    }

    public Vector3f getPosition() {
        return position;
    }

    public Quat4f getRotation() {
        return rotation;
    }

    public MovementMode getMode() {
        return mode;
    }

    public boolean isGrounded() {
        return grounded;
    }

    public Vector3f getVelocity() {
        return velocity;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public void setMode(MovementMode mode) {
        this.mode = mode;
    }

    public void setGrounded(boolean grounded) {
        this.grounded = grounded;
    }

    public int getSequenceNumber() {
        return sequenceNumber;
    }

    public void setSequenceNumber(int sequenceNumber) {
        this.sequenceNumber = sequenceNumber;
    }

    public void setClimbDirection(Vector3i climbDirection) {
        this.climbDirection = climbDirection;
    }

    public Vector3i getClimbDirection() {
        return climbDirection;
    }
    /**
     * Retrieve the pitch in degrees.
     *
     * @return
     */
    public float getPitch() {
        return pitch;
    }

    public void setPitch(float pitch) {
        this.pitch = pitch;
    }

    /**
     * Retrieve the yaw in degrees.
     *
     * @return
     */
    public float getYaw() {
        return yaw;
    }

    public void setYaw(float yaw) {
        this.yaw = yaw;
    }

    public float getFootstepDelta() {
        return footstepDelta;
    }

    public void setFootstepDelta(float delta) {
        this.footstepDelta = delta;
    }

    /**
     * Sets the state of the given entity to the state represented by the
     * CharacterStateEvent. The state of the entity is determined by its
     * LocationComponent (location and orientation of physics body),
     * CharacterMovementComponent (velocity and various movement state
     * variables) and CharacterComponent for pitch and yaw (used for the camera).
     *
     * @param entity
     * @param state
     */
    public static void setToState(EntityRef entity, CharacterStateEvent state) {
        LocationComponent location = entity.getComponent(LocationComponent.class);
        CharacterMovementComponent movementComp = entity.getComponent(CharacterMovementComponent.class);
        CharacterComponent characterComponent = entity.getComponent(CharacterComponent.class);
        if (location == null || movementComp == null || characterComponent == null) {
            return;
        }
        location.setWorldPosition(state.getPosition());
        location.setWorldRotation(state.getRotation());
        entity.saveComponent(location);
        movementComp.mode = state.getMode();
        movementComp.setVelocity(state.getVelocity());
        movementComp.grounded = state.isGrounded();
        movementComp.footstepDelta = state.getFootstepDelta();
        entity.saveComponent(movementComp);
        characterComponent.pitch = state.pitch;
        characterComponent.yaw = state.yaw;
        entity.saveComponent(characterComponent);
        setPhysicsLocation(entity, state.getPosition());
    }

    public static void setToInterpolateState(EntityRef entity, CharacterStateEvent a, CharacterStateEvent b, long time) {
        float t = (float) (time - a.getTime()) / (b.getTime() - a.getTime());
        Vector3f newPos = new Vector3f();
        newPos.interpolate(a.getPosition(), b.getPosition(), t);
        Quat4f newRot = new Quat4f();
        newRot.interpolate(a.getRotation(), b.getRotation(), t);
        LocationComponent location = entity.getComponent(LocationComponent.class);
        location.setWorldPosition(newPos);
        location.setWorldRotation(newRot);
        entity.saveComponent(location);

        CharacterMovementComponent movementComponent = entity.getComponent(CharacterMovementComponent.class);
        movementComponent.mode = a.getMode();
        movementComponent.setVelocity(a.getVelocity());
        movementComponent.grounded = a.isGrounded();
        if (b.getFootstepDelta() < a.getFootstepDelta()) {
            movementComponent.footstepDelta = t * (1 + b.getFootstepDelta() - a.getFootstepDelta()) + a.getFootstepDelta();
            if (movementComponent.footstepDelta > 1) {
                movementComponent.footstepDelta -= 1;
            }
        } else {
            movementComponent.footstepDelta = t * (b.getFootstepDelta() - a.getFootstepDelta()) + a.getFootstepDelta();
        }
        entity.saveComponent(movementComponent);

        CharacterComponent characterComponent = entity.getComponent(CharacterComponent.class);
        characterComponent.pitch = b.pitch;
        characterComponent.yaw = b.yaw;
        entity.saveComponent(characterComponent);
        setPhysicsLocation(entity, newPos);
    }

    public static void setToExtrapolateState(EntityRef entity, CharacterStateEvent state, long time) {
        float t = (time - state.getTime()) * 0.0001f;
        Vector3f newPos = new Vector3f(state.getVelocity());
        newPos.scale(t);
        newPos.add(state.getPosition());
        LocationComponent location = entity.getComponent(LocationComponent.class);
        location.setWorldPosition(newPos);
        location.setWorldRotation(state.getRotation());
        entity.saveComponent(location);

        CharacterMovementComponent movementComponent = entity.getComponent(CharacterMovementComponent.class);
        movementComponent.mode = state.getMode();
        movementComponent.setVelocity(state.getVelocity());
        movementComponent.grounded = state.isGrounded();
        entity.saveComponent(movementComponent);

        CharacterComponent characterComponent = entity.getComponent(CharacterComponent.class);
        characterComponent.pitch = state.pitch;
        characterComponent.yaw = state.yaw;
        entity.saveComponent(characterComponent);
        setPhysicsLocation(entity, newPos);
    }

    /**
     * Sets the location in the physics engine.
     *
     * @param entity The entity to set the location of.
     * @param newPos The new position of the entity.
     */
    private static void setPhysicsLocation(EntityRef entity, Vector3f newPos) {
        PhysicsEngine physics = CoreRegistry.get(PhysicsEngine.class);
        CharacterCollider collider = physics.getCharacterCollider(entity);
        collider.setLocation(newPos);
    }

}
TOP

Related Classes of org.terasology.logic.characters.CharacterStateEvent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.