Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / automator / ObjectAutomatorRotate.java @ dd00d051

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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.objectlib.automator;
21

    
22
import java.io.IOException;
23
import java.io.InputStream;
24

    
25
import android.app.Activity;
26
import android.graphics.Bitmap;
27
import android.graphics.BitmapFactory;
28

    
29
import org.distorted.library.effect.MatrixEffectQuaternion;
30
import org.distorted.library.effect.MatrixEffectScale;
31
import org.distorted.library.main.DistortedEffects;
32
import org.distorted.library.main.DistortedFramebuffer;
33
import org.distorted.library.main.DistortedNode;
34
import org.distorted.library.main.DistortedTexture;
35
import org.distorted.library.mesh.MeshQuad;
36
import org.distorted.library.message.EffectListener;
37
import org.distorted.library.type.Dynamic;
38
import org.distorted.library.type.Dynamic3D;
39
import org.distorted.library.type.Dynamic4D;
40
import org.distorted.library.type.Static3D;
41
import org.distorted.library.type.Static4D;
42
import org.distorted.library.main.QuatHelper;
43

    
44
import org.distorted.objectlib.R;
45
import org.distorted.objectlib.main.TwistyObject;
46

    
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

    
49
class ObjectAutomatorRotate implements EffectListener
50
  {
51
  private static final int NUM_SCREEN = 0;
52
  private static final int NUM_OBJECT = 1;
53

    
54
  private static Static4D INIT_QUAT;
55

    
56
  private final ObjectAutomator mControl;
57
  private DistortedEffects[] mScreenEffects, mObjectEffects;
58
  private DistortedNode[] mScreenNodes, mObjectNodes;
59
  private long mScreenEffectID, mObjectEffectID, mCubeEffectID;
60
  private Static4D mObjRotQuat;
61

    
62
  private Dynamic3D mDynamic3;
63
  private Dynamic4D mDynamic4;
64
  private MatrixEffectScale mScale;
65
  private MatrixEffectQuaternion mQuaternion;
66
  private MeshQuad mScreenQuad, mObjectQuad;
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
   private Bitmap openBitmap(Activity act, int resource)
71
     {
72
     try( InputStream is = act.getResources().openRawResource(resource) )
73
       {
74
       return BitmapFactory.decodeStream(is);
75
       }
76
     catch( IOException e )
77
       {
78
       // ignore
79
       }
80

    
81
     return null;
82
     }
83

    
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

    
86
  private void computeInitQuat()
87
    {
88
    double alphaZ = 0;//-Math.PI* 0.1250f;
89
    double alphaY = 0;//-Math.PI* 0.0625f;
90

    
91
    alphaY /= 2;
92
    alphaZ /= 2;
93

    
94
    float sinZ = (float)Math.sin(alphaZ);
95
    float cosZ = (float)Math.cos(alphaZ);
96
    float sinY = (float)Math.sin(alphaY);
97
    float cosY = (float)Math.cos(alphaY);
98

    
99
    Static4D qZ = new Static4D(0,0,sinZ,cosZ);
100
    Static4D qY = new Static4D(0,sinY,0,cosY);
101

    
102
    INIT_QUAT = QuatHelper.quatMultiply(qY,qZ);
103
    }
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106
// Take 3D vector 'ax', rotate it by quaternion 'objQuat' to get vector V1.
107
// Take 3D vector (1,0,0) and rotate it by INIT_QUAT to get vector V2.
108
// Return a quaternion Q such that if we rotate V1 by Q, we get V2.
109

    
110
  private Static4D computeQuat(Static3D ax, Static4D objQuat, float x, float y, float z)
111
    {
112
    Static4D ax4D = new Static4D( ax.get0(), ax.get1(), ax.get2(), 0);
113
    Static4D axRo = QuatHelper.rotateVectorByQuat(ax4D,objQuat);
114
    return QuatHelper.retRotationQuat(axRo.get0(),axRo.get1(),axRo.get2(),x,y,z);
115
    }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  private void computeRotQuat()
120
    {
121
    TwistyObject object = mControl.getObject();
122
    Static3D[] axis = object.getRotationAxis();
123
    int chosen=-1,numAxis = axis.length;
124
    float cos,maxCos = -1.0f;
125
    Static4D quat;
126

    
127
    Static4D objCurrQuat = mControl.getQuat();
128
    Static4D axisX = new Static4D(1,0,0,0);
129
    Static4D rotAxisX = QuatHelper.rotateVectorByQuat(axisX,INIT_QUAT);
130

    
131
    float axX = rotAxisX.get0();
132
    float axY = rotAxisX.get1();
133
    float axZ = rotAxisX.get2();
134

    
135
    for (int a=0; a<numAxis; a++)
136
      {
137
      quat = computeQuat(axis[a],objCurrQuat,axX,axY,axZ);
138
      cos = quat.get3();
139

    
140
android.util.Log.e("D", "axis="+a+" "+quat.get0()+" "+quat.get1()+" "+quat.get2()+" "+quat.get3() );
141

    
142
      if (cos > maxCos)
143
        {
144
        maxCos = cos;
145
        chosen = a;
146
        if( mObjRotQuat==null ) mObjRotQuat = new Static4D(quat);
147
        else mObjRotQuat.set(quat);
148
        }
149
      }
150

    
151
    android.util.Log.e("D", "axis chosen: "+chosen);
152

    
153

    
154
android.util.Log.e("D", mObjRotQuat.get0()+" "+mObjRotQuat.get1()+" "+mObjRotQuat.get2()+" "+mObjRotQuat.get3() );
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  private void setScreenEffectsStage1()
160
    {
161
    mDynamic3.resetToBeginning();
162
    mScale.notifyWhenFinished(mControl);
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166
// the whole cube rotates so that its axis is alignled according to the Euler angles defined in
167
// computeInitQuat()
168

    
169
  private void setObjectEffectsStage1()
170
    {
171
    TwistyObject obj = mControl.getObject();
172
    obj.apply(mQuaternion,0);
173
    mDynamic4.resetToBeginning();
174
    mQuaternion.notifyWhenFinished(this);
175

    
176

    
177
Static4D d = mDynamic4.getPoint(1);
178

    
179
android.util.Log.e("D", "set: "+d.get0()+" "+d.get1()+" "+d.get2()+" "+d.get3() );
180

    
181
    }
182

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

    
185
  private void setObjectEffectsStage2()
186
    {
187

    
188
    }
189

    
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

    
192
  private void createScreenEffects()
193
    {
194
    mScreenEffects   = new DistortedEffects[NUM_SCREEN];
195
    mScreenEffects[0]= new DistortedEffects();
196

    
197
    DistortedFramebuffer frame = mControl.getFramebuffer();
198
    int wid = frame.getWidth();
199

    
200
    Static3D scaleStart= new Static3D(1,1,1);
201
    Static3D scaleEnd  = new Static3D(wid,wid,wid);
202

    
203
    mDynamic3 = new Dynamic3D(10000,0.5f);
204
    mDynamic3.add(scaleStart);
205
    mDynamic3.add(scaleEnd  );
206
    mDynamic3.add(scaleStart);
207
    mDynamic3.setMode(Dynamic.MODE_PATH);
208

    
209
    mScale = new MatrixEffectScale(mDynamic3);
210
    mScreenEffectID = mScale.getID();
211
    mScreenEffects[0].apply(mScale);
212
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  private void createObjectEffects()
217
    {
218
    mObjectEffects   = new DistortedEffects[NUM_OBJECT];
219
    mObjectEffects[0]= new DistortedEffects();
220

    
221
    mDynamic4 = new Dynamic4D(5000,0.5f);
222
    mDynamic4.add(new Static4D(0,0,0,1));
223
    mDynamic4.add(mObjRotQuat);
224
    mDynamic4.add(mObjRotQuat);
225
    mDynamic4.add(mObjRotQuat);
226
    mDynamic4.setMode(Dynamic.MODE_PATH);
227

    
228
android.util.Log.e("D", "create: "+mObjRotQuat.get0()+" "+mObjRotQuat.get1()+" "+mObjRotQuat.get2()+" "+mObjRotQuat.get3() );
229

    
230
TwistyObject obj = mControl.getObject();
231
Static3D ax = obj.getRotationAxis()[0];
232
Static4D axis = new Static4D(ax.get0(), ax.get1(), ax.get2(), 0);
233

    
234
Static4D v1 = QuatHelper.rotateVectorByQuat( new Static4D(1,0,0,0), INIT_QUAT);
235
Static4D v2 = QuatHelper.rotateVectorByQuat( axis                 , mObjRotQuat);
236

    
237
android.util.Log.e("D", "v1: "+v1.get0()+" "+v1.get1()+" "+v1.get2()+" "+v1.get3());
238
android.util.Log.e("D", "v2: "+v2.get0()+" "+v2.get1()+" "+v2.get2()+" "+v2.get3());
239
android.util.Log.e("D", "ax: "+ax.get0()+" "+ax.get1()+" "+ax.get2());
240

    
241

    
242
    Static3D center = new Static3D(0,0,0);
243
    mQuaternion = new MatrixEffectQuaternion(mDynamic4, center);
244
    mCubeEffectID = mQuaternion.getID();
245

    
246
    DistortedFramebuffer frame = mControl.getFramebuffer();
247
    int wid = frame.getWidth();
248
    Static3D scaleFactor = new Static3D(wid,wid*0.1f,10);
249
    MatrixEffectScale scale = new MatrixEffectScale(scaleFactor);
250
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion(INIT_QUAT,center);
251

    
252
    mObjectEffects[0].apply(scale);
253
    mObjectEffects[0].apply(quat);
254
    }
255

    
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

    
258
  private void createScreenNodes()
259
    {
260
    if( mScreenNodes==null )
261
      {
262
      mScreenNodes= new DistortedNode[NUM_SCREEN];
263
      mScreenQuad = new MeshQuad();
264
      }
265

    
266
    DistortedTexture texture = new DistortedTexture();
267
    texture.setColorARGB(0xff00ff00);
268
    mScreenNodes[0] = new DistortedNode(texture, mScreenEffects[0], mScreenQuad);
269
    }
270

    
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272

    
273
  private void createObjectNodes()
274
    {
275
    if( mObjectNodes==null )
276
      {
277
      mObjectNodes= new DistortedNode[NUM_OBJECT];
278
      mObjectQuad = new MeshQuad();
279
      }
280

    
281
    Activity act = mControl.getActivity();
282

    
283
    if( act!=null )
284
      {
285
      Bitmap bmpArrow = openBitmap(act, R.drawable.ui_axis_arrow);
286
      DistortedTexture textureArrow = new DistortedTexture();
287

    
288
      if( bmpArrow!=null ) textureArrow.setTexture(bmpArrow);
289

    
290
      mObjectNodes[0] = new DistortedNode(textureArrow, mObjectEffects[0], mObjectQuad);
291
      }
292
    else
293
      {
294
      android.util.Log.e("D", "Activity NULL!!");
295
      }
296
    }
297

    
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

    
300
  long getEffectID()
301
    {
302
    return mObjectEffectID;
303
    }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

    
307
  DistortedNode[] getScreenNodes()
308
    {
309
    if( NUM_SCREEN>0 )
310
      {
311
      if( mScreenEffects==null ) createScreenEffects();
312
      createScreenNodes();
313
      setScreenEffectsStage1();
314
      }
315

    
316
    return mScreenNodes;
317
    }
318

    
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320

    
321
  DistortedNode[] returnScreenNodes()
322
    {
323
    return mScreenNodes;
324
    }
325

    
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327

    
328
   DistortedNode[] getObjectNodes()
329
    {
330
    if( NUM_OBJECT>0 )
331
      {
332
      if( INIT_QUAT==null ) computeInitQuat();
333
      computeRotQuat();
334
      if( mObjectEffects==null ) createObjectEffects();
335
      createObjectNodes();
336
      setObjectEffectsStage1();
337
      }
338

    
339
    return mObjectNodes;
340
    }
341

    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343

    
344
   DistortedNode[] returnObjectNodes()
345
    {
346
    return mObjectNodes;
347
    }
348

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350

    
351
  ObjectAutomatorRotate(ObjectAutomator control)
352
    {
353
    mControl = control;
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
  @Override
359
  public void effectFinished(long effectID)
360
    {
361
    if( effectID==mCubeEffectID)
362
      {
363
      setObjectEffectsStage2();
364

    
365
      TwistyObject obj = mControl.getObject();
366
      obj.remove(mCubeEffectID);
367
      mObjectEffectID = -1;
368
      mControl.effectFinished(mObjectEffectID);
369
      }
370
    }
371
  }
(2-2/3)