Revision 470820a7
Added by Leszek Koltunski over 5 years ago
| src/main/java/org/distorted/objects/Cubit.java | ||
|---|---|---|
| 27 | 27 |
import org.distorted.library.effect.MatrixEffectQuaternion; |
| 28 | 28 |
import org.distorted.library.effect.MatrixEffectRotate; |
| 29 | 29 |
import org.distorted.library.main.DistortedEffects; |
| 30 |
import org.distorted.library.main.DistortedNode; |
|
| 31 |
import org.distorted.library.mesh.MeshBase; |
|
| 32 | 30 |
import org.distorted.library.message.EffectListener; |
| 33 | 31 |
import org.distorted.library.type.Dynamic1D; |
| 34 | 32 |
import org.distorted.library.type.Static1D; |
| ... | ... | |
| 41 | 39 |
class Cubit |
| 42 | 40 |
{
|
| 43 | 41 |
private static final int POST_ROTATION_MILLISEC = 500; |
| 44 |
private static final Static3D matrCenter = new Static3D(0,0,0);
|
|
| 42 |
private static final Static3D MATRIX_CENTER = new Static3D(0,0,0);
|
|
| 45 | 43 |
|
| 46 | 44 |
private final Static3D mOrigPosition; |
| 47 | 45 |
|
| 48 | 46 |
private RubikObject mParent; |
| 49 |
private MeshBase mMesh; |
|
| 50 | 47 |
private Static3D mRotationAxis; |
| 51 | 48 |
private MatrixEffectRotate mRotateEffect; |
| 52 | 49 |
private Static3D mCurrentPosition; |
| 53 | 50 |
private int mNumAxis; |
| 54 | 51 |
private Dynamic1D mRotationAngle; |
| 55 | 52 |
|
| 56 |
DistortedNode mNode; |
|
| 57 | 53 |
DistortedEffects mEffect; |
| 58 | 54 |
Static4D mQuatScramble; |
| 59 | 55 |
float[] mRotationRow; |
| 60 | 56 |
|
| 57 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 58 |
|
|
| 59 |
Cubit(RubikObject parent, Static3D position) |
|
| 60 |
{
|
|
| 61 |
float x = position.get0(); |
|
| 62 |
float y = position.get1(); |
|
| 63 |
float z = position.get2(); |
|
| 64 |
|
|
| 65 |
Static3D vector = new Static3D(x,y,z); |
|
| 66 |
|
|
| 67 |
mParent = parent; |
|
| 68 |
mOrigPosition = new Static3D(x,y,z); |
|
| 69 |
mQuatScramble = new Static4D(0,0,0,1); |
|
| 70 |
mRotationAngle = new Dynamic1D(); |
|
| 71 |
mRotationAxis = new Static3D(1,0,0); |
|
| 72 |
mCurrentPosition = position; |
|
| 73 |
mRotateEffect = new MatrixEffectRotate(mRotationAngle, mRotationAxis, MATRIX_CENTER); |
|
| 74 |
|
|
| 75 |
mNumAxis = mParent.ROTATION_AXIS.length; |
|
| 76 |
mRotationRow = new float[mNumAxis]; |
|
| 77 |
computeRotationRow(); |
|
| 78 |
|
|
| 79 |
mEffect = new DistortedEffects(); |
|
| 80 |
mEffect.apply( new MatrixEffectMove(vector) ); |
|
| 81 |
mEffect.apply( new MatrixEffectQuaternion(mQuatScramble, MATRIX_CENTER)); |
|
| 82 |
mEffect.apply(mRotateEffect); |
|
| 83 |
mEffect.apply(mParent.mQuatAEffect); |
|
| 84 |
mEffect.apply(mParent.mQuatCEffect); |
|
| 85 |
mEffect.apply(mParent.mScaleEffect); |
|
| 86 |
} |
|
| 87 |
|
|
| 61 | 88 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 62 | 89 |
// Because of quatMultiplication, errors can accumulate - so to avoid this, we |
| 63 | 90 |
// correct the value of the 'scramble' quat to what it should be - one of the legal quats from the |
| ... | ... | |
| 163 | 190 |
} |
| 164 | 191 |
} |
| 165 | 192 |
|
| 166 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 167 |
|
|
| 168 |
Cubit(RubikObject parent, MeshBase mesh, Static3D position) |
|
| 169 |
{
|
|
| 170 |
float x = position.get0(); |
|
| 171 |
float y = position.get1(); |
|
| 172 |
float z = position.get2(); |
|
| 173 |
|
|
| 174 |
Static3D vector = new Static3D(x,y,z); |
|
| 175 |
|
|
| 176 |
mParent = parent; |
|
| 177 |
mMesh = mesh; |
|
| 178 |
mOrigPosition = new Static3D(x,y,z); |
|
| 179 |
mQuatScramble = new Static4D(0,0,0,1); |
|
| 180 |
mRotationAngle = new Dynamic1D(); |
|
| 181 |
mRotationAxis = new Static3D(1,0,0); |
|
| 182 |
mCurrentPosition = position; |
|
| 183 |
mRotateEffect = new MatrixEffectRotate(mRotationAngle, mRotationAxis, matrCenter); |
|
| 184 |
|
|
| 185 |
mNumAxis = mParent.ROTATION_AXIS.length; |
|
| 186 |
mRotationRow = new float[mNumAxis]; |
|
| 187 |
computeRotationRow(); |
|
| 188 |
|
|
| 189 |
mEffect = new DistortedEffects(); |
|
| 190 |
mEffect.apply( new MatrixEffectMove(vector) ); |
|
| 191 |
mEffect.apply( new MatrixEffectQuaternion(mQuatScramble, matrCenter)); |
|
| 192 |
mEffect.apply(mRotateEffect); |
|
| 193 |
mEffect.apply(mParent.mQuatAEffect); |
|
| 194 |
mEffect.apply(mParent.mQuatCEffect); |
|
| 195 |
mEffect.apply(mParent.mScaleEffect); |
|
| 196 |
|
|
| 197 |
mNode = new DistortedNode(mParent.mTexture,mEffect,mMesh); |
|
| 198 |
} |
|
| 199 |
|
|
| 200 | 193 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 201 | 194 |
|
| 202 | 195 |
void savePreferences(SharedPreferences.Editor editor) |
| ... | ... | |
| 357 | 350 |
} |
| 358 | 351 |
} |
| 359 | 352 |
|
| 360 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 361 |
// all DistortedTextures, DistortedNodes, DistortedFramebuffers, DistortedScreens and all types of |
|
| 362 |
// Meshes HAVE TO be markedForDeletion when they are no longer needed- otherwise we have a major |
|
| 363 |
// memory leak. |
|
| 364 |
|
|
| 365 |
void releaseResources() |
|
| 366 |
{
|
|
| 367 |
mMesh.markForDeletion(); |
|
| 368 |
mNode.markForDeletion(); |
|
| 369 |
} |
|
| 370 |
|
|
| 371 | 353 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 372 | 354 |
|
| 373 | 355 |
void solve() |
| ... | ... | |
| 395 | 377 |
|
| 396 | 378 |
return dx*dx + dy*dy + dz*dz; |
| 397 | 379 |
} |
| 398 |
|
|
| 399 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 400 |
|
|
| 401 |
int getColorIndex(int face) |
|
| 402 |
{
|
|
| 403 |
Static4D texMap = mMesh.getTextureMap(face); |
|
| 404 |
return (int)(texMap.get0() / texMap.get2()); |
|
| 405 |
} |
|
| 406 |
|
|
| 407 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 408 |
|
|
| 409 |
MeshBase getMesh() |
|
| 410 |
{
|
|
| 411 |
return mMesh; |
|
| 412 |
} |
|
| 413 | 380 |
} |
| src/main/java/org/distorted/objects/RubikCube.java | ||
|---|---|---|
| 232 | 232 |
mMesh.apply(effect12); |
| 233 | 233 |
mMesh.apply(effect13); |
| 234 | 234 |
mMesh.apply(effect14); |
| 235 |
|
|
| 236 |
mMesh.mergeEffComponents(); |
|
| 235 | 237 |
} |
| 236 | 238 |
|
| 237 |
return mMesh.copy(false);
|
|
| 239 |
return mMesh.copy(true);
|
|
| 238 | 240 |
} |
| 239 | 241 |
|
| 240 | 242 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| src/main/java/org/distorted/objects/RubikObject.java | ||
|---|---|---|
| 25 | 25 |
import android.graphics.Paint; |
| 26 | 26 |
|
| 27 | 27 |
import org.distorted.library.effect.Effect; |
| 28 |
import org.distorted.library.effect.MatrixEffectMove; |
|
| 28 | 29 |
import org.distorted.library.effect.MatrixEffectQuaternion; |
| 29 | 30 |
import org.distorted.library.effect.MatrixEffectScale; |
| 30 | 31 |
import org.distorted.library.main.DistortedEffects; |
| 31 | 32 |
import org.distorted.library.main.DistortedNode; |
| 32 | 33 |
import org.distorted.library.main.DistortedTexture; |
| 33 | 34 |
import org.distorted.library.mesh.MeshBase; |
| 35 |
import org.distorted.library.mesh.MeshJoined; |
|
| 34 | 36 |
import org.distorted.library.mesh.MeshRectangles; |
| 35 | 37 |
import org.distorted.library.message.EffectListener; |
| 36 | 38 |
import org.distorted.library.type.Static1D; |
| ... | ... | |
| 47 | 49 |
private static final int TEXTURE_HEIGHT = 128; |
| 48 | 50 |
final float[] LEGAL_QUATS; |
| 49 | 51 |
final Static3D[] ROTATION_AXIS; |
| 52 |
final int NUM_FACES; |
|
| 50 | 53 |
|
| 51 | 54 |
static float OBJECT_SCREEN_RATIO; |
| 52 | 55 |
|
| ... | ... | |
| 59 | 62 |
private Cubit[] mCubits; |
| 60 | 63 |
private int mSize; |
| 61 | 64 |
private RubikObjectList mList; |
| 65 |
private MeshBase mMesh; |
|
| 66 |
private DistortedEffects mEffects; |
|
| 62 | 67 |
|
| 63 | 68 |
float mStart, mStep; |
| 64 | 69 |
|
| ... | ... | |
| 85 | 90 |
NUM_CUBITS = mOrigPos.length; |
| 86 | 91 |
ROTATION_AXIS = getRotationAxis(); |
| 87 | 92 |
OBJECT_SCREEN_RATIO = getScreenRatio(); |
| 93 |
NUM_FACES = getNumFaces(); |
|
| 88 | 94 |
|
| 89 | 95 |
mSize = size; |
| 90 | 96 |
computeStartAndStep(mOrigPos); |
| ... | ... | |
| 106 | 112 |
|
| 107 | 113 |
mCubits = new Cubit[NUM_CUBITS]; |
| 108 | 114 |
mTexture = new DistortedTexture(); |
| 115 |
MeshBase[] cubitMesh = new MeshBase[NUM_CUBITS]; |
|
| 109 | 116 |
|
| 110 | 117 |
for(int i=0; i<NUM_CUBITS; i++) |
| 111 | 118 |
{
|
| 112 |
MeshBase cubitMesh = createCubitMesh(i); |
|
| 113 |
mCubits[i] = new Cubit(this,cubitMesh,mOrigPos[i]); |
|
| 114 |
textureCubitMesh(cubitMesh,i); |
|
| 115 |
|
|
| 116 |
attach(mCubits[i].mNode); |
|
| 119 |
cubitMesh[i] = createCubitMesh(i); |
|
| 120 |
cubitMesh[i].apply(new MatrixEffectMove(mOrigPos[i]),1,0); |
|
| 121 |
mCubits[i] = new Cubit(this,mOrigPos[i]); |
|
| 117 | 122 |
} |
| 118 | 123 |
|
| 124 |
mMesh = new MeshJoined(cubitMesh); |
|
| 125 |
|
|
| 126 |
resetAllTextureMaps(); |
|
| 127 |
|
|
| 128 |
mEffects = new DistortedEffects(); |
|
| 129 |
mEffects.apply(mQuatAEffect); |
|
| 130 |
mEffects.apply(mQuatCEffect); |
|
| 131 |
mEffects.apply(mScaleEffect); |
|
| 132 |
|
|
| 133 |
attach( new DistortedNode(mTexture,mEffects,mMesh) ); |
|
| 134 |
|
|
| 119 | 135 |
setupPosition(moves); |
| 120 | 136 |
|
| 121 | 137 |
setProjection(fov, 0.1f); |
| ... | ... | |
| 126 | 142 |
private void textureCubitMesh(MeshBase mesh, int cubit) |
| 127 | 143 |
{
|
| 128 | 144 |
boolean belongs; |
| 129 |
final int numFaces = getNumFaces(); |
|
| 130 |
final Static4D[] maps = new Static4D[numFaces]; |
|
| 131 |
final float ratio = 1.0f/(numFaces+1); |
|
| 145 |
final Static4D[] maps = new Static4D[NUM_FACES]; |
|
| 146 |
final float ratio = 1.0f/(NUM_FACES+1); |
|
| 132 | 147 |
|
| 133 |
if( 2*ROTATION_AXIS.length == numFaces ) // i.e. there are faces on both ends of the axis (cube)
|
|
| 148 |
if( 2*ROTATION_AXIS.length == NUM_FACES ) // i.e. there are faces on both ends of the axis (cube)
|
|
| 134 | 149 |
{
|
| 135 |
for(int i=0; i<numFaces; i++)
|
|
| 150 |
for(int i=0; i<NUM_FACES; i++)
|
|
| 136 | 151 |
{
|
| 137 | 152 |
belongs = isOnFace(cubit, i/2, i%2==0 ? mSize-1:0 ); |
| 138 |
maps[i] = new Static4D( (belongs?i:6)*ratio, 0.0f, ratio, 1.0f);
|
|
| 153 |
maps[i] = new Static4D( (belongs?i:NUM_FACES)*ratio, 0.0f, ratio, 1.0f);
|
|
| 139 | 154 |
} |
| 140 | 155 |
} |
| 141 |
else if( ROTATION_AXIS.length == numFaces ) // just a single face on the right end of an axis (pyraminx)
|
|
| 156 |
else if( ROTATION_AXIS.length == NUM_FACES ) // just a single face on the right end of an axis (pyraminx)
|
|
| 142 | 157 |
{
|
| 143 |
for(int i=0; i<numFaces; i++)
|
|
| 158 |
for(int i=0; i<NUM_FACES; i++)
|
|
| 144 | 159 |
{
|
| 145 | 160 |
belongs = isOnFace(cubit, i, 0 ); |
| 146 |
maps[i] = new Static4D( (belongs?i:6)*ratio, 0.0f, ratio, 1.0f);
|
|
| 161 |
maps[i] = new Static4D( (belongs?i:NUM_FACES)*ratio, 0.0f, ratio, 1.0f);
|
|
| 147 | 162 |
} |
| 148 | 163 |
} |
| 149 | 164 |
|
| 150 |
mesh.setTextureMap(maps); |
|
| 165 |
mesh.setTextureMap(maps,NUM_FACES*cubit);
|
|
| 151 | 166 |
} |
| 152 | 167 |
|
| 153 | 168 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 246 | 261 |
|
| 247 | 262 |
int getCubitFaceColorIndex(int cubit, int face) |
| 248 | 263 |
{
|
| 249 |
return mCubits[cubit].getColorIndex(face); |
|
| 264 |
Static4D texMap = mMesh.getTextureMap(NUM_FACES*cubit + face); |
|
| 265 |
return (int)(texMap.get0() / texMap.get2()); |
|
| 250 | 266 |
} |
| 251 | 267 |
|
| 252 | 268 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 286 | 302 |
{
|
| 287 | 303 |
Bitmap bitmap; |
| 288 | 304 |
|
| 289 |
final int numColors = getNumFaces(); |
|
| 290 |
|
|
| 291 | 305 |
Paint paint = new Paint(); |
| 292 |
bitmap = Bitmap.createBitmap( (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
|
|
| 306 |
bitmap = Bitmap.createBitmap( (NUM_FACES+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
|
|
| 293 | 307 |
Canvas canvas = new Canvas(bitmap); |
| 294 | 308 |
|
| 295 | 309 |
paint.setAntiAlias(true); |
| ... | ... | |
| 297 | 311 |
paint.setStyle(Paint.Style.FILL); |
| 298 | 312 |
|
| 299 | 313 |
paint.setColor(INTERIOR_COLOR); |
| 300 |
canvas.drawRect(0, 0, (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, paint);
|
|
| 314 |
canvas.drawRect(0, 0, (NUM_FACES+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, paint);
|
|
| 301 | 315 |
|
| 302 |
for(int i=0; i<numColors; i++)
|
|
| 316 |
for(int i=0; i<NUM_FACES; i++)
|
|
| 303 | 317 |
{
|
| 304 | 318 |
createFaceTexture(canvas, paint, i, i*TEXTURE_HEIGHT, 0, TEXTURE_HEIGHT); |
| 305 | 319 |
} |
| ... | ... | |
| 356 | 370 |
{
|
| 357 | 371 |
mTexture.markForDeletion(); |
| 358 | 372 |
|
| 359 |
for(int i=0; i<NUM_CUBITS; i++) mCubits[i].releaseResources();
|
|
| 373 |
// TODO ?
|
|
| 360 | 374 |
} |
| 361 | 375 |
|
| 362 | 376 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 400 | 414 |
{
|
| 401 | 415 |
for(int i=0; i<NUM_CUBITS; i++) |
| 402 | 416 |
{
|
| 403 |
textureCubitMesh( mCubits[i].getMesh() , i );
|
|
| 417 |
textureCubitMesh( mMesh , i );
|
|
| 404 | 418 |
} |
| 405 | 419 |
} |
| 406 | 420 |
|
| ... | ... | |
| 408 | 422 |
|
| 409 | 423 |
public void setTextureMap(int cubit, int face, int newColor) |
| 410 | 424 |
{
|
| 411 |
final int numFaces = getNumFaces(); |
|
| 412 |
final float ratio = 1.0f/(numFaces+1); |
|
| 413 |
final Static4D[] maps = new Static4D[numFaces]; |
|
| 425 |
final float ratio = 1.0f/(NUM_FACES+1); |
|
| 426 |
final Static4D[] maps = new Static4D[NUM_FACES]; |
|
| 414 | 427 |
|
| 415 | 428 |
try |
| 416 | 429 |
{
|
| 417 | 430 |
maps[face] = new Static4D( newColor*ratio, 0.0f, ratio, 1.0f); |
| 418 |
mCubits[cubit].getMesh().setTextureMap(maps);
|
|
| 431 |
mMesh.setTextureMap(maps,NUM_FACES*cubit);
|
|
| 419 | 432 |
} |
| 420 | 433 |
catch(ArrayIndexOutOfBoundsException ignored) |
| 421 | 434 |
{
|
| src/main/java/org/distorted/objects/RubikPyraminx.java | ||
|---|---|---|
| 225 | 225 |
meshes[i].setEffectAssociation(0,association,0); |
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 |
Static4D[] textureMaps = new Static4D[MESHES]; |
|
| 229 |
for(int i=0; i<MESHES; i++) textureMaps[i] = new Static4D(i*0.25f,0.0f,0.25f,1.0f); |
|
| 230 | 228 |
MeshBase result = new MeshJoined(meshes); |
| 231 |
result.setTextureMap(textureMaps); |
|
| 232 | 229 |
|
| 233 | 230 |
Static3D a0 = new Static3D( 0, 1, 0 ); |
| 234 | 231 |
Static3D a1 = new Static3D( 0, -1.0f/3, 2*SQ2/3 ); |
| ... | ... | |
| 301 | 298 |
result.apply( ROTATION[mRotArray[cubit]] ); |
| 302 | 299 |
} |
| 303 | 300 |
|
| 301 |
result.mergeEffComponents(); |
|
| 302 |
|
|
| 304 | 303 |
return result; |
| 305 | 304 |
} |
| 306 | 305 |
|
| ... | ... | |
| 313 | 312 |
if( kind>=0 ) |
| 314 | 313 |
{
|
| 315 | 314 |
if( mMeshRotated[kind]==null ) mMeshRotated[kind] = createStaticMesh(cubit); |
| 316 |
return mMeshRotated[kind].copy(false);
|
|
| 315 |
return mMeshRotated[kind].copy(true);
|
|
| 317 | 316 |
} |
| 318 | 317 |
else |
| 319 | 318 |
{
|
| 320 | 319 |
if( mMesh==null ) mMesh = createStaticMesh(cubit); |
| 321 |
return mMesh.copy(false);
|
|
| 320 |
return mMesh.copy(true);
|
|
| 322 | 321 |
} |
| 323 | 322 |
} |
| 324 | 323 |
|
Also available in: Unified diff
Begin porting RubikCube to the new SingleMesh library. This will make rendering much faster - e.g. in case of Cube 5, instead of 98 renders of individual Cubits, there will be one render of the whole Mesh.