org.gearvrf.controls.model.Apple.java Source code

Java tutorial

Introduction

Here is the source code for org.gearvrf.controls.model.Apple.java

Source

/* Copyright 2015 Samsung Electronics Co., LTD
 *
 * 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.gearvrf.controls.model;

import android.content.res.Resources;
import android.content.res.TypedArray;

import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.gearvrf.GVRAndroidResource;
import org.gearvrf.GVRContext;
import org.gearvrf.GVRMaterial;
import org.gearvrf.GVRMesh;
import org.gearvrf.GVRRenderData;
import org.gearvrf.GVRSceneObject;
import org.gearvrf.GVRTexture;
import org.gearvrf.animation.GVRAnimation;
import org.gearvrf.animation.GVRInterpolator;
import org.gearvrf.animation.GVROpacityAnimation;
import org.gearvrf.animation.GVRRelativeMotionAnimation;
import org.gearvrf.animation.GVRScaleAnimation;
import org.gearvrf.controls.MainScript;
import org.gearvrf.controls.R;
import org.gearvrf.controls.WormShadow;
import org.gearvrf.controls.anim.AnimationsTime;
import org.gearvrf.controls.interpolators.Bounce;
import org.gearvrf.controls.interpolators.CircularIn;
import org.gearvrf.controls.interpolators.CircularOut;
import org.gearvrf.controls.interpolators.ExpoIn;
import org.gearvrf.controls.interpolators.ExpoOut;
import org.gearvrf.controls.interpolators.QuadIn;
import org.gearvrf.controls.interpolators.QuadOut;
import org.gearvrf.controls.shaders.ColorSwapShader;
import org.gearvrf.controls.util.Constants;
import org.gearvrf.controls.util.RenderingOrder;
import org.gearvrf.controls.util.Util;

import java.util.ArrayList;

public class Apple extends GVRSceneObject {

    // public final float ANIMATION_DURATION =
    // AnimationsTime.getDropTime();//2.5f;
    public final float OPACITY_ANIMATION_DURATION = 2;
    public final float Y_ANIMATION_DELTA = -5;
    private final float APPLE_SCALE = 0.75f;
    private final static float MAX_APPLES_DISTANCE = 1.5f;
    private final static float CAMERA_DIRECTION_THREASHOLD = 0.75f;
    public static ArrayList<Apple> appleList = new ArrayList<Apple>();
    public Star star;
    private WormShadow shadow;

    public static int currentMotion = 0;

    public enum Motion {
        Linear, Bouncing, CircularIn, CircularOut, ExpoIn, ExpoOut, QuadIn, QuadOut
    };

    public static Motion motion = Motion.Linear;

    public Apple(GVRContext gvrContext) {
        super(gvrContext);
        this.getTransform().setScale(APPLE_SCALE, APPLE_SCALE, APPLE_SCALE);
        setAppleRenderData(gvrContext);
        setAppleShaderParameters(gvrContext);
        star = new Star(gvrContext);
        shadow = new WormShadow(gvrContext, 0.27f, 0.27f, RenderingOrder.APPLE_SHADOW);
        shadow.getTransform().setScale(2, 2, 2);
        gvrContext.getMainScene().addSceneObject(star);
    }

    public void setAppleRenderData(GVRContext gvrContext) {
        GVRMesh mesh = gvrContext.loadMesh(new GVRAndroidResource(gvrContext, R.raw.apple));

        ColorSwapShader shader = new ColorSwapShader(gvrContext);
        GVRMaterial material = new GVRMaterial(gvrContext, shader.getShaderId());
        GVRRenderData renderData = new GVRRenderData(gvrContext);
        renderData.setMesh(mesh);
        renderData.setMaterial(material);
        this.attachRenderData(renderData);

        getRenderData().setRenderingOrder(RenderingOrder.APPLE);
    }

    public void setAppleShaderParameters(GVRContext gvrContext) {
        GVRTexture grayScaleTexture = gvrContext
                .loadTexture(new GVRAndroidResource(gvrContext, R.drawable.apple_diffuse));
        GVRTexture detailsTexture = gvrContext
                .loadTexture(new GVRAndroidResource(gvrContext, R.drawable.apple_details));

        this.getRenderData().getMaterial().setOpacity(0);
        this.getRenderData().getMaterial().setTexture(ColorSwapShader.TEXTURE_GRAYSCALE, grayScaleTexture);
        this.getRenderData().getMaterial().setTexture(ColorSwapShader.TEXTURE_DETAILS, detailsTexture);
        updateAppleColor();
    }

    public static void addApple(Apple apple) {
        appleList.add(apple);
    }

    public static float[] getColor(GVRContext gvrContext) {

        Resources res = gvrContext.getContext().getResources();
        TypedArray colorArray = res.obtainTypedArray(R.array.colors);
        TypedArray colorTypeValues;
        float[] appleColor = new float[3];
        colorTypeValues = res.obtainTypedArray(colorArray.getResourceId(Apple.currentMotion, 0));

        appleColor[0] = colorTypeValues.getFloat(0, 0);
        appleColor[1] = colorTypeValues.getFloat(1, 0);
        appleColor[2] = colorTypeValues.getFloat(2, 0);

        return Util.normalizeColor(appleColor);

    }

    public static GVRInterpolator defineInterpolator(Motion motion) {

        GVRInterpolator interpolator = null;
        switch (motion) {

        case Bouncing:
            interpolator = new Bounce();

            break;
        case CircularIn:
            interpolator = new CircularIn();

            break;
        case CircularOut:
            interpolator = new CircularOut();

            break;
        case ExpoIn:
            interpolator = new ExpoIn();

            break;
        case ExpoOut:
            interpolator = new ExpoOut();

            break;
        case QuadIn:
            interpolator = new QuadIn();

            break;
        case QuadOut:
            interpolator = new QuadOut();

            break;
        default:
            interpolator = null;

            break;
        }
        currentMotion = motion.ordinal();
        return interpolator;
    }

    public void updateAppleColor() {

        float[] color = getColor(this.getGVRContext());
        this.getRenderData().getMaterial().setVec4(ColorSwapShader.COLOR, color[0], color[1], color[2], 1);

    }

    public void playAnimation(GVRContext gvrContext) {

        GVRAnimation anim = new GVRRelativeMotionAnimation(this, AnimationsTime.getDropTime(), 0,
                -Constants.APPLE_INICIAL_YPOS - 1, 0);
        anim.setInterpolator(defineInterpolator(motion));
        anim.start(gvrContext.getAnimationEngine());
        playShadowAnimation();
        playOpacityAnimation(gvrContext);
    }

    private void playShadowAnimation() {
        new GVRScaleAnimation(shadow, AnimationsTime.getDropTime(), 2f).setInterpolator(defineInterpolator(motion))
                .start(getGVRContext().getAnimationEngine());
    }

    public void playOpacityAnimation(GVRContext gvrContext) {

        GVRAnimation anim = new GVROpacityAnimation(this, OPACITY_ANIMATION_DURATION, 1);
        anim.start(gvrContext.getAnimationEngine());

    }

    public void resetPosition(GVRContext gvrContext) {

        updateAppleColor();
        star.playMoveAnimation(gvrContext, this);
        setApplePositionInsideFrustum(gvrContext);
        this.getTransform().setPositionY(Constants.APPLE_INICIAL_YPOS);
        playAnimation(gvrContext);

    }

    public boolean checkValidPosition(Vector3D pos) {

        Vector3D wormPos = new Vector3D(MainScript.worm.wormParent.getTransform().getPositionX(),
                MainScript.worm.wormParent.getTransform().getPositionY(),
                MainScript.worm.wormParent.getTransform().getPositionZ());
        if (Vector3D.distance(pos, wormPos) < MAX_APPLES_DISTANCE)
            return false;
        for (Apple a : appleList) {

            if (a == this)
                continue;
            Vector3D iteratedApple = new Vector3D(a.getTransform().getPositionX(), 0,
                    a.getTransform().getPositionZ());
            float distance = (float) Vector3D.distance(pos, iteratedApple);

            if (distance < MAX_APPLES_DISTANCE) {

                return false;
            }

        }
        return true;
    }

    public void setAppleRandomPosition(GVRContext context) {

        float angle = (float) Math.random() * 360;
        float distance = (float) (Math.random()
                * (Constants.MAX_APPLE_DISTANCE - (Constants.MAX_APPLE_DISTANCE - Constants.MIN_APPLE_DISTANCE))
                + Constants.MIN_APPLE_DISTANCE);
        this.getTransform().setPositionZ(distance);
        this.getTransform().rotateByAxisWithPivot(angle, 0, 1, 0, 0, 0, 0);

        Vector3D instanceApple = new Vector3D(this.getTransform().getPositionX(),
                this.getTransform().getPositionY(), this.getTransform().getPositionZ());
        if (!checkValidPosition(instanceApple)) {
            setAppleRandomPosition(context);

        } else {
            if (!appleList.contains(this)) {
                addApple(this);
                shadow.getTransform().setPosition((float) instanceApple.getX(), -0.9999f,
                        (float) instanceApple.getZ());
                getGVRContext().getMainScene().addSceneObject(shadow);
            }
        }
    }

    public void setApplePositionInsideFrustum(GVRContext context) {
        float angle = (float) Math.random() * 80 - 40;
        float distance = (float) (Math.random()
                * (Constants.MAX_WORM_MOVE_DISTANCE
                        - (Constants.MAX_WORM_MOVE_DISTANCE - Constants.MIN_WORM_MOVE_DISTANCE))
                + Constants.MIN_WORM_MOVE_DISTANCE);

        Vector3D instanceApple = setNewApplePosition(context, angle, distance);
        if (instanceApple == null)
            return;
        if (!checkValidPosition(instanceApple)) {

            setApplePositionInsideFrustum(context);

        }

    }

    private Vector3D setNewApplePosition(GVRContext context, float angle, float distance) {
        float[] vecDistance = context.getMainScene().getMainCameraRig().getLookAt();

        if (vecDistance[1] > CAMERA_DIRECTION_THREASHOLD || vecDistance[1] < -CAMERA_DIRECTION_THREASHOLD) {
            setAppleRandomPosition(context);
            return null;
        }

        vecDistance[0] *= distance;
        vecDistance[2] *= distance;
        Vector3D instanceApple = new Vector3D(vecDistance[0], 0, vecDistance[2]);
        instanceApple.normalize();
        this.getTransform().setPositionX((float) instanceApple.getX());
        this.getTransform().setPositionZ((float) instanceApple.getZ());
        this.getTransform().rotateByAxisWithPivot(angle, 0, 1, 0, 0, 0, 0);
        instanceApple = new Vector3D(this.getTransform().getPositionX(), this.getTransform().getPositionY(),
                this.getTransform().getPositionZ());
        shadow.getTransform().setPosition((float) instanceApple.getX(), -0.9999f, (float) instanceApple.getZ());
        shadow.getTransform().setScale(1, 1, 1);
        return instanceApple;
    }
}