Project

General

Profile

« Previous | Next » 

Revision b9d4aa3b

Added by Leszek Koltunski over 3 years ago

Lots of changes :)

View differences:

src/main/java/org/distorted/control/RubikControl.java
25 25
import org.distorted.library.message.EffectListener;
26 26
import org.distorted.main.RubikActivity;
27 27
import org.distorted.main.RubikSurfaceView;
28
import org.distorted.objects.TwistyObject;
28 29

  
29 30
import java.lang.ref.WeakReference;
30 31

  
......
48 49
    return act!=null ? act.getScreen() : null;
49 50
    }
50 51

  
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53

  
54
  TwistyObject getObject()
55
    {
56
    RubikActivity act = mRefAct.get();
57
    return act!=null ? act.getObject() : null;
58
    }
59

  
51 60
///////////////////////////////////////////////////////////////////////////////////////////////////
52 61

  
53 62
  RubikSurfaceView getSurfaceView()
......
87 96
  private void addRotateObjects()
88 97
    {
89 98
    DistortedScreen screen = getScreen();
90
    DistortedNode[] nodes = mRotate.getNodes();
99
    DistortedNode[] screenNodes = mRotate.getScreenNodes();
91 100

  
92
    if( screen!=null && nodes!=null )
101
    if( screen!=null && screenNodes!=null )
93 102
      {
94
      for (DistortedNode node : nodes) screen.attach(node);
103
      for (DistortedNode node : screenNodes) screen.attach(node);
104
      }
105

  
106
    DistortedNode object = getObject();
107
    DistortedNode[] objectNodes = mRotate.getObjectNodes();
108

  
109
    if( object!=null && objectNodes!=null )
110
      {
111
      for (DistortedNode node : objectNodes) object.attach(node);
95 112
      }
96 113
    }
97 114

  
......
100 117
  private void removeRotateObjects()
101 118
    {
102 119
    DistortedScreen screen = getScreen();
103
    DistortedNode[] nodes = mRotate.returnNodes();
120
    DistortedNode[] screenNodes = mRotate.returnScreenNodes();
104 121

  
105
    if( screen!=null && nodes!=null )
122
    if( screen!=null && screenNodes!=null )
106 123
      {
107
      for (DistortedNode node : nodes) screen.detach(node);
124
      for (DistortedNode node : screenNodes) screen.detach(node);
125
      }
126

  
127
    DistortedNode object = getObject();
128
    DistortedNode[] objectNodes = mRotate.returnObjectNodes();
129

  
130
    if( object!=null && objectNodes!=null )
131
      {
132
      for (DistortedNode node : objectNodes) object.detach(node);
108 133
      }
109 134
    }
110 135

  
src/main/java/org/distorted/control/RubikControlRotate.java
19 19

  
20 20
package org.distorted.control;
21 21

  
22
import org.distorted.helpers.QuatHelper;
22 23
import org.distorted.library.effect.MatrixEffectScale;
23 24
import org.distorted.library.main.DistortedEffects;
24 25
import org.distorted.library.main.DistortedNode;
......
28 29
import org.distorted.library.type.Dynamic;
29 30
import org.distorted.library.type.Dynamic3D;
30 31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33
import org.distorted.objects.TwistyObject;
31 34

  
32 35
///////////////////////////////////////////////////////////////////////////////////////////////////
33 36

  
34 37
class RubikControlRotate
35 38
  {
36
  private static final int NUM_NODE = 1;
39
  private static final int NUM_SCREEN = 0;
40
  private static final int NUM_OBJECT = 1;
41

  
42
  private static Static4D INIT_QUAT;
37 43

  
38 44
  private final RubikControl mControl;
39
  private DistortedEffects[] mEffects;
40
  private DistortedNode[] mNodes;
41
  private long mEffectID;
45
  private DistortedEffects[] mScreenEffects, mObjectEffects;
46
  private DistortedNode[] mScreenNodes, mObjectNodes;
47
  private long mScreenEffectID, mObjectEffectID;
48
  private Static4D mObjRotQuat;
42 49

  
43 50
  private Dynamic3D mDynamic;
44 51
  private MatrixEffectScale mScale;
45
  private MeshQuad mQuad;
52
  private MeshQuad mScreenQuad, mObjectQuad;
46 53

  
47 54
///////////////////////////////////////////////////////////////////////////////////////////////////
48 55

  
49
  private void createEffects()
56
  private void computeInitQuat()
50 57
    {
51
    if( mEffects==null )
52
      {
53
      mEffects   = new DistortedEffects[NUM_NODE];
54
      mEffects[0]= new DistortedEffects();
58
    final double alphaZ = Math.PI/8;
59
    final double alphaY = Math.PI/16;
60

  
61
    float sinZ = (float)Math.sin(alphaZ);
62
    float cosZ = (float)Math.cos(alphaZ);
63
    float sinY = (float)Math.sin(alphaY);
64
    float cosY = (float)Math.cos(alphaY);
65

  
66
    Static4D qZ = new Static4D(0,0,sinZ,cosZ);
67
    Static4D qY = new Static4D(0,sinY,0,cosY);
68

  
69
    INIT_QUAT = QuatHelper.quatMultiply(qY,qZ);
70
    }
71

  
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73

  
74
  private Static4D computeQuat(Static3D ax)
75
    {
76
    return null;
77
    }
55 78

  
56
      DistortedScreen screen = mControl.getScreen();
57
      int wid = screen.getWidth();
79
///////////////////////////////////////////////////////////////////////////////////////////////////
58 80

  
59
      Static3D scaleStart= new Static3D(1,1,1);
60
      Static3D scaleEnd  = new Static3D(wid,wid,wid);
81
  private void computeRotQuat()
82
    {
83
    TwistyObject object = mControl.getObject();
84
    Static3D[] axis = object.getRotationAxis();
85
    float cos,maxCos = -1.0f;
86
    Static4D quat;
61 87

  
62
      mDynamic = new Dynamic3D(10000,0.5f);
63
      mDynamic.add(scaleStart);
64
      mDynamic.add(scaleEnd  );
65
      mDynamic.add(scaleStart);
66
      mDynamic.setMode(Dynamic.MODE_PATH);
88
    for (Static3D axi : axis)
89
      {
90
      quat = computeQuat(axi);
91
      cos = quat.get3();
67 92

  
68
      mScale = new MatrixEffectScale(mDynamic);
69
      mScale.notifyWhenFinished(mControl);
70
      mEffectID = mScale.getID();
71
      mEffects[0].apply(mScale);
93
      if (cos > maxCos)
94
        {
95
        maxCos = cos;
96
        mObjRotQuat = quat;
97
        }
72 98
      }
73
    else
99
    }
100

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

  
103
  private void setScreenEffectsStage1()
104
    {
105
    mDynamic.resetToBeginning();
106
    mScale.notifyWhenFinished(mControl);
107
    }
108

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

  
111
  private void setObjectEffectsStage1()
112
    {
113
    // TODO
114
    }
115

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

  
118
  private void createScreenEffects()
119
    {
120
    mScreenEffects   = new DistortedEffects[NUM_SCREEN];
121
    mScreenEffects[0]= new DistortedEffects();
122

  
123
    DistortedScreen screen = mControl.getScreen();
124
    int wid = screen.getWidth();
125

  
126
    Static3D scaleStart= new Static3D(1,1,1);
127
    Static3D scaleEnd  = new Static3D(wid,wid,wid);
128

  
129
    mDynamic = new Dynamic3D(10000,0.5f);
130
    mDynamic.add(scaleStart);
131
    mDynamic.add(scaleEnd  );
132
    mDynamic.add(scaleStart);
133
    mDynamic.setMode(Dynamic.MODE_PATH);
134

  
135
    mScale = new MatrixEffectScale(mDynamic);
136
    mScreenEffectID = mScale.getID();
137
    mScreenEffects[0].apply(mScale);
138
    }
139

  
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

  
142
  private void createObjectEffects()
143
    {
144
    mObjectEffects   = new DistortedEffects[NUM_OBJECT];
145
    mObjectEffects[0]= new DistortedEffects();
146

  
147
    DistortedScreen screen = mControl.getScreen();
148
    int wid = screen.getWidth();
149

  
150
    Static3D scaleStart= new Static3D(1,1,1);
151
    Static3D scaleEnd  = new Static3D(wid,wid,wid);
152

  
153
    mDynamic = new Dynamic3D(10000,0.5f);
154
    mDynamic.add(scaleStart);
155
    mDynamic.add(scaleEnd  );
156
    mDynamic.add(scaleStart);
157
    mDynamic.setMode(Dynamic.MODE_PATH);
158

  
159
    mScale = new MatrixEffectScale(mDynamic);
160
    mObjectEffectID = mScale.getID();
161
    mObjectEffects[0].apply(mScale);
162
    }
163

  
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

  
166
  private void createScreenNodes()
167
    {
168
    if( mScreenNodes==null )
74 169
      {
75
      mDynamic.resetToBeginning();
76
      mScale.notifyWhenFinished(mControl);
170
      mScreenNodes= new DistortedNode[NUM_SCREEN];
171
      mScreenQuad = new MeshQuad();
77 172
      }
173

  
174
    DistortedTexture texture = new DistortedTexture();
175
    texture.setColorARGB(0xff00ff00);
176
    mScreenNodes[0] = new DistortedNode(texture, mScreenEffects[0], mScreenQuad);
78 177
    }
79 178

  
80 179
///////////////////////////////////////////////////////////////////////////////////////////////////
81 180

  
82
  private void createNodes()
181
  private void createObjectNodes()
83 182
    {
84
    if( mNodes==null )
183
    if( mObjectNodes==null )
85 184
      {
86
      mNodes = new DistortedNode[NUM_NODE];
87
      mQuad = new MeshQuad();
185
      mObjectNodes= new DistortedNode[NUM_OBJECT];
186
      mObjectQuad = new MeshQuad();
187
      }
188

  
189
    if( INIT_QUAT==null )
190
      {
191
      computeInitQuat();
192
      computeRotQuat();
88 193
      }
89 194

  
90 195
    DistortedTexture texture = new DistortedTexture();
91 196
    texture.setColorARGB(0xff00ff00);
92
    mNodes[0] = new DistortedNode(texture, mEffects[0], mQuad);
197
    mObjectNodes[0] = new DistortedNode(texture, mObjectEffects[0], mObjectQuad);
93 198
    }
94 199

  
95 200
///////////////////////////////////////////////////////////////////////////////////////////////////
201
// ??
96 202

  
97 203
  long getEffectID()
98 204
    {
99
    return mEffectID;
205
    return mObjectEffectID;
206
    }
207

  
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

  
210
  long getScreenEffectID()
211
    {
212
    return mScreenEffectID;
100 213
    }
101 214

  
102 215
///////////////////////////////////////////////////////////////////////////////////////////////////
103 216

  
104
  DistortedNode[] getNodes()
217
  long getObjectEffectID()
105 218
    {
106
    createEffects();
107
    createNodes();
219
    return mObjectEffectID;
220
    }
221

  
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

  
224
  DistortedNode[] getScreenNodes()
225
    {
226
    if( NUM_SCREEN>0 )
227
      {
228
      if( mScreenEffects==null ) createScreenEffects();
229
      createScreenNodes();
230
      setScreenEffectsStage1();
231
      }
232

  
233
    return mScreenNodes;
234
    }
235

  
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

  
238
  DistortedNode[] returnScreenNodes()
239
    {
240
    return mScreenNodes;
241
    }
242

  
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

  
245
   DistortedNode[] getObjectNodes()
246
    {
247
    if( NUM_OBJECT>0 )
248
      {
249
      if( mObjectEffects==null ) createObjectEffects();
250
      createObjectNodes();
251
      setObjectEffectsStage1();
252
      }
108 253

  
109
    return mNodes;
254
    return mObjectNodes;
110 255
    }
111 256

  
112 257
///////////////////////////////////////////////////////////////////////////////////////////////////
113 258

  
114
  DistortedNode[] returnNodes()
259
   DistortedNode[] returnObjectNodes()
115 260
    {
116
    return mNodes;
261
    return mObjectNodes;
117 262
    }
118 263

  
119 264
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/control/RubikControlWhole.java
50 50
  private static final int D2 =  250; // finger press
51 51
  private static final int D3 =10000; // finger triangle
52 52
  private static final int D4 = 3000; // fingers approach
53
  private static final int D5 =10000; // fingers circle
53
  private static final int D5 = 8000; // fingers circle
54 54

  
55 55
  private static final int[] DUR = { D1, D2, D3, D2, D1/4, 3*D1/4, D1/4, D2, D4, D5, D4, D2, D1 };
56 56
  private static final int[] DYN = { 2, 1, 1, 1, 2, 2, 4, 2, 2, 2, 2, 2, 4};
......
826 826
      Bitmap bmpHand = openBitmap(act, R.drawable.ui_hand_pointer);
827 827

  
828 828
      mTextureCirc = new DistortedTexture();
829
      mTextureCirc.setTexture(bmpCirc);
830 829
      mTextureShad = new DistortedTexture();
831
      mTextureShad.setTexture(bmpShad);
832 830
      DistortedTexture textureHand = new DistortedTexture();
833
      textureHand.setTexture(bmpHand);
831

  
832
      if( bmpCirc!=null ) mTextureCirc.setTexture(bmpCirc);
833
      if( bmpShad!=null ) mTextureShad.setTexture(bmpShad);
834
      if( bmpHand!=null ) textureHand.setTexture(bmpHand);
834 835

  
835 836
      mNodes[0]= new DistortedNode(mTextureShad,mEffects[0],mQuad);
836 837
      mNodes[1]= new DistortedNode(mTextureShad,mEffects[1],mQuad);
src/main/java/org/distorted/helpers/QuatHelper.java
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.helpers;
21

  
22
import org.distorted.library.type.Static4D;
23

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

  
26
public class QuatHelper
27
  {
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29
// return quat1*quat2
30

  
31
    public static Static4D quatMultiply( Static4D quat1, Static4D quat2 )
32
      {
33
      float qx = quat1.get0();
34
      float qy = quat1.get1();
35
      float qz = quat1.get2();
36
      float qw = quat1.get3();
37

  
38
      float rx = quat2.get0();
39
      float ry = quat2.get1();
40
      float rz = quat2.get2();
41
      float rw = quat2.get3();
42

  
43
      float tx = rw*qx - rz*qy + ry*qz + rx*qw;
44
      float ty = rw*qy + rz*qx + ry*qw - rx*qz;
45
      float tz = rw*qz + rz*qw - ry*qx + rx*qy;
46
      float tw = rw*qw - rz*qz - ry*qy - rx*qx;
47

  
48
      return new Static4D(tx,ty,tz,tw);
49
      }
50

  
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52
// rotate 'vector' by quat  ( i.e. return quat*vector*(quat^-1) )
53

  
54
    public static Static4D rotateVectorByQuat(Static4D vector, Static4D quat)
55
      {
56
      float qx = quat.get0();
57
      float qy = quat.get1();
58
      float qz = quat.get2();
59
      float qw = quat.get3();
60

  
61
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
62
      Static4D tmp = quatMultiply(quat,vector);
63

  
64
      return quatMultiply(tmp,quatInverted);
65
      }
66

  
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68
// rotate 'vector' by quat^(-1)  ( i.e. return (quat^-1)*vector*quat )
69

  
70
    public static Static4D rotateVectorByInvertedQuat(Static4D vector, Static4D quat)
71
      {
72
      float qx = quat.get0();
73
      float qy = quat.get1();
74
      float qz = quat.get2();
75
      float qw = quat.get3();
76

  
77
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
78
      Static4D tmp = quatMultiply(quatInverted,vector);
79

  
80
      return quatMultiply(tmp,quat);
81
      }
82

  
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

  
85
    public static Static4D quatFromDrag(float dragX, float dragY)
86
      {
87
      float axisX = dragY;  // inverted X and Y - rotation axis is perpendicular to (dragX,dragY)
88
      float axisY = dragX;  // Why not (-dragY, dragX) ? because Y axis is also inverted!
89
      float axisZ = 0;
90
      float axisL = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
91

  
92
      if( axisL>0 )
93
        {
94
        axisX /= axisL;
95
        axisY /= axisL;
96
        axisZ /= axisL;
97

  
98
        float ratio = axisL;
99
        ratio = ratio - (int)ratio;     // the cos() is only valid in (0,Pi)
100

  
101
        float cosA = (float)Math.cos(Math.PI*ratio);
102
        float sinA = (float)Math.sqrt(1-cosA*cosA);
103

  
104
        return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
105
        }
106

  
107
      return new Static4D(0f, 0f, 0f, 1f);
108
      }
109
  }
src/main/java/org/distorted/main/RubikSurfaceView.java
30 30

  
31 31
import com.google.firebase.crashlytics.FirebaseCrashlytics;
32 32

  
33
import org.distorted.helpers.QuatHelper;
33 34
import org.distorted.library.type.Static2D;
34 35
import org.distorted.library.type.Static4D;
35 36
import org.distorted.objects.TwistyObject;
......
45 46

  
46 47
public class RubikSurfaceView extends GLSurfaceView
47 48
{
48
    private static final int NUM_SPEED_PROBES = 10;
49
    private static final int INVALID_POINTER_ID = -1;
49
    public static final int NUM_SPEED_PROBES = 10;
50
    public static final int INVALID_POINTER_ID = -1;
50 51

  
51 52
    public static final int MODE_ROTATE  = 0;
52 53
    public static final int MODE_DRAG    = 1;
......
54 55

  
55 56
    // Moving the finger from the middle of the vertical screen to the right edge will rotate a
56 57
    // given face by SWIPING_SENSITIVITY/2 degrees.
57
    private final static int SWIPING_SENSITIVITY  = 240;
58
    public final static int SWIPING_SENSITIVITY  = 240;
58 59
    // Moving the finger by 0.3 of an inch will start a Rotation.
59
    private final static float ROTATION_SENSITIVITY = 0.3f;
60
    public final static float ROTATION_SENSITIVITY = 0.3f;
60 61

  
61 62
    private final Static4D CAMERA_POINT = new Static4D(0, 0, 0, 0);
62 63

  
......
138 139
      mMovement = movement;
139 140
      }
140 141

  
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

  
143
    private Static4D quatFromDrag(float dragX, float dragY)
144
      {
145
      float axisX = dragY;  // inverted X and Y - rotation axis is perpendicular to (dragX,dragY)
146
      float axisY = dragX;  // Why not (-dragY, dragX) ? because Y axis is also inverted!
147
      float axisZ = 0;
148
      float axisL = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
149

  
150
      if( axisL>0 )
151
        {
152
        axisX /= axisL;
153
        axisY /= axisL;
154
        axisZ /= axisL;
155

  
156
        float ratio = axisL;
157
        ratio = ratio - (int)ratio;     // the cos() is only valid in (0,Pi)
158

  
159
        float cosA = (float)Math.cos(Math.PI*ratio);
160
        float sinA = (float)Math.sqrt(1-cosA*cosA);
161

  
162
        return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
163
        }
164

  
165
      return new Static4D(0f, 0f, 0f, 1f);
166
      }
167

  
168 142
///////////////////////////////////////////////////////////////////////////////////////////////////
169 143
// cast the 3D axis we are currently rotating along (which is already casted to the surface of the
170 144
// currently touched face AND converted into a 4D vector - fourth 0) to a 2D in-screen-surface axis
171 145

  
172 146
    private void computeCurrentAxis(Static4D axis)
173 147
      {
174
      Static4D result = rotateVectorByQuat(axis, mQuat);
148
      Static4D result = QuatHelper.rotateVectorByQuat(axis, mQuat);
175 149

  
176 150
      mAxisX =result.get0();
177 151
      mAxisY =result.get1();
......
181 155
      mAxisY /= len;
182 156
      }
183 157

  
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185
// return quat1*quat2
186

  
187
    public static Static4D quatMultiply( Static4D quat1, Static4D quat2 )
188
      {
189
      float qx = quat1.get0();
190
      float qy = quat1.get1();
191
      float qz = quat1.get2();
192
      float qw = quat1.get3();
193

  
194
      float rx = quat2.get0();
195
      float ry = quat2.get1();
196
      float rz = quat2.get2();
197
      float rw = quat2.get3();
198

  
199
      float tx = rw*qx - rz*qy + ry*qz + rx*qw;
200
      float ty = rw*qy + rz*qx + ry*qw - rx*qz;
201
      float tz = rw*qz + rz*qw - ry*qx + rx*qy;
202
      float tw = rw*qw - rz*qz - ry*qy - rx*qx;
203

  
204
      return new Static4D(tx,ty,tz,tw);
205
      }
206

  
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208
// rotate 'vector' by quat  ( i.e. return quat*vector*(quat^-1) )
209

  
210
    public static Static4D rotateVectorByQuat(Static4D vector, Static4D quat)
211
      {
212
      float qx = quat.get0();
213
      float qy = quat.get1();
214
      float qz = quat.get2();
215
      float qw = quat.get3();
216

  
217
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
218
      Static4D tmp = quatMultiply(quat,vector);
219

  
220
      return quatMultiply(tmp,quatInverted);
221
      }
222

  
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224
// rotate 'vector' by quat^(-1)  ( i.e. return (quat^-1)*vector*quat )
225

  
226
    public static Static4D rotateVectorByInvertedQuat(Static4D vector, Static4D quat)
227
      {
228
      float qx = quat.get0();
229
      float qy = quat.get1();
230
      float qz = quat.get2();
231
      float qw = quat.get3();
232

  
233
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
234
      Static4D tmp = quatMultiply(quatInverted,vector);
235

  
236
      return quatMultiply(tmp,quat);
237
      }
238

  
239 158
///////////////////////////////////////////////////////////////////////////////////////////////////
240 159

  
241 160
    private void addSpeedProbe(float x, float y)
......
312 231
        CAMERA_POINT.set2( object==null ? 1.21f : object.getCameraDist() );
313 232

  
314 233
        Static4D touchPoint = new Static4D(x, y, 0, 0);
315
        Static4D rotatedTouchPoint= rotateVectorByInvertedQuat(touchPoint, mQuat);
316
        Static4D rotatedCamera= rotateVectorByInvertedQuat(CAMERA_POINT, mQuat);
234
        Static4D rotatedTouchPoint= QuatHelper.rotateVectorByInvertedQuat(touchPoint, mQuat);
235
        Static4D rotatedCamera= QuatHelper.rotateVectorByInvertedQuat(CAMERA_POINT, mQuat);
317 236

  
318 237
        if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint,rotatedCamera) )
319 238
          {
......
389 308
        float sinA =-(float)Math.sin(angleDiff);
390 309
        float cosA = (float)Math.cos(angleDiff);
391 310

  
392
        Static4D dragQuat = quatMultiply(new Static4D(0,0,sinA,cosA), mQuat);
311
        Static4D dragQuat = QuatHelper.quatMultiply(new Static4D(0,0,sinA,cosA), mQuat);
393 312
        mTemp.set(dragQuat);
394 313

  
395 314
        mRotAngle = angleNow;
......
402 321
        }
403 322
      else
404 323
        {
405
        Static4D dragQuat = quatMultiply(quatFromDrag(mX-x,y-mY), mQuat);
324
        Static4D dragQuat = QuatHelper.quatMultiply(QuatHelper.quatFromDrag(mX-x,y-mY), mQuat);
406 325
        mTemp.set(dragQuat);
407 326
        }
408 327

  
......
474 393
      int numLayers = object.getNumLayers();
475 394

  
476 395
      Static4D touchPoint2 = new Static4D(x, y, 0, 0);
477
      Static4D rotatedTouchPoint2= rotateVectorByInvertedQuat(touchPoint2, mQuat);
396
      Static4D rotatedTouchPoint2= QuatHelper.rotateVectorByInvertedQuat(touchPoint2, mQuat);
478 397
      Static2D res = mMovement.newRotation(numLayers,rotatedTouchPoint2);
479 398

  
480 399
      mCurrentAxis = (int)res.get0();
src/main/java/org/distorted/objects/Cubit.java
21 21

  
22 22
import android.content.SharedPreferences;
23 23

  
24
import org.distorted.helpers.QuatHelper;
24 25
import org.distorted.library.type.Static4D;
25
import org.distorted.main.RubikSurfaceView;
26 26

  
27 27
///////////////////////////////////////////////////////////////////////////////////////////////////
28 28

  
......
141 141
    for(int i=0; i<len; i++)
142 142
      {
143 143
      cubitCenter =  new Static4D(mCurrentPosition[3*i], mCurrentPosition[3*i+1], mCurrentPosition[3*i+2], 0);
144
      rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
144
      rotatedCenter = QuatHelper.rotateVectorByQuat( cubitCenter, quat);
145 145

  
146 146
      mCurrentPosition[3*i  ] = rotatedCenter.get0();
147 147
      mCurrentPosition[3*i+1] = rotatedCenter.get1();
......
189 189

  
190 190
  int removeRotationNow(Static4D quat)
191 191
    {
192
    Static4D q = RubikSurfaceView.quatMultiply(quat,mParent.QUATS[mQuatIndex]);
192
    Static4D q = QuatHelper.quatMultiply(quat,mParent.QUATS[mQuatIndex]);
193 193
    mQuatIndex = normalizeScrambleQuat(q);
194 194

  
195 195
    modifyCurrentPosition(quat);
src/main/java/org/distorted/objects/TwistyDino4.java
21 21

  
22 22
import android.content.res.Resources;
23 23

  
24
import org.distorted.helpers.QuatHelper;
24 25
import org.distorted.library.main.DistortedEffects;
25 26
import org.distorted.library.main.DistortedTexture;
26 27
import org.distorted.library.mesh.MeshSquare;
27 28
import org.distorted.library.type.Static4D;
28 29
import org.distorted.main.R;
29
import org.distorted.main.RubikSurfaceView;
30 30

  
31 31
import java.util.Random;
32 32

  
......
57 57
    float MAXDIFF = 0.01f;
58 58
    float[] center= CENTERS[centerNum];
59 59
    Static4D sc = new Static4D(center[0], center[1], center[2], 1.0f);
60
    Static4D result = RubikSurfaceView.rotateVectorByQuat(sc,QUATS[quatNum]);
60
    Static4D result = QuatHelper.rotateVectorByQuat(sc,QUATS[quatNum]);
61 61
    int numCenters = CENTERS.length;
62 62

  
63 63
    float x = result.get0();
src/main/java/org/distorted/objects/TwistyKilominx.java
25 25

  
26 26
import org.distorted.helpers.FactoryCubit;
27 27
import org.distorted.helpers.FactorySticker;
28
import org.distorted.helpers.QuatHelper;
28 29
import org.distorted.library.effect.MatrixEffectQuaternion;
29 30
import org.distorted.library.main.DistortedEffects;
30 31
import org.distorted.library.main.DistortedTexture;
......
33 34
import org.distorted.library.type.Static3D;
34 35
import org.distorted.library.type.Static4D;
35 36
import org.distorted.main.R;
36
import org.distorted.main.RubikSurfaceView;
37 37

  
38 38
///////////////////////////////////////////////////////////////////////////////////////////////////
39 39

  
......
158 158
    {
159 159
    Static4D quat = QUATS[QUAT_CORNER_INDICES[corner]];
160 160

  
161
    mCurrCornerV[0] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[0],quat);
162
    mCurrCornerV[1] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[1],quat);
163
    mCurrCornerV[2] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[2],quat);
161
    mCurrCornerV[0] = QuatHelper.rotateVectorByQuat(mBasicCornerV[0],quat);
162
    mCurrCornerV[1] = QuatHelper.rotateVectorByQuat(mBasicCornerV[1],quat);
163
    mCurrCornerV[2] = QuatHelper.rotateVectorByQuat(mBasicCornerV[2],quat);
164 164
    }
165 165

  
166 166
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/TwistyMegaminx.java
25 25

  
26 26
import org.distorted.helpers.FactoryCubit;
27 27
import org.distorted.helpers.FactorySticker;
28
import org.distorted.helpers.QuatHelper;
28 29
import org.distorted.library.effect.MatrixEffectQuaternion;
29 30
import org.distorted.library.main.DistortedEffects;
30 31
import org.distorted.library.main.DistortedTexture;
......
33 34
import org.distorted.library.type.Static3D;
34 35
import org.distorted.library.type.Static4D;
35 36
import org.distorted.main.R;
36
import org.distorted.main.RubikSurfaceView;
37 37

  
38 38
///////////////////////////////////////////////////////////////////////////////////////////////////
39 39

  
......
147 147
    {
148 148
    Static4D quat = QUATS[QUAT_CORNER_INDICES[corner]];
149 149

  
150
    mCurrCornerV[0] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[0],quat);
151
    mCurrCornerV[1] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[1],quat);
152
    mCurrCornerV[2] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[2],quat);
150
    mCurrCornerV[0] = QuatHelper.rotateVectorByQuat(mBasicCornerV[0],quat);
151
    mCurrCornerV[1] = QuatHelper.rotateVectorByQuat(mBasicCornerV[1],quat);
152
    mCurrCornerV[2] = QuatHelper.rotateVectorByQuat(mBasicCornerV[2],quat);
153 153
    }
154 154

  
155 155
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/TwistyObject.java
28 28
import com.google.firebase.crashlytics.FirebaseCrashlytics;
29 29

  
30 30
import org.distorted.helpers.FactoryCubit;
31
import org.distorted.helpers.QuatHelper;
31 32
import org.distorted.library.effect.Effect;
32 33
import org.distorted.library.effect.MatrixEffectMove;
33 34
import org.distorted.library.effect.MatrixEffectQuaternion;
......
48 49
import org.distorted.library.type.Static3D;
49 50
import org.distorted.library.type.Static4D;
50 51
import org.distorted.main.BuildConfig;
51
import org.distorted.main.RubikSurfaceView;
52 52

  
53 53
import java.io.DataInputStream;
54 54
import java.io.IOException;
......
466 466

  
467 467
  int mulQuat(int q1, int q2)
468 468
    {
469
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
469
    Static4D result = QuatHelper.quatMultiply(QUATS[q1],QUATS[q2]);
470 470

  
471 471
    float rX = result.get0();
472 472
    float rY = result.get1();
......
533 533
               Static4D quat2 = QUATS[cubit.mQuatIndex];
534 534

  
535 535
               Static4D cubitCenter = new Static4D( orig[0], orig[1], orig[2], 0);              // not used for bandaged objects,
536
               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );   // only check the first position
537
               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
536
               Static4D rotated1 = QuatHelper.rotateVectorByQuat( cubitCenter, quat1 );   // only check the first position
537
               Static4D rotated2 = QuatHelper.rotateVectorByQuat( cubitCenter, quat2 );
538 538

  
539 539
               rotated1.get(mTmp1, 0, 0, 0);
540 540
               rotated2.get(mTmp2, 0, 0, 0);
......
974 974
  abstract float returnMultiplier();
975 975
  abstract float[][] getCuts(int numLayers);
976 976
  abstract boolean shouldResetTextureMaps();
977
  abstract Static3D[] getRotationAxis();
978 977

  
978
  public abstract Static3D[] getRotationAxis();
979 979
  public abstract boolean isSolved();
980 980
  public abstract int[] getBasicAngle();
981 981
  public abstract String retObjectString();
src/main/java/org/distorted/screens/RubikScreenPlay.java
397 397
              pDiag.show( act.getSupportFragmentManager(), RubikDialogPattern.getDialogTag() );
398 398
              break;
399 399
      case 2: RubikControl control = RubikControl.getInstance();
400
              control.animateAll(act);
400
              //control.animateAll(act);
401
              control.animateRotate(act);
401 402
              break;
402 403
      case 3: ScreenList.switchScreen(act, ScreenList.SVER);
403 404
              break;
src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
30 30

  
31 31
import com.google.firebase.crashlytics.FirebaseCrashlytics;
32 32

  
33
import org.distorted.helpers.QuatHelper;
33 34
import org.distorted.library.type.Static2D;
34 35
import org.distorted.library.type.Static4D;
35 36
import org.distorted.objects.Movement;
36 37
import org.distorted.objects.TwistyObject;
37 38

  
39
import static org.distorted.main.RubikSurfaceView.INVALID_POINTER_ID;
40
import static org.distorted.main.RubikSurfaceView.NUM_SPEED_PROBES;
41
import static org.distorted.main.RubikSurfaceView.ROTATION_SENSITIVITY;
42
import static org.distorted.main.RubikSurfaceView.SWIPING_SENSITIVITY;
43

  
38 44
///////////////////////////////////////////////////////////////////////////////////////////////////
39 45

  
40 46
public class TutorialSurfaceView extends GLSurfaceView
41 47
{
42
    private static final int NUM_SPEED_PROBES = 10;
43
    private static final int INVALID_POINTER_ID = -1;
44

  
45
    // Moving the finger from the middle of the vertical screen to the right edge will rotate a
46
    // given face by SWIPING_SENSITIVITY/2 degrees.
47
    private final static int SWIPING_SENSITIVITY  = 240;
48
    // Moving the finger by 0.3 of an inch will start a Rotation.
49
    private final static float ROTATION_SENSITIVITY = 0.3f;
50

  
51
    private final Static4D CAMERA_POINT = new Static4D(0, 0, 1, 0);
52

  
48
    private final Static4D CAMERA_POINT = new Static4D(0, 0, 0, 0);
53 49
    private TutorialRenderer mRenderer;
54 50
    private TutorialPreRender mPreRender;
55 51
    private Movement mMovement;
......
125 121
      mMovement = movement;
126 122
      }
127 123

  
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

  
130
    private Static4D quatFromDrag(float dragX, float dragY)
131
      {
132
      float axisX = dragY;  // inverted X and Y - rotation axis is perpendicular to (dragX,dragY)
133
      float axisY = dragX;  // Why not (-dragY, dragX) ? because Y axis is also inverted!
134
      float axisZ = 0;
135
      float axisL = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
136

  
137
      if( axisL>0 )
138
        {
139
        axisX /= axisL;
140
        axisY /= axisL;
141
        axisZ /= axisL;
142

  
143
        float ratio = axisL;
144
        ratio = ratio - (int)ratio;     // the cos() is only valid in (0,Pi)
145

  
146
        float cosA = (float)Math.cos(Math.PI*ratio);
147
        float sinA = (float)Math.sqrt(1-cosA*cosA);
148

  
149
        return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
150
        }
151

  
152
      return new Static4D(0f, 0f, 0f, 1f);
153
      }
154

  
155 124
///////////////////////////////////////////////////////////////////////////////////////////////////
156 125
// cast the 3D axis we are currently rotating along (which is already casted to the surface of the
157 126
// currently touched face AND converted into a 4D vector - fourth 0) to a 2D in-screen-surface axis
158 127

  
159 128
    private void computeCurrentAxis(Static4D axis)
160 129
      {
161
      Static4D result = rotateVectorByQuat(axis, mQuat);
130
      Static4D result = QuatHelper.rotateVectorByQuat(axis, mQuat);
162 131

  
163 132
      mAxisX =result.get0();
164 133
      mAxisY =result.get1();
......
168 137
      mAxisY /= len;
169 138
      }
170 139

  
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172
// return quat1*quat2
173

  
174
    public static Static4D quatMultiply( Static4D quat1, Static4D quat2 )
175
      {
176
      float qx = quat1.get0();
177
      float qy = quat1.get1();
178
      float qz = quat1.get2();
179
      float qw = quat1.get3();
180

  
181
      float rx = quat2.get0();
182
      float ry = quat2.get1();
183
      float rz = quat2.get2();
184
      float rw = quat2.get3();
185

  
186
      float tx = rw*qx - rz*qy + ry*qz + rx*qw;
187
      float ty = rw*qy + rz*qx + ry*qw - rx*qz;
188
      float tz = rw*qz + rz*qw - ry*qx + rx*qy;
189
      float tw = rw*qw - rz*qz - ry*qy - rx*qx;
190

  
191
      return new Static4D(tx,ty,tz,tw);
192
      }
193

  
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195
// rotate 'vector' by quat  ( i.e. return quat*vector*(quat^-1) )
196

  
197
    public static Static4D rotateVectorByQuat(Static4D vector, Static4D quat)
198
      {
199
      float qx = quat.get0();
200
      float qy = quat.get1();
201
      float qz = quat.get2();
202
      float qw = quat.get3();
203

  
204
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
205
      Static4D tmp = quatMultiply(quat,vector);
206

  
207
      return quatMultiply(tmp,quatInverted);
208
      }
209

  
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211
// rotate 'vector' by quat^(-1)  ( i.e. return (quat^-1)*vector*quat )
212

  
213
    public static Static4D rotateVectorByInvertedQuat(Static4D vector, Static4D quat)
214
      {
215
      float qx = quat.get0();
216
      float qy = quat.get1();
217
      float qz = quat.get2();
218
      float qw = quat.get3();
219

  
220
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
221
      Static4D tmp = quatMultiply(quatInverted,vector);
222

  
223
      return quatMultiply(tmp,quat);
224
      }
225

  
226 140
///////////////////////////////////////////////////////////////////////////////////////////////////
227 141

  
228 142
    private void addSpeedProbe(float x, float y)
......
285 199

  
286 200
    private void setUpDragOrRotate(float x, float y)
287 201
      {
288
        Static4D touchPoint = new Static4D(x, y, 0, 0);
289
        Static4D rotatedTouchPoint= rotateVectorByInvertedQuat(touchPoint, mQuat);
290
        Static4D rotatedCamera= rotateVectorByInvertedQuat(CAMERA_POINT, mQuat);
202
      TwistyObject object = mPreRender.getObject();
203
      CAMERA_POINT.set2( object==null ? 1.21f : object.getCameraDist() );
291 204

  
292
        if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint,rotatedCamera) )
293
          {
294
          mDragging           = false;
295
          mContinuingRotation = false;
296
          mBeginningRotation= !mPreRender.isTouchBlocked();
297
          }
298
        else
299
          {
300
          final TutorialActivity act = (TutorialActivity)getContext();
301
          boolean locked      = act.isLocked();
302
          mDragging           = !locked;
303
          mContinuingRotation = false;
304
          mBeginningRotation  = false;
205
      Static4D touchPoint = new Static4D(x, y, 0, 0);
206
      Static4D rotatedTouchPoint= QuatHelper.rotateVectorByInvertedQuat(touchPoint, mQuat);
207
      Static4D rotatedCamera= QuatHelper.rotateVectorByInvertedQuat(CAMERA_POINT, mQuat);
305 208

  
306
          if( !mDragging )
307
            {
308
            TutorialState state = act.getState();
309
            state.reddenLock(act);
310
            }
209
      if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint,rotatedCamera) )
210
        {
211
        mDragging           = false;
212
        mContinuingRotation = false;
213
        mBeginningRotation= !mPreRender.isTouchBlocked();
214
        }
215
      else
216
        {
217
        final TutorialActivity act = (TutorialActivity)getContext();
218
        boolean locked      = act.isLocked();
219
        mDragging           = !locked;
220
        mContinuingRotation = false;
221
        mBeginningRotation  = false;
222

  
223
        if( !mDragging )
224
          {
225
          TutorialState state = act.getState();
226
          state.reddenLock(act);
311 227
          }
228
        }
312 229
      }
313 230

  
314 231
///////////////////////////////////////////////////////////////////////////////////////////////////
......
345 262
        float sinA =-(float)Math.sin(angleDiff);
346 263
        float cosA = (float)Math.cos(angleDiff);
347 264

  
348
        Static4D dragQuat = quatMultiply(new Static4D(0,0,sinA,cosA), mQuat);
265
        Static4D dragQuat = QuatHelper.quatMultiply(new Static4D(0,0,sinA,cosA), mQuat);
349 266
        mTemp.set(dragQuat);
350 267

  
351 268
        mRotAngle = angleNow;
......
359 276
        }
360 277
      else
361 278
        {
362
        Static4D dragQuat = quatMultiply(quatFromDrag(mX-x,y-mY), mQuat);
279
        Static4D dragQuat = QuatHelper.quatMultiply(QuatHelper.quatFromDrag(mX-x,y-mY), mQuat);
363 280
        mTemp.set(dragQuat);
364 281
        }
365 282

  
......
421 338
      int numLayers = object.getNumLayers();
422 339

  
423 340
      Static4D touchPoint2 = new Static4D(x, y, 0, 0);
424
      Static4D rotatedTouchPoint2= rotateVectorByInvertedQuat(touchPoint2, mQuat);
341
      Static4D rotatedTouchPoint2= QuatHelper.rotateVectorByInvertedQuat(touchPoint2, mQuat);
425 342
      Static2D res = mMovement.newRotation(numLayers,rotatedTouchPoint2);
426 343

  
427 344
      mCurrentAxis = (int)res.get0();

Also available in: Unified diff