Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / touchcontrol / TouchControlMirror.java @ 1eafa9c6

1 0c5d8bf7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6 71f8a172 Leszek Koltunski
// 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 0c5d8bf7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.objectlib.touchcontrol;
11
12 aacf5e27 Leszek Koltunski
import org.distorted.library.helpers.QuatHelper;
13 0c5d8bf7 Leszek Koltunski
import org.distorted.library.type.Static4D;
14
import org.distorted.objectlib.main.TwistyObject;
15
16
///////////////////////////////////////////////////////////////////////////////////////////////////
17
18
public class TouchControlMirror extends TouchControlShapeChanging
19
  {
20
  public TouchControlMirror(TwistyObject object)
21
    {
22
    super(object);
23
    }
24
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26
// We want to avoid the situation when we grab by one of the inside, black faces and that makes us
27
// compute an incorrect 'disabled' ax.
28
// If the touched face is black, return one of the 'not black' faces of the current touched cubit
29
// - the one which is the most flat with the screen, i.e. the one whose normal makes the smallest
30
// angle with the camera vector.
31
32
  private int correctTouchedFace(int cubit, int face, float[] quat)
33
    {
34
    int[] numLayers = mObject.getNumLayers();
35 51262d81 Leszek Koltunski
    int variant     = mObject.getCubitVariant(cubit,numLayers);
36
    int stiShape    = mObject.getVariantStickerShape(variant,face);
37 0c5d8bf7 Leszek Koltunski
38 51262d81 Leszek Koltunski
    if( stiShape>=0 ) return face;
39 0c5d8bf7 Leszek Koltunski
40
    float cx = mCamera[0];
41
    float cy = mCamera[1];
42
    float cz = mCamera[2];
43
44
    float len = (float)Math.sqrt(cx*cx+cy*cy+cz*cz);
45
46
    cx /= len;
47
    cy /= len;
48
    cz /= len;
49
50
    float[] normal = mInfos[mTouchedCubit][face].getNormal();
51
    QuatHelper.rotateVectorByQuat(mTmp,normal,quat);
52
53
    int maxFace= 0;
54
    float maxAngle = -1.0f;
55
56
    for(int i=0; i<6; i++)
57
      if( i!=face )
58
        {
59 51262d81 Leszek Koltunski
        stiShape = mObject.getVariantStickerShape(variant,i);
60 0c5d8bf7 Leszek Koltunski
61 51262d81 Leszek Koltunski
        if( stiShape>=0 )
62 0c5d8bf7 Leszek Koltunski
          {
63
          normal = mInfos[mTouchedCubit][i].getNormal();
64
          QuatHelper.rotateVectorByQuat(mTmp,normal,quat);
65
          float angle = cx*mTmp[0] + cy*mTmp[1] + cz*mTmp[2];
66
67
          if( angle>maxAngle )
68
            {
69
            maxAngle= angle;
70
            maxFace = i;
71
            }
72
          }
73
        }
74
75
    return maxFace;
76
    }
77
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79
80
  private int computeDisabledAxis()
81
    {
82
    int quatIndex  = mObject.getCubitQuatIndex(mTouchedCubit);
83
    float[] quat   = mQuats[quatIndex];
84
    int face = correctTouchedFace(mTouchedCubit,mTouchedFace,quat);
85
    float[] normal = mInfos[mTouchedCubit][face].getNormal();
86
    QuatHelper.rotateVectorByQuat(mTmp,normal,quat);
87
88
    float cx = mTmp[0];
89
    float cy = mTmp[1];
90
    float cz = mTmp[2];
91
92
    float max = -1.0f;
93
    int maxAxis = -1;
94
95
    for(int axis=0; axis<mNumAxis; axis++)
96
      {
97
      float ax = mRotAxis[axis].get0();
98
      float ay = mRotAxis[axis].get1();
99
      float az = mRotAxis[axis].get2();
100
101
      float angle = ax*cx + ay*cy + az*cz;
102
      if( angle<0 ) angle = -angle;
103
104
      if( angle>max )
105
        {
106
        max=angle;
107
        maxAxis = axis;
108
        }
109
      }
110
111
    return maxAxis;
112
    }
113
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115
116
  private int computeRotationIndex(int disabled, float dx, float dy, float dz)
117
    {
118
    float min = Float.MAX_VALUE;
119
    int minAxis = -1;
120
121
    for(int axis=0; axis<mNumAxis; axis++)
122
      if( axis!=disabled )
123
        {
124
        float ax = mRotAxis[axis].get0();
125
        float ay = mRotAxis[axis].get1();
126
        float az = mRotAxis[axis].get2();
127
128
        float angle = dx*ax + dy*ay + dz*az;
129
        if( angle<0 ) angle=-angle;
130
131
        if( angle<min )
132
          {
133
          min=angle;
134
          minAxis = axis;
135
          }
136
        }
137
138
    return minAxis;
139
    }
140
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142
// PUBLIC API
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144
145 cd2e8d4c Leszek Koltunski
  public void newRotation(int[] output, Static4D rotatedTouchPoint, Static4D quat)
146 0c5d8bf7 Leszek Koltunski
    {
147
    float dx = mPoint[0] - rotatedTouchPoint.get0()/mObjectRatio;
148
    float dy = mPoint[1] - rotatedTouchPoint.get1()/mObjectRatio;
149
    float dz = mPoint[2] - rotatedTouchPoint.get2()/mObjectRatio;
150
151 93dc5a55 leszek
    if( mGhostAxisEnabled<0 )
152 4a014840 leszek
      {
153
      int disabledAxis = computeDisabledAxis();
154
      int rotIndex = computeRotationIndex(disabledAxis,dx,dy,dz);
155
      int row = computeRow(mTouchedCubit,rotIndex);
156
      output[0] = rotIndex;
157
      output[1] = row;
158
      }
159
    else
160
      {
161 93dc5a55 leszek
      output[0] = mGhostAxisEnabled;
162
      output[1] = computeRow(mTouchedCubit,mGhostAxisEnabled);
163 4a014840 leszek
      }
164 0c5d8bf7 Leszek Koltunski
    }
165
  }