Project

General

Profile

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

magiccube / src / main / java / org / distorted / bandaged / BandagedCreatorView.java @ 2683f0c4

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
    public static final int INVALID_POINTER_ID = -1;
29

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

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39
// PUBLIC API
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

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

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

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

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

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

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

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

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

    
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

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

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

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

    
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

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

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

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

    
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

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

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

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

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

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

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

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

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

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

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

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

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

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

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

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

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

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

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

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

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

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

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

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

    
239
            mRenderer.setQuatTemp(px*sinA, py*sinA, pz*sinA, cosA);
240
            }
241
          }
242

    
243
        mRenderer.resetQuats();
244
        mX = x;
245
        mY = y;
246
        }
247
      }
248

    
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250

    
251
    private void actionUp()
252
      {
253
      mPointer1 = INVALID_POINTER_ID;
254
      mPointer2 = INVALID_POINTER_ID;
255

    
256
      if( mTouchedIndex2>=0 )
257
        {
258
        mRenderer.untouchCubit(mTouchedIndex1);
259

    
260
        if( mTouchedIndex2!=mTouchedIndex1 )
261
          {
262
          mRenderer.untouchCubit(mTouchedIndex2);
263
          mRenderer.setConnecting(mTouchedIndex1,mTouchedIndex2);
264
          }
265

    
266
        mTouchedIndex1 = -1;
267
        mTouchedIndex2 = -1;
268
        }
269

    
270
      mX = -1;
271
      mY = -1;
272

    
273
      mRenderer.resetQuats();
274
      }
275

    
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277

    
278
    private void actionPointerDown(MotionEvent event)
279
      {
280
      int index = event.getActionIndex();
281

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

    
295
      mRotAngle = getAngle(mX1,mY1,mX2,mY2);
296
      mInitDistance = -1;
297
      mRenderer.resetQuats();
298
      }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
    private void actionPointerUp(MotionEvent event)
303
      {
304
      int index = event.getActionIndex();
305

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

    
319
      mRenderer.resetQuats();
320
      }
321

    
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

    
324
    @Override
325
    public boolean onTouchEvent(MotionEvent event)
326
      {
327
      if( mRenderer.isBusy() ) return true;
328

    
329
      int action = event.getActionMasked();
330

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

    
340
      return true;
341
      }
342
}
343

    
(6-6/13)