1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.gameperformance;
17 
18 import java.util.Random;
19 
20 import android.annotation.NonNull;
21 import android.opengl.Matrix;
22 
23 /**
24  * Class that performs bouncing animation for RenderPatch on the screen.
25  */
26 public class RenderPatchAnimation {
27     private final static Random RANDOM = new Random();
28 
29     private final RenderPatch mRenderPatch;
30     // Bounds of animation
31     private final float mAvailableX;
32     private final float mAvailableY;
33 
34     // Crurrent position.
35     private float mPosX;
36     private float mPosY;
37     // Direction of movement.
38     private float mDirX;
39     private float mDirY;
40 
41     private float[] mMatrix;
42 
RenderPatchAnimation(@onNull RenderPatch renderPatch, float ratio)43     public RenderPatchAnimation(@NonNull RenderPatch renderPatch, float ratio) {
44         mRenderPatch = renderPatch;
45 
46         mAvailableX = ratio - mRenderPatch.getDimension();
47         mAvailableY = 1.0f - mRenderPatch.getDimension();
48 
49         mPosX = 2.0f * mAvailableX * RANDOM.nextFloat() - mAvailableX;
50         mPosY = 2.0f * mAvailableY * RANDOM.nextFloat() - mAvailableY;
51         mMatrix = new float[16];
52 
53         // Evenly distributed in cycle, normalized.
54         while (true) {
55             mDirX = 2.0f * RANDOM.nextFloat() - 1.0f;
56             mDirY = mRenderPatch.getDimension() < 1.0f ? 2.0f * RANDOM.nextFloat() - 1.0f : 0.0f;
57 
58             final float length = (float)Math.sqrt(mDirX * mDirX + mDirY * mDirY);
59             if (length <= 1.0f && length > 0.0f) {
60                 mDirX /= length;
61                 mDirY /= length;
62                 break;
63             }
64         }
65     }
66 
67     @NonNull
68     public RenderPatch getRenderPatch() {
69         return mRenderPatch;
70     }
71 
72     /**
73      * Performs the next update. t specifies the distance to travel along the direction. This checks
74      * if patch goes out of screen and invert axis direction if needed.
75      */
76     public void update(float t) {
77         mPosX += mDirX * t;
78         mPosY += mDirY * t;
79         if (mPosX < -mAvailableX) {
80             mDirX = Math.abs(mDirX);
81         } else if (mPosX > mAvailableX) {
82             mDirX = -Math.abs(mDirX);
83         }
84         if (mPosY < -mAvailableY) {
85             mDirY = Math.abs(mDirY);
86         } else if (mPosY > mAvailableY) {
87             mDirY = -Math.abs(mDirY);
88         }
89     }
90 
91     /**
92      * Returns Model/View/Projection transform for the patch.
93      */
94     public float[] getTransform(@NonNull float[] vpMatrix) {
95         Matrix.setIdentityM(mMatrix, 0);
96         mMatrix[12] = mPosX;
97         mMatrix[13] = mPosY;
98         Matrix.multiplyMM(mMatrix, 0, vpMatrix, 0, mMatrix, 0);
99         return mMatrix;
100     }
101 }