Package org.terasology.logic.players

Source Code of org.terasology.logic.players.FirstPersonRenderer

/*
* 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.players;

import com.google.common.collect.Maps;
import org.lwjgl.opengl.GL11;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.asset.Asset;
import org.terasology.asset.Assets;
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.entitySystem.systems.BaseComponentSystem;
import org.terasology.entitySystem.systems.RegisterMode;
import org.terasology.entitySystem.systems.RegisterSystem;
import org.terasology.entitySystem.systems.RenderSystem;
import org.terasology.logic.characters.CharacterComponent;
import org.terasology.logic.characters.CharacterMovementComponent;
import org.terasology.logic.inventory.InventoryUtils;
import org.terasology.logic.inventory.ItemComponent;
import org.terasology.registry.In;
import org.terasology.rendering.assets.material.Material;
import org.terasology.rendering.assets.mesh.Mesh;
import org.terasology.rendering.assets.shader.ShaderProgramFeature;
import org.terasology.rendering.assets.texture.Texture;
import org.terasology.rendering.assets.texture.TextureRegion;
import org.terasology.rendering.iconmesh.IconMeshFactory;
import org.terasology.rendering.primitives.Tessellator;
import org.terasology.rendering.primitives.TessellatorHelper;
import org.terasology.rendering.world.WorldRenderer;
import org.terasology.world.WorldProvider;
import org.terasology.world.block.Block;
import org.terasology.world.block.family.BlockFamily;
import org.terasology.world.block.items.BlockItemComponent;

import javax.vecmath.Vector2f;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;
import java.util.Map;

import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glScalef;
import static org.lwjgl.opengl.GL11.glTranslatef;

/**
* @author Immortius <immortius@gmail.com>
*/
@RegisterSystem(RegisterMode.CLIENT)
public class FirstPersonRenderer extends BaseComponentSystem implements RenderSystem {
    private static final Logger logger = LoggerFactory.getLogger(FirstPersonRenderer.class);

    @In
    private WorldProvider worldProvider;
    @In
    private LocalPlayer localPlayer;
    @In
    private WorldRenderer worldRenderer;

    private Mesh handMesh;
    private Texture handTex;

    private Map<String, Mesh> iconMeshes = Maps.newHashMap();

    @Override
    public void initialise() {
        Vector2f texPos = new Vector2f(40.0f * 0.015625f, 32.0f * 0.03125f);
        Vector2f texWidth = new Vector2f(4.0f * 0.015625f, -12.0f * 0.03125f);

        Tessellator tessellator = new Tessellator();
        TessellatorHelper.addBlockMesh(tessellator, new Vector4f(1, 1, 1, 1), texPos, texWidth, 1.0f, 1.0f, 0.9f, 0.0f, 0.0f, 0.0f);
        handMesh = tessellator.generateMesh();
        handTex = Assets.getTexture("engine:char");
    }

    @Override
    public void renderOpaque() {

    }

    @Override
    public void renderAlphaBlend() {

    }

    @Override
    public void renderFirstPerson() {
        CharacterComponent character = localPlayer.getCharacterEntity().getComponent(CharacterComponent.class);
        if (character == null) {
            return;
        }
        CharacterMovementComponent charMoveComp = localPlayer.getCharacterEntity().getComponent(CharacterMovementComponent.class);
        if (charMoveComp == null) {
            return;
        }
        float bobOffset = calcBobbingOffset(charMoveComp.footstepDelta, (float) java.lang.Math.PI / 8f, 0.05f);
        float handMovementAnimationOffset = character.handAnimation;

        int invSlotIndex = character.selectedItem;
        EntityRef heldItem = InventoryUtils.getItemAt(localPlayer.getCharacterEntity(), invSlotIndex);
        ItemComponent heldItemComp = heldItem.getComponent(ItemComponent.class);
        BlockItemComponent blockItem = heldItem.getComponent(BlockItemComponent.class);
        if (blockItem != null && blockItem.blockFamily != null) {
            renderBlock(blockItem.blockFamily, bobOffset, handMovementAnimationOffset);
        } else if (heldItemComp != null && heldItemComp.renderWithIcon) {
            renderIcon(heldItemComp.icon, bobOffset, handMovementAnimationOffset);
        } else {
            renderHand(bobOffset, handMovementAnimationOffset);
        }

    }

    @Override
    public void renderShadows() {
    }

    @Override
    public void renderOverlay() {

    }

    private void renderHand(float bobOffset, float handMovementAnimationOffset) {
        Material shader = Assets.getMaterial("engine:prog.block");
        shader.activateFeature(ShaderProgramFeature.FEATURE_USE_MATRIX_STACK);

        shader.enable();
        shader.setFloat("sunlight", worldRenderer.getSunlightValue(), true);
        shader.setFloat("blockLight", worldRenderer.getBlockLightValue(), true);
        glBindTexture(GL11.GL_TEXTURE_2D, handTex.getId());

        glPushMatrix();
        glTranslatef(0.8f, -0.8f + bobOffset - handMovementAnimationOffset * 0.5f, -1.0f - handMovementAnimationOffset * 0.5f);
        glRotatef(-45f - handMovementAnimationOffset * 64.0f, 1.0f, 0.0f, 0.0f);
        glRotatef(35f, 0.0f, 1.0f, 0.0f);
        glTranslatef(0f, 0.25f, 0f);
        glScalef(0.3f, 0.6f, 0.3f);

        handMesh.render();

        glPopMatrix();

        shader.deactivateFeature(ShaderProgramFeature.FEATURE_USE_MATRIX_STACK);
    }

    private void renderIcon(TextureRegion iconTexture, float bobOffset, float handMovementAnimationOffset) {
        Material shader = Assets.getMaterial("engine:prog.block");
        shader.activateFeature(ShaderProgramFeature.FEATURE_USE_MATRIX_STACK);

        shader.enable();

        shader.setBoolean("textured", false, true);

        shader.setFloat("sunlight", worldRenderer.getSunlightValue(), true);
        shader.setFloat("blockLight", worldRenderer.getBlockLightValue(), true);

        glPushMatrix();

        float textureScale = Math.max(iconTexture.getWidth(), iconTexture.getHeight()) / 16f;

        glTranslatef(1.0f, -0.7f + bobOffset - handMovementAnimationOffset * 0.5f, (-1.5f - handMovementAnimationOffset * 0.5f) * (float) Math.pow(textureScale, 0.5));
        glRotatef(-handMovementAnimationOffset * 64.0f, 1.0f, 0.0f, 0.0f);
        glRotatef(-20f, 1.0f, 0.0f, 0.0f);
        glRotatef(-80f, 0.0f, 1.0f, 0.0f);
        glRotatef(45f, 0.0f, 0.0f, 1.0f);
        float scale = 0.75f * (float) Math.pow(textureScale, 0.5);
        glScalef(scale, scale, scale);

        if (iconTexture instanceof Asset<?>) {
            Mesh itemMesh = IconMeshFactory.getIconMesh(iconTexture);
            itemMesh.render();
        }

        glPopMatrix();

        shader.deactivateFeature(ShaderProgramFeature.FEATURE_USE_MATRIX_STACK);
    }

    private void renderBlock(BlockFamily blockFamily, float bobOffset, float handMovementAnimationOffset) {
        Block activeBlock = blockFamily.getArchetypeBlock();
        Vector3f playerPos = localPlayer.getPosition();

        // Adjust the brightness of the block according to the current position of the player
        Material shader = Assets.getMaterial("engine:prog.block");
        shader.activateFeature(ShaderProgramFeature.FEATURE_USE_MATRIX_STACK);

        shader.enable();

        glPushMatrix();

        glTranslatef(1.0f, -0.7f + bobOffset - handMovementAnimationOffset * 0.5f, -1.5f - handMovementAnimationOffset * 0.5f);
        glRotatef(-25f - handMovementAnimationOffset * 64.0f, 1.0f, 0.0f, 0.0f);
        glRotatef(35f, 0.0f, 1.0f, 0.0f);
        glTranslatef(0f, 0.1f, 0f);
        glScalef(0.75f, 0.75f, 0.75f);

        float blockLight = worldRenderer.getBlockLightValue();
        float sunlight = worldRenderer.getSunlightValue();

        //  Blocks with a luminance > 0.0 shouldn't be affected by block light
        if (blockFamily.getArchetypeBlock().getLuminance() > 0.0) {
            blockLight = 1.0f;
        }

        activeBlock.renderWithLightValue(sunlight, blockLight);

        glPopMatrix();

        shader.deactivateFeature(ShaderProgramFeature.FEATURE_USE_MATRIX_STACK);
    }

    private float calcBobbingOffset(float counter, float phaseOffset, float amplitude) {
        return (float) java.lang.Math.sin(2 * Math.PI * counter + phaseOffset) * amplitude;
    }


}
TOP

Related Classes of org.terasology.logic.players.FirstPersonRenderer

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.