Revision b9d4aa3b
Added by Leszek Koltunski over 4 years ago
| 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
Lots of changes :)