Project

General

Profile

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

magiccube / src / main / java / org / distorted / control / RubikControlRotate.java @ 588ace55

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