Project

General

Profile

Download (10.6 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / bandaged / BandagedCreatorView.java @ 306aa049

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.bandaged;
11

    
12
import android.app.ActivityManager;
13
import android.content.Context;
14
import android.content.pm.ConfigurationInfo;
15
import android.opengl.GLES30;
16
import android.opengl.GLSurfaceView;
17
import android.util.AttributeSet;
18
import android.view.MotionEvent;
19

    
20
import com.google.firebase.crashlytics.FirebaseCrashlytics;
21

    
22
import org.distorted.library.main.DistortedScreen;
23

    
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

    
26
public class BandagedCreatorView extends GLSurfaceView
27
{
28
    private final static float DIRECTION_SENSITIVITY= 12.0f;
29
    public static final int INVALID_POINTER_ID = -1;
30

    
31
    private BandagedCreatorRenderer mRenderer;
32
    private BandagedCreatorTouchControl mTouchControl;
33
    private int mScreenWidth, mScreenHeight, mScreenMin;
34
    private int mTouchedIndex1, mTouchedIndex2;
35
    private float mX1, mY1, mX2, mY2, mX, mY;
36
    private int mPointer1, mPointer2;
37
    private float mRotAngle, mInitDistance;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40
// PUBLIC API
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

    
43
    public BandagedCreatorView(Context context, AttributeSet attrs)
44
      {
45
      super(context,attrs);
46

    
47
      mX = -1;
48
      mY = -1;
49

    
50
      mTouchedIndex1 = -1;
51
      mTouchedIndex2 = -1;
52

    
53
      if(!isInEditMode())
54
        {
55
        BandagedCreatorActivity act = (BandagedCreatorActivity)context;
56
        mRenderer = new BandagedCreatorRenderer(this);
57
        DistortedScreen screen = mRenderer.getScreen();
58
        mTouchControl = new BandagedCreatorTouchControl( mRenderer.getObjectRatio() , screen.getFOV() );
59

    
60
        final ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
61

    
62
        try
63
          {
64
          final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
65
          int esVersion = configurationInfo.reqGlEsVersion>>16;
66
          setEGLContextClientVersion(esVersion);
67
          setRenderer(mRenderer);
68
          }
69
        catch(Exception ex)
70
          {
71
          act.OpenGLError();
72

    
73
          String shading = GLES30.glGetString(GLES30.GL_SHADING_LANGUAGE_VERSION);
74
          String version = GLES30.glGetString(GLES30.GL_VERSION);
75
          String vendor  = GLES30.glGetString(GLES30.GL_VENDOR);
76
          String renderer= GLES30.glGetString(GLES30.GL_RENDERER);
77

    
78
          FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
79
          crashlytics.setCustomKey("GLSL Version"  , shading );
80
          crashlytics.setCustomKey("GL version"    , version );
81
          crashlytics.setCustomKey("GL Vendor "    , vendor  );
82
          crashlytics.setCustomKey("GLSL renderer" , renderer);
83
          crashlytics.recordException(ex);
84
          }
85
        }
86
      }
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

    
90
    public int getTouched()
91
      {
92
      return mTouchedIndex1;
93
      }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
    public BandagedCreatorTouchControl getTouchControl()
98
      {
99
      return mTouchControl;
100
      }
101

    
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

    
104
    public BandagedCreatorRenderer getRenderer()
105
      {
106
      return mRenderer;
107
      }
108

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

    
111
    public void setCubits(BandagedCubit[] cubits, int x, int y, int z)
112
      {
113
      mTouchControl.setCubits(cubits,x,y,z);
114
      }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
    public void resetCubits()
119
      {
120
      if( mTouchedIndex1>=0 ) mRenderer.untouchCubit(mTouchedIndex1);
121
      if( mTouchedIndex2>=0 ) mRenderer.untouchCubit(mTouchedIndex2);
122

    
123
      mTouchedIndex1 = -1;
124
      mTouchedIndex2 = -1;
125
      }
126

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

    
129
    public void setScreenSize(int width, int height)
130
      {
131
      mScreenWidth = width;
132
      mScreenHeight= height;
133
      mScreenMin   = Math.min(width, height);
134
      }
135

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

    
138
    private float getAngle(float x1, float y1, float x2, float y2)
139
      {
140
      return (float) Math.atan2(y1-y2, x1-x2);
141
      }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
    private void actionDown(MotionEvent event)
146
      {
147
      mPointer1 = event.getPointerId(0);
148
      mX1 = event.getX();
149
      mY1 = event.getY();
150
      mPointer2 = INVALID_POINTER_ID;
151

    
152
      float x1 = (mX1 -mScreenWidth*0.5f)/mScreenMin;
153
      float y1 = (mScreenHeight*0.5f-mY1)/mScreenMin;
154

    
155
      int index = mTouchControl.cubitTouched(x1,y1,mRenderer.getQuatAccu() );
156

    
157
      if( index<0 )
158
        {
159
        mX = mX1;
160
        mY = mY1;
161
        }
162
      else
163
        {
164
        mX = -1;
165
        mY = -1;
166

    
167
        if( mTouchedIndex1<0 )
168
          {
169
          mTouchedIndex1 = index;
170
          mRenderer.touchCubit(mTouchedIndex1);
171
          }
172
        else
173
          {
174
          mTouchedIndex2 = index;
175

    
176
          if( mTouchedIndex1 != index )
177
            {
178
            mRenderer.touchCubit(mTouchedIndex2);
179
            }
180
          }
181
        }
182
      }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

    
186
    private void actionMove(MotionEvent event)
187
      {
188
      int index1 = event.findPointerIndex(mPointer1);
189

    
190
      if( index1>=0 )
191
        {
192
        mX1 = event.getX(index1);
193
        mY1 = event.getY(index1);
194
        }
195

    
196
      int index2 = event.findPointerIndex(mPointer2);
197

    
198
      if( index2>=0 )
199
        {
200
        mX2 = event.getX(index2);
201
        mY2 = event.getY(index2);
202
        }
203

    
204
      if( mPointer1!=INVALID_POINTER_ID && mPointer2!=INVALID_POINTER_ID)
205
        {
206
        float angleNow = getAngle(mX1,mY1,mX2,mY2);
207
        float angleDiff = angleNow-mRotAngle;
208
        float sinA = (float)Math.sin(angleDiff);
209
        float cosA = (float)Math.cos(angleDiff);
210
        mRenderer.setQuatTemp(0,0,sinA,cosA);
211
        mRenderer.resetQuats();
212
        mRotAngle = angleNow;
213

    
214
        float distNow  = (float)Math.sqrt( (mX1-mX2)*(mX1-mX2) + (mY1-mY2)*(mY1-mY2) );
215
        float distQuot = mInitDistance<0 ? 1.0f : distNow/ mInitDistance;
216
        mInitDistance = distNow;
217
        mRenderer.mulObjectRatio(distQuot);
218
        }
219
      else
220
        {
221
        float x = event.getX();
222
        float y = event.getY();
223

    
224
        if( mX>=0 && mY>= 0 )
225
          {
226
          float px = mY-y;
227
          float py = mX-x;
228
          float pz = 0;
229
          float plen = (float)Math.sqrt(px*px + py*py + pz*pz);
230

    
231
          if( plen>0 )
232
            {
233
            px /= plen;
234
            py /= plen;
235
            pz /= plen;
236

    
237
            float cosA = (float)Math.cos(plen*3.14f/mScreenMin);
238
            float sinA = (float)Math.sqrt(1-cosA*cosA);
239

    
240
            mRenderer.setQuatTemp(px*sinA, py*sinA, pz*sinA, cosA);
241
            }
242
          }
243
        if( (mX-x)*(mX-x) + (mY-y)*(mY-y) > mScreenMin*mScreenMin/(DIRECTION_SENSITIVITY*DIRECTION_SENSITIVITY) )
244
          {
245
          mX = x;
246
          mY = y;
247
          mRenderer.resetQuats();
248
          }
249
        }
250
      }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
    private void actionUp()
255
      {
256
      mPointer1 = INVALID_POINTER_ID;
257
      mPointer2 = INVALID_POINTER_ID;
258

    
259
      if( mTouchedIndex2>=0 )
260
        {
261
        mRenderer.untouchCubit(mTouchedIndex1);
262

    
263
        if( mTouchedIndex2!=mTouchedIndex1 )
264
          {
265
          mRenderer.untouchCubit(mTouchedIndex2);
266
          mRenderer.setConnecting(mTouchedIndex1,mTouchedIndex2);
267
          }
268

    
269
        mTouchedIndex1 = -1;
270
        mTouchedIndex2 = -1;
271
        }
272

    
273
      mX = -1;
274
      mY = -1;
275

    
276
      mRenderer.resetQuats();
277
      }
278

    
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280

    
281
    private void actionPointerDown(MotionEvent event)
282
      {
283
      int index = event.getActionIndex();
284

    
285
      if( mPointer1==INVALID_POINTER_ID )
286
        {
287
        mPointer1 = event.getPointerId(index);
288
        mX1 = event.getX(index);
289
        mY1 = event.getY(index);
290
        }
291
      else if( mPointer2==INVALID_POINTER_ID )
292
        {
293
        mPointer2 = event.getPointerId(index);
294
        mX2 = event.getX(index);
295
        mY2 = event.getY(index);
296
        }
297

    
298
      mRotAngle = getAngle(mX1,mY1,mX2,mY2);
299
      mInitDistance = -1;
300
      mRenderer.resetQuats();
301
      }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

    
305
    private void actionPointerUp(MotionEvent event)
306
      {
307
      int index = event.getActionIndex();
308

    
309
      if( index==event.findPointerIndex(mPointer1) )
310
        {
311
        mPointer1 = INVALID_POINTER_ID;
312
        mX = mX2;
313
        mY = mY2;
314
        }
315
      else if( index==event.findPointerIndex(mPointer2) )
316
        {
317
        mPointer2 = INVALID_POINTER_ID;
318
        mX = mX1;
319
        mY = mY1;
320
        }
321

    
322
      mRenderer.resetQuats();
323
      }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
    @Override
328
    public boolean onTouchEvent(MotionEvent event)
329
      {
330
      if( mRenderer.isBusy() ) return true;
331

    
332
      int action = event.getActionMasked();
333

    
334
      switch(action)
335
         {
336
         case MotionEvent.ACTION_DOWN        : actionDown(event)       ; break;
337
         case MotionEvent.ACTION_MOVE        : actionMove(event)       ; break;
338
         case MotionEvent.ACTION_UP          : actionUp()              ; break;
339
         case MotionEvent.ACTION_POINTER_DOWN: actionPointerDown(event); break;
340
         case MotionEvent.ACTION_POINTER_UP  : actionPointerUp  (event); break;
341
         }
342

    
343
      return true;
344
      }
345
}
346

    
(6-6/13)