Project

General

Profile

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

magiccube / src / main / java / org / distorted / control / RubikControlRotate.java @ 3f7a4363

1 51f51f83 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.control;
21
22 b2a92941 Leszek Koltunski
import android.graphics.Bitmap;
23
import android.graphics.BitmapFactory;
24
25
import org.distorted.library.effect.MatrixEffectQuaternion;
26 51f51f83 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectScale;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedNode;
29 7a44bbc2 Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
30 51f51f83 Leszek Koltunski
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshQuad;
32 b2a92941 Leszek Koltunski
import org.distorted.library.message.EffectListener;
33 51f51f83 Leszek Koltunski
import org.distorted.library.type.Dynamic;
34
import org.distorted.library.type.Dynamic3D;
35 b2a92941 Leszek Koltunski
import org.distorted.library.type.Dynamic4D;
36 51f51f83 Leszek Koltunski
import org.distorted.library.type.Static3D;
37 b9d4aa3b Leszek Koltunski
import org.distorted.library.type.Static4D;
38 3f7a4363 Leszek Koltunski
39
import org.distorted.objectlib.main.TwistyObject;
40
import org.distorted.objectlib.main.QuatHelper;
41
42 b2a92941 Leszek Koltunski
import org.distorted.main.R;
43
import org.distorted.main.RubikActivity;
44 51f51f83 Leszek Koltunski
45 b2a92941 Leszek Koltunski
import java.io.IOException;
46
import java.io.InputStream;
47
48 51f51f83 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
49
50 b2a92941 Leszek Koltunski
class RubikControlRotate implements EffectListener
51 51f51f83 Leszek Koltunski
  {
52 b9d4aa3b Leszek Koltunski
  private static final int NUM_SCREEN = 0;
53
  private static final int NUM_OBJECT = 1;
54
55
  private static Static4D INIT_QUAT;
56 51f51f83 Leszek Koltunski
57
  private final RubikControl mControl;
58 b9d4aa3b Leszek Koltunski
  private DistortedEffects[] mScreenEffects, mObjectEffects;
59
  private DistortedNode[] mScreenNodes, mObjectNodes;
60 b2a92941 Leszek Koltunski
  private long mScreenEffectID, mObjectEffectID, mCubeEffectID;
61 b9d4aa3b Leszek Koltunski
  private Static4D mObjRotQuat;
62 51f51f83 Leszek Koltunski
63 b2a92941 Leszek Koltunski
  private Dynamic3D mDynamic3;
64
  private Dynamic4D mDynamic4;
65 51f51f83 Leszek Koltunski
  private MatrixEffectScale mScale;
66 b2a92941 Leszek Koltunski
  private MatrixEffectQuaternion mQuaternion;
67 b9d4aa3b Leszek Koltunski
  private MeshQuad mScreenQuad, mObjectQuad;
68 51f51f83 Leszek Koltunski
69 b2a92941 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
70
71
   private Bitmap openBitmap(RubikActivity act, int resource)
72
     {
73
     try( InputStream is = act.getResources().openRawResource(resource) )
74
       {
75
       return BitmapFactory.decodeStream(is);
76
       }
77
     catch( IOException e )
78
       {
79
       // ignore
80
       }
81
82
     return null;
83
     }
84
85 51f51f83 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
86
87 b9d4aa3b Leszek Koltunski
  private void computeInitQuat()
88 51f51f83 Leszek Koltunski
    {
89 b2a92941 Leszek Koltunski
    double alphaZ = 0;//-Math.PI* 0.1250f;
90
    double alphaY = 0;//-Math.PI* 0.0625f;
91 7aa4c349 Leszek Koltunski
92
    alphaY /= 2;
93
    alphaZ /= 2;
94 b9d4aa3b Leszek Koltunski
95
    float sinZ = (float)Math.sin(alphaZ);
96
    float cosZ = (float)Math.cos(alphaZ);
97
    float sinY = (float)Math.sin(alphaY);
98
    float cosY = (float)Math.cos(alphaY);
99
100
    Static4D qZ = new Static4D(0,0,sinZ,cosZ);
101
    Static4D qY = new Static4D(0,sinY,0,cosY);
102
103
    INIT_QUAT = QuatHelper.quatMultiply(qY,qZ);
104
    }
105
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107 7aa4c349 Leszek Koltunski
// Take 3D vector 'ax', rotate it by quaternion 'objQuat' to get vector V1.
108
// Take 3D vector (1,0,0) and rotate it by INIT_QUAT to get vector V2.
109
// Return a quaternion Q such that if we rotate V1 by Q, we get V2.
110 b9d4aa3b Leszek Koltunski
111 7aa4c349 Leszek Koltunski
  private Static4D computeQuat(Static3D ax, Static4D objQuat, float x, float y, float z)
112 b9d4aa3b Leszek Koltunski
    {
113 7aa4c349 Leszek Koltunski
    Static4D ax4D = new Static4D( ax.get0(), ax.get1(), ax.get2(), 0);
114
    Static4D axRo = QuatHelper.rotateVectorByQuat(ax4D,objQuat);
115
    return QuatHelper.retRotationQuat(axRo.get0(),axRo.get1(),axRo.get2(),x,y,z);
116 b9d4aa3b Leszek Koltunski
    }
117 51f51f83 Leszek Koltunski
118 b9d4aa3b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
119 7a44bbc2 Leszek Koltunski
120 b9d4aa3b Leszek Koltunski
  private void computeRotQuat()
121
    {
122
    TwistyObject object = mControl.getObject();
123
    Static3D[] axis = object.getRotationAxis();
124 7aa4c349 Leszek Koltunski
    int chosen=-1,numAxis = axis.length;
125 b9d4aa3b Leszek Koltunski
    float cos,maxCos = -1.0f;
126
    Static4D quat;
127 51f51f83 Leszek Koltunski
128 7aa4c349 Leszek Koltunski
    Static4D objCurrQuat = mControl.getCurrQuat();
129
    Static4D axisX = new Static4D(1,0,0,0);
130
    Static4D rotAxisX = QuatHelper.rotateVectorByQuat(axisX,INIT_QUAT);
131
132
    float axX = rotAxisX.get0();
133
    float axY = rotAxisX.get1();
134
    float axZ = rotAxisX.get2();
135
136
    for (int a=0; a<numAxis; a++)
137 b9d4aa3b Leszek Koltunski
      {
138 7aa4c349 Leszek Koltunski
      quat = computeQuat(axis[a],objCurrQuat,axX,axY,axZ);
139 b9d4aa3b Leszek Koltunski
      cos = quat.get3();
140 51f51f83 Leszek Koltunski
141 b2a92941 Leszek Koltunski
android.util.Log.e("D", "axis="+a+" "+quat.get0()+" "+quat.get1()+" "+quat.get2()+" "+quat.get3() );
142
143 b9d4aa3b Leszek Koltunski
      if (cos > maxCos)
144
        {
145
        maxCos = cos;
146 7aa4c349 Leszek Koltunski
        chosen = a;
147 b2a92941 Leszek Koltunski
        if( mObjRotQuat==null ) mObjRotQuat = new Static4D(quat);
148
        else mObjRotQuat.set(quat);
149 b9d4aa3b Leszek Koltunski
        }
150 51f51f83 Leszek Koltunski
      }
151 7aa4c349 Leszek Koltunski
152
    android.util.Log.e("D", "axis chosen: "+chosen);
153 b2a92941 Leszek Koltunski
154
155
android.util.Log.e("D", mObjRotQuat.get0()+" "+mObjRotQuat.get1()+" "+mObjRotQuat.get2()+" "+mObjRotQuat.get3() );
156 b9d4aa3b Leszek Koltunski
    }
157
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159
160
  private void setScreenEffectsStage1()
161
    {
162 b2a92941 Leszek Koltunski
    mDynamic3.resetToBeginning();
163 b9d4aa3b Leszek Koltunski
    mScale.notifyWhenFinished(mControl);
164
    }
165
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167 b2a92941 Leszek Koltunski
// the whole cube rotates so that its axis is alignled according to the Euler angles defined in
168
// computeInitQuat()
169 b9d4aa3b Leszek Koltunski
170
  private void setObjectEffectsStage1()
171
    {
172 b2a92941 Leszek Koltunski
    TwistyObject obj = mControl.getObject();
173
    obj.apply(mQuaternion,0);
174
    mDynamic4.resetToBeginning();
175
    mQuaternion.notifyWhenFinished(this);
176
177
178
Static4D d = mDynamic4.getPoint(1);
179
180
android.util.Log.e("D", "set: "+d.get0()+" "+d.get1()+" "+d.get2()+" "+d.get3() );
181
182
    }
183
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185
186
  private void setObjectEffectsStage2()
187
    {
188
189 b9d4aa3b Leszek Koltunski
    }
190
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193
  private void createScreenEffects()
194
    {
195
    mScreenEffects   = new DistortedEffects[NUM_SCREEN];
196
    mScreenEffects[0]= new DistortedEffects();
197
198
    DistortedScreen screen = mControl.getScreen();
199
    int wid = screen.getWidth();
200
201
    Static3D scaleStart= new Static3D(1,1,1);
202
    Static3D scaleEnd  = new Static3D(wid,wid,wid);
203
204 b2a92941 Leszek Koltunski
    mDynamic3 = new Dynamic3D(10000,0.5f);
205
    mDynamic3.add(scaleStart);
206
    mDynamic3.add(scaleEnd  );
207
    mDynamic3.add(scaleStart);
208
    mDynamic3.setMode(Dynamic.MODE_PATH);
209 b9d4aa3b Leszek Koltunski
210 b2a92941 Leszek Koltunski
    mScale = new MatrixEffectScale(mDynamic3);
211 b9d4aa3b Leszek Koltunski
    mScreenEffectID = mScale.getID();
212
    mScreenEffects[0].apply(mScale);
213
    }
214
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216
217
  private void createObjectEffects()
218
    {
219
    mObjectEffects   = new DistortedEffects[NUM_OBJECT];
220
    mObjectEffects[0]= new DistortedEffects();
221
222 b2a92941 Leszek Koltunski
    mDynamic4 = new Dynamic4D(5000,0.5f);
223
    mDynamic4.add(new Static4D(0,0,0,1));
224
    mDynamic4.add(mObjRotQuat);
225
    mDynamic4.add(mObjRotQuat);
226
    mDynamic4.add(mObjRotQuat);
227
    mDynamic4.setMode(Dynamic.MODE_PATH);
228 b9d4aa3b Leszek Koltunski
229 b2a92941 Leszek Koltunski
android.util.Log.e("D", "create: "+mObjRotQuat.get0()+" "+mObjRotQuat.get1()+" "+mObjRotQuat.get2()+" "+mObjRotQuat.get3() );
230
231
TwistyObject obj = mControl.getObject();
232
Static3D ax = obj.getRotationAxis()[0];
233
Static4D axis = new Static4D(ax.get0(), ax.get1(), ax.get2(), 0);
234
235
Static4D v1 = QuatHelper.rotateVectorByQuat( new Static4D(1,0,0,0), INIT_QUAT);
236
Static4D v2 = QuatHelper.rotateVectorByQuat( axis                 , mObjRotQuat);
237 b9d4aa3b Leszek Koltunski
238 b2a92941 Leszek Koltunski
android.util.Log.e("D", "v1: "+v1.get0()+" "+v1.get1()+" "+v1.get2()+" "+v1.get3());
239
android.util.Log.e("D", "v2: "+v2.get0()+" "+v2.get1()+" "+v2.get2()+" "+v2.get3());
240
android.util.Log.e("D", "ax: "+ax.get0()+" "+ax.get1()+" "+ax.get2());
241 b9d4aa3b Leszek Koltunski
242 b2a92941 Leszek Koltunski
243
    Static3D center = new Static3D(0,0,0);
244
    mQuaternion = new MatrixEffectQuaternion(mDynamic4, center);
245
    mCubeEffectID = mQuaternion.getID();
246
247
    DistortedScreen screen = mControl.getScreen();
248
    int wid = screen.getWidth();
249
    Static3D scaleFactor = new Static3D(wid,wid*0.1f,10);
250
    MatrixEffectScale scale = new MatrixEffectScale(scaleFactor);
251
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion(INIT_QUAT,center);
252
253
    mObjectEffects[0].apply(scale);
254
    mObjectEffects[0].apply(quat);
255 b9d4aa3b Leszek Koltunski
    }
256
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258
259
  private void createScreenNodes()
260
    {
261
    if( mScreenNodes==null )
262 51f51f83 Leszek Koltunski
      {
263 b9d4aa3b Leszek Koltunski
      mScreenNodes= new DistortedNode[NUM_SCREEN];
264
      mScreenQuad = new MeshQuad();
265 51f51f83 Leszek Koltunski
      }
266 b9d4aa3b Leszek Koltunski
267
    DistortedTexture texture = new DistortedTexture();
268
    texture.setColorARGB(0xff00ff00);
269
    mScreenNodes[0] = new DistortedNode(texture, mScreenEffects[0], mScreenQuad);
270 51f51f83 Leszek Koltunski
    }
271
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273
274 b9d4aa3b Leszek Koltunski
  private void createObjectNodes()
275 51f51f83 Leszek Koltunski
    {
276 b9d4aa3b Leszek Koltunski
    if( mObjectNodes==null )
277 51f51f83 Leszek Koltunski
      {
278 b9d4aa3b Leszek Koltunski
      mObjectNodes= new DistortedNode[NUM_OBJECT];
279
      mObjectQuad = new MeshQuad();
280
      }
281
282 b2a92941 Leszek Koltunski
    RubikActivity act = mControl.getActivity();
283 51f51f83 Leszek Koltunski
284 b2a92941 Leszek Koltunski
    if( act!=null )
285
      {
286
      Bitmap bmpArrow = openBitmap(act, R.drawable.ui_axis_arrow);
287
      DistortedTexture textureArrow = new DistortedTexture();
288 b9d4aa3b Leszek Koltunski
289 b2a92941 Leszek Koltunski
      if( bmpArrow!=null ) textureArrow.setTexture(bmpArrow);
290 b9d4aa3b Leszek Koltunski
291 b2a92941 Leszek Koltunski
      mObjectNodes[0] = new DistortedNode(textureArrow, mObjectEffects[0], mObjectQuad);
292
      }
293
    else
294
      {
295
      android.util.Log.e("D", "Activity NULL!!");
296
      }
297 51f51f83 Leszek Koltunski
    }
298
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300
301 b2a92941 Leszek Koltunski
  long getEffectID()
302 51f51f83 Leszek Koltunski
    {
303 b9d4aa3b Leszek Koltunski
    return mObjectEffectID;
304
    }
305
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307
308
  DistortedNode[] getScreenNodes()
309
    {
310
    if( NUM_SCREEN>0 )
311
      {
312
      if( mScreenEffects==null ) createScreenEffects();
313
      createScreenNodes();
314
      setScreenEffectsStage1();
315
      }
316
317
    return mScreenNodes;
318
    }
319
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321
322
  DistortedNode[] returnScreenNodes()
323
    {
324
    return mScreenNodes;
325
    }
326
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328
329
   DistortedNode[] getObjectNodes()
330
    {
331
    if( NUM_OBJECT>0 )
332
      {
333 b2a92941 Leszek Koltunski
      if( INIT_QUAT==null ) computeInitQuat();
334
      computeRotQuat();
335 b9d4aa3b Leszek Koltunski
      if( mObjectEffects==null ) createObjectEffects();
336
      createObjectNodes();
337
      setObjectEffectsStage1();
338
      }
339 51f51f83 Leszek Koltunski
340 b9d4aa3b Leszek Koltunski
    return mObjectNodes;
341 51f51f83 Leszek Koltunski
    }
342
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344
345 b9d4aa3b Leszek Koltunski
   DistortedNode[] returnObjectNodes()
346 51f51f83 Leszek Koltunski
    {
347 b9d4aa3b Leszek Koltunski
    return mObjectNodes;
348 51f51f83 Leszek Koltunski
    }
349
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351
352
  RubikControlRotate(RubikControl control)
353
    {
354
    mControl = control;
355
    }
356 b2a92941 Leszek Koltunski
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358
359
  @Override
360
  public void effectFinished(long effectID)
361
    {
362
    if( effectID==mCubeEffectID)
363
      {
364
      setObjectEffectsStage2();
365
366
      TwistyObject obj = mControl.getObject();
367
      obj.remove(mCubeEffectID);
368
      mObjectEffectID = -1;
369
      mControl.effectFinished(mObjectEffectID);
370
      }
371
    }
372 51f51f83 Leszek Koltunski
  }