Revision f404152d
Added by Leszek Koltunski over 1 year ago
src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java | ||
---|---|---|
20 | 20 |
import javax.microedition.khronos.opengles.GL10; |
21 | 21 |
|
22 | 22 |
import android.app.Activity; |
23 |
import android.app.ActivityManager; |
|
24 |
import android.content.Context; |
|
25 |
import android.content.pm.ConfigurationInfo; |
|
26 | 23 |
import android.content.res.Resources; |
27 | 24 |
import android.opengl.GLES31; |
28 | 25 |
import android.opengl.GLSurfaceView; |
... | ... | |
43 | 40 |
import org.distorted.library.type.Static3D; |
44 | 41 |
import org.distorted.library.type.Static4D; |
45 | 42 |
import org.distorted.objectlib.json.JsonWriter; |
46 |
import org.distorted.objectlib.main.InitData; |
|
47 |
import org.distorted.objectlib.shape.ShapeHexahedron; |
|
48 | 43 |
import org.distorted.objectlib.main.TwistyObject; |
49 |
import org.distorted.objectlib.objects.TwistyBandagedCuboid; |
|
44 |
|
|
50 | 45 |
import org.json.JSONException; |
51 | 46 |
|
52 | 47 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
64 | 59 |
private final DistortedScreen mScreen; |
65 | 60 |
private final Static3D mScale; |
66 | 61 |
private final Static4D mQuatT, mQuatA; |
67 |
private final int[] mObjSize;
|
|
62 |
private final BandagedObject mObject;
|
|
68 | 63 |
|
69 |
private BandagedCubit[] mCubits; |
|
70 | 64 |
private boolean mInitialPhase; |
71 | 65 |
private long mStartTime; |
72 | 66 |
private float mQuatX, mQuatY, mQuatZ, mQuatW; |
73 |
private int mX, mY, mZ, mNumCubits; |
|
74 | 67 |
private boolean mResetQuats, mSetQuatT, mResettingObject, mConnectingCubits, mCreatingCubits, mRescaling; |
75 | 68 |
private int mIndex1, mIndex2; |
76 | 69 |
private int mSaveIcon; |
... | ... | |
100 | 93 |
|
101 | 94 |
mObjectScreenRatio= INIT_RATIO; |
102 | 95 |
mSaveIcon = -1; |
103 |
mObjSize = new int[3]; |
|
104 | 96 |
|
105 | 97 |
mScreen = new DistortedScreen(); |
106 | 98 |
mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f); |
107 | 99 |
mScale = new Static3D(1,1,1); |
108 |
} |
|
109 |
|
|
110 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
111 |
|
|
112 |
private boolean isAdjacent(float[] pos1, float[] pos2) |
|
113 |
{ |
|
114 |
int len1 = pos1.length/3; |
|
115 |
int len2 = pos2.length/3; |
|
116 |
|
|
117 |
for(int i=0; i<len1; i++) |
|
118 |
for(int j=0; j<len2; j++) |
|
119 |
{ |
|
120 |
float d0 = pos1[3*i ] - pos2[3*j ]; |
|
121 |
float d1 = pos1[3*i+1] - pos2[3*j+1]; |
|
122 |
float d2 = pos1[3*i+2] - pos2[3*j+2]; |
|
123 |
|
|
124 |
if( d0*d0 + d1*d1 + d2*d2 == 1 ) return true; |
|
125 |
} |
|
126 |
|
|
127 |
return false; |
|
128 |
} |
|
129 |
|
|
130 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
131 |
|
|
132 |
private int computeNumCubits(int x, int y, int z) |
|
133 |
{ |
|
134 |
return ( x<=1 || y<=1 || z<=1 ) ? x*y*z : x*y*z-(x-2)*(y-2)*(z-2); |
|
135 |
} |
|
136 |
|
|
137 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
138 |
|
|
139 |
private void createCubits() |
|
140 |
{ |
|
141 |
mCubits = new BandagedCubit[mNumCubits]; |
|
142 |
int c=0; |
|
143 |
|
|
144 |
float begX = 0.5f*(1-mX); |
|
145 |
float begY = 0.5f*(1-mY); |
|
146 |
float begZ = 0.5f*(1-mZ); |
|
147 |
|
|
148 |
for(int x=0; x<mX; x++) |
|
149 |
for(int y=0; y<mY; y++) |
|
150 |
for(int z=0; z<mZ; z++) |
|
151 |
if( x==0 || x==mX-1 || y==0 || y==mY-1 || z==0 || z==mZ-1 ) |
|
152 |
{ |
|
153 |
float[] pos = new float[] { begX+x,begY+y,begZ+z }; |
|
154 |
mCubits[c] = new BandagedCubit(pos,mX,mY,mZ,mQuatT,mQuatA,mScale,false); |
|
155 |
c++; |
|
156 |
} |
|
157 |
|
|
158 |
mView.setCubits(mCubits,mX,mY,mZ); |
|
159 |
} |
|
160 |
|
|
161 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
162 |
|
|
163 |
private void resetObject() |
|
164 |
{ |
|
165 |
mView.resetCubits(); |
|
166 |
|
|
167 |
for(int c=0; c<mNumCubits; c++) |
|
168 |
{ |
|
169 |
if( !mCubits[c].isAttached() ) |
|
170 |
{ |
|
171 |
mCubits[c].attach(); |
|
172 |
mScreen.attach(mCubits[c].getNode()); |
|
173 |
} |
|
174 |
if( mCubits[c].getPosition().length>3 ) |
|
175 |
{ |
|
176 |
mCubits[c].reset(mScaleValue); |
|
177 |
} |
|
178 |
mCubits[c].setUnmarked(); |
|
179 |
} |
|
100 |
mObject = new BandagedObject(mScreen); |
|
180 | 101 |
} |
181 | 102 |
|
182 | 103 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
236 | 157 |
if( mConnectingCubits ) |
237 | 158 |
{ |
238 | 159 |
mConnectingCubits = false; |
239 |
tryConnectingCubits(mIndex1,mIndex2);
|
|
160 |
mObject.tryConnectingCubits(mIndex1,mIndex2,mScaleValue);
|
|
240 | 161 |
} |
241 | 162 |
|
242 | 163 |
if( mCreatingCubits ) |
243 | 164 |
{ |
244 | 165 |
mCreatingCubits = false; |
245 |
|
|
246 | 166 |
rescaleObject(); |
247 | 167 |
|
248 | 168 |
if( mCubitsCreated ) |
249 | 169 |
{ |
250 |
createCubits(); |
|
251 |
|
|
170 |
mObject.createCubits(mQuatT,mQuatA,mScale); |
|
171 |
float[] dist = mObject.getDist3D(); |
|
172 |
BandagedCreatorTouchControl control = mView.getTouchControl(); |
|
173 |
control.setDist3D(dist); |
|
252 | 174 |
mScreen.detachAll(); |
253 | 175 |
mView.resetCubits(); |
254 |
|
|
255 |
for(int i=0; i<mNumCubits; i++) |
|
256 |
{ |
|
257 |
mCubits[i].scaleMove(mScaleValue); |
|
258 |
DistortedNode node = mCubits[i].getNode(); |
|
259 |
mScreen.attach(node); |
|
260 |
} |
|
176 |
mObject.attachCubits(mScaleValue); |
|
261 | 177 |
} |
262 | 178 |
} |
263 | 179 |
|
... | ... | |
265 | 181 |
{ |
266 | 182 |
mRescaling = false; |
267 | 183 |
rescaleObject(); |
268 |
for(int i=0; i<mNumCubits; i++) mCubits[i].scaleMove(mScaleValue);
|
|
184 |
mObject.scaleCubits(mScaleValue);
|
|
269 | 185 |
BandagedCreatorTouchControl control = mView.getTouchControl(); |
270 | 186 |
control.setObjectRatio(mObjectScreenRatio); |
271 | 187 |
} |
... | ... | |
281 | 197 |
mWidth = width; |
282 | 198 |
mHeight= height; |
283 | 199 |
rescaleObject(); |
284 |
|
|
285 | 200 |
mScreen.detachAll(); |
286 | 201 |
int touched = mView.getTouched(); |
287 |
|
|
288 |
for(int i=0; i<mNumCubits; i++) |
|
289 |
if( mCubits[i].isAttached() ) |
|
290 |
{ |
|
291 |
mCubits[i].scaleMove(mScaleValue); |
|
292 |
if( touched==i ) mCubits[i].setMarked(); |
|
293 |
else mCubits[i].setUnmarked(); |
|
294 |
DistortedNode node = mCubits[i].getNode(); |
|
295 |
mScreen.attach(node); |
|
296 |
} |
|
297 |
|
|
202 |
mObject.attachAndMarkCubits(mScaleValue,touched); |
|
298 | 203 |
mView.setScreenSize(width,height); |
299 | 204 |
mScreen.resize(width,height); |
300 | 205 |
} |
... | ... | |
306 | 211 |
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) |
307 | 212 |
{ |
308 | 213 |
DistortedLibrary.setMax(EffectType.VERTEX,0); |
309 |
MeshBase.setMaxEffComponents(120); |
|
310 |
|
|
214 |
MeshBase.setMaxEffComponents(120); // what? |
|
311 | 215 |
FragmentEffectBrightness.enable(); |
312 |
|
|
313 | 216 |
DistortedLibrary.onSurfaceCreated(this,1); |
314 | 217 |
DistortedLibrary.setCull(true); |
315 |
|
|
316 |
if( mCubits==null ) |
|
317 |
{ |
|
318 |
createCubits(); |
|
319 |
} |
|
320 |
else |
|
321 |
{ |
|
322 |
for(int i=0; i<mNumCubits; i++) mCubits[i].recreateBitmap(); |
|
323 |
} |
|
324 |
|
|
218 |
mObject.recreateCubits(mQuatT,mQuatA,mScale); |
|
325 | 219 |
mCubitsCreated = true; |
326 | 220 |
mWidth = 0; |
327 | 221 |
mHeight= 0; |
... | ... | |
343 | 237 |
mConnectingCubits = true; |
344 | 238 |
} |
345 | 239 |
|
346 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
347 |
|
|
348 |
private void tryConnectingCubits(int index1, int index2) |
|
349 |
{ |
|
350 |
if( index1!=index2 ) |
|
351 |
{ |
|
352 |
float[] pos1 = mCubits[index1].getPosition(); |
|
353 |
float[] pos2 = mCubits[index2].getPosition(); |
|
354 |
|
|
355 |
if( isAdjacent(pos1,pos2) ) |
|
356 |
{ |
|
357 |
mCubits[index2].join(pos1,mScaleValue); |
|
358 |
mCubits[index1].detach(); |
|
359 |
mScreen.detach(mCubits[index1].getNode()); |
|
360 |
} |
|
361 |
} |
|
362 |
} |
|
363 |
|
|
364 | 240 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
365 | 241 |
|
366 | 242 |
public Static4D getQuatAccu() |
... | ... | |
400 | 276 |
|
401 | 277 |
public void saveObject() |
402 | 278 |
{ |
403 |
int numAttached=0; |
|
404 |
|
|
405 |
for(int i=0; i<mNumCubits; i++) |
|
406 |
if( mCubits[i].isAttached() ) numAttached++; |
|
407 |
|
|
408 |
float[][] pos = new float[numAttached][]; |
|
409 |
int attached=0; |
|
410 |
|
|
411 |
for(int i=0; i<mNumCubits; i++) |
|
412 |
if( mCubits[i].isAttached() ) |
|
413 |
{ |
|
414 |
pos[attached++] = mCubits[i].getPosition(); |
|
415 |
} |
|
416 |
|
|
417 |
InitData data = new InitData(mObjSize,pos); |
|
418 |
TwistyObject obj = new TwistyBandagedCuboid( TwistyObject.MESH_NICE, TwistyObject.MODE_NORM, |
|
419 |
new Static4D(0,0,0,1), new Static3D(0,0,0), 1.0f, data, null ); |
|
279 |
TwistyObject obj = mObject.createObject(TwistyObject.MODE_NORM, 1.0f ); |
|
420 | 280 |
String name = obj.getShortName(); |
421 | 281 |
BandagedCreatorActivity act = (BandagedCreatorActivity) mView.getContext(); |
422 | 282 |
|
423 | 283 |
if( act.objectDoesntExist(name) && createObjectJson(obj,act) ) |
424 | 284 |
{ |
425 |
setupIconCreation(act,data);
|
|
285 |
setupIconCreation(act); |
|
426 | 286 |
act.addObject(obj.getShortName()); |
427 | 287 |
} |
428 | 288 |
} |
... | ... | |
485 | 345 |
|
486 | 346 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
487 | 347 |
|
488 |
private int computeProjectionAngle() |
|
489 |
{ |
|
490 |
float quot1 = mObjSize[2]/ (float)mObjSize[0]; |
|
491 |
float quot2 = mObjSize[2]/ (float)mObjSize[1]; |
|
492 |
float quot3 = mObjSize[0]/ (float)mObjSize[2]; |
|
493 |
float quot4 = mObjSize[0]/ (float)mObjSize[1]; |
|
494 |
|
|
495 |
float quot5 = Math.max(quot1,quot2); |
|
496 |
float quot6 = Math.max(quot3,quot4); |
|
497 |
float quot7 = Math.max(quot5,quot6); |
|
498 |
|
|
499 |
if( quot7<=1.0f ) return 120; |
|
500 |
else if( quot7<=1.5f ) return 90; |
|
501 |
else if( quot7<=2.0f ) return 60; |
|
502 |
else return 30; |
|
503 |
} |
|
504 |
|
|
505 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
506 |
|
|
507 |
private void setupIconCreation(Activity act, InitData data) |
|
348 |
private void setupIconCreation(Activity act) |
|
508 | 349 |
{ |
509 | 350 |
final float R=1.0f; |
510 | 351 |
final int FBO_WIDTH = (int)(R*720); |
511 | 352 |
final int FBO_HEIGHT = (int)(R*1280); |
512 | 353 |
final float OBJECT_SIZE = R*0.35f; |
513 | 354 |
|
514 |
TwistyObject obj = new TwistyBandagedCuboid( TwistyObject.MESH_NICE, TwistyObject.MODE_ICON, |
|
515 |
ShapeHexahedron.DEFAULT_ROT, new Static3D(0,0,0), OBJECT_SIZE, data, null ); |
|
516 |
|
|
355 |
TwistyObject obj = mObject.createObject(TwistyObject.MODE_ICON, OBJECT_SIZE ); |
|
517 | 356 |
DistortedEffects effects = obj.getObjectEffects(); |
518 | 357 |
DistortedNode node = obj.getNode(); |
519 | 358 |
|
... | ... | |
523 | 362 |
mFramebuffer.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f); |
524 | 363 |
} |
525 | 364 |
|
526 |
mFramebuffer.setProjection( computeProjectionAngle() ,0.1f); |
|
365 |
mFramebuffer.setProjection( mObject.computeProjectionAngle() ,0.1f);
|
|
527 | 366 |
mFramebuffer.detachAll(); |
528 | 367 |
mFramebuffer.attach(node); |
529 | 368 |
|
... | ... | |
590 | 429 |
|
591 | 430 |
private void rescaleObject() |
592 | 431 |
{ |
593 |
final int size = mX>mY ? Math.max(mX, mZ) : Math.max(mY, mZ);
|
|
432 |
float size = mObject.getSize();
|
|
594 | 433 |
final float Q = mObjectScreenRatio/size; |
595 | 434 |
mScaleValue = mWidth<mHeight ? Q*mWidth : Q*mHeight; |
596 | 435 |
mScale.set( mScaleValue,mScaleValue,mScaleValue ); |
... | ... | |
600 | 439 |
|
601 | 440 |
public void changeObject(int x, int y, int z) |
602 | 441 |
{ |
603 |
if( mX!=x || mY!=y || mZ!=z ) |
|
604 |
{ |
|
605 |
mX = x; |
|
606 |
mY = y; |
|
607 |
mZ = z; |
|
608 |
|
|
609 |
mObjSize[0] = mX; |
|
610 |
mObjSize[1] = mY; |
|
611 |
mObjSize[2] = mZ; |
|
612 |
|
|
613 |
mNumCubits = computeNumCubits(mX,mY,mZ); |
|
614 |
|
|
615 |
mCreatingCubits = true; |
|
616 |
} |
|
442 |
if( mObject.tryChangeObject(x,y,z) ) mCreatingCubits = true; |
|
617 | 443 |
} |
618 | 444 |
|
619 | 445 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
644 | 470 |
if( mInitialPhase && quotient>0.5f ) |
645 | 471 |
{ |
646 | 472 |
mInitialPhase=false; |
647 |
resetObject(); |
|
473 |
mView.resetCubits(); |
|
474 |
mObject.resetObject(mScaleValue); |
|
648 | 475 |
} |
649 | 476 |
|
650 | 477 |
double angle = 2*Math.PI*quotient*quotient*(3-2*quotient); |
... | ... | |
661 | 488 |
|
662 | 489 |
public void touchCubit(int index) |
663 | 490 |
{ |
664 |
if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setMarked();
|
|
491 |
mObject.touchCubit(index);
|
|
665 | 492 |
} |
666 | 493 |
|
667 | 494 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
668 | 495 |
|
669 | 496 |
public void untouchCubit(int index) |
670 | 497 |
{ |
671 |
if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setUnmarked(); |
|
498 |
mObject.untouchCubit(index); |
|
499 |
} |
|
500 |
|
|
501 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
502 |
|
|
503 |
public BandagedCreatorTouchControl createTouchControl() |
|
504 |
{ |
|
505 |
return new BandagedCreatorTouchControl( getObjectRatio() , mScreen.getFOV(), mObject ); |
|
672 | 506 |
} |
673 | 507 |
|
674 | 508 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
src/main/java/org/distorted/bandaged/BandagedCreatorScreen.java | ||
---|---|---|
12 | 12 |
import java.lang.ref.WeakReference; |
13 | 13 |
import java.util.ArrayList; |
14 | 14 |
|
15 |
import android.annotation.SuppressLint; |
|
15 | 16 |
import android.app.Activity; |
16 | 17 |
import android.content.SharedPreferences; |
17 | 18 |
import android.graphics.Bitmap; |
... | ... | |
124 | 125 |
return ret; |
125 | 126 |
} |
126 | 127 |
|
127 |
|
|
128 | 128 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
129 | 129 |
|
130 | 130 |
private void changeObject() |
... | ... | |
319 | 319 |
|
320 | 320 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
321 | 321 |
|
322 |
@SuppressLint("SuspiciousIndentation") |
|
322 | 323 |
@Override |
323 | 324 |
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) |
324 | 325 |
{ |
src/main/java/org/distorted/bandaged/BandagedCreatorTouchControl.java | ||
---|---|---|
12 | 12 |
import org.distorted.library.helpers.QuatHelper; |
13 | 13 |
import org.distorted.library.type.Static3D; |
14 | 14 |
import org.distorted.library.type.Static4D; |
15 |
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron; |
|
16 | 15 |
|
17 | 16 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
18 | 17 |
|
19 | 18 |
public class BandagedCreatorTouchControl |
20 | 19 |
{ |
21 |
private static final float DIST2D = 0.5f; |
|
22 |
|
|
20 |
private final BandagedObject mObject; |
|
23 | 21 |
private final Static4D CAMERA_POINT; |
24 |
private final float[] mPoint, mCamera, mTouch, mPos;
|
|
22 |
private final float[] mPoint, mCamera, mTouch; |
|
25 | 23 |
private final float[] mPoint2D; |
26 | 24 |
private float mObjectRatio; |
27 | 25 |
private final Static3D[] mFaceAxis; |
28 |
private final float[] mDist3D; |
|
29 | 26 |
|
30 |
private BandagedCubit[] mCubits; |
|
31 |
private int mNumCubits; |
|
27 |
private float[] mDist3D; |
|
32 | 28 |
private int mLastTouchedFace; |
33 |
private float mX, mY, mZ, mMax; |
|
34 |
|
|
35 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
36 |
|
|
37 |
private boolean isInsideFace(int face, float[] p) |
|
38 |
{ |
|
39 |
return ( p[0]<=DIST2D && p[0]>=-DIST2D && p[1]<=DIST2D && p[1]>=-DIST2D ); |
|
40 |
} |
|
41 | 29 |
|
42 | 30 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
43 | 31 |
// Convert the 3D point3D into a 2D point on the same face surface, but in a different |
... | ... | |
118 | 106 |
} |
119 | 107 |
} |
120 | 108 |
|
121 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
122 |
|
|
123 |
private void stretchPoint(int face, float[] output) |
|
124 |
{ |
|
125 |
switch(face/2) |
|
126 |
{ |
|
127 |
case 0: output[0] *= (mMax/mZ); output[1] *= (mMax/mY); break; |
|
128 |
case 1: output[0] *= (mMax/mX); output[1] *= (mMax/mZ); break; |
|
129 |
case 2: output[0] *= (mMax/mX); output[1] *= (mMax/mY); break; |
|
130 |
} |
|
131 |
} |
|
132 |
|
|
133 | 109 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
134 | 110 |
|
135 | 111 |
private boolean faceIsVisible(int face) |
... | ... | |
162 | 138 |
float az = mFaceAxis[mLastTouchedFace].get2(); |
163 | 139 |
|
164 | 140 |
convertTo2Dcoords(mTouch, ax,ay,az, mPoint2D); |
165 |
stretchPoint(mLastTouchedFace,mPoint2D); |
|
166 |
if( isInsideFace(mLastTouchedFace,mPoint2D) ) return true; |
|
141 |
mObject.stretchPoint(mLastTouchedFace,mPoint2D);
|
|
142 |
if( mObject.isInsideFace(mLastTouchedFace,mPoint2D) ) return true;
|
|
167 | 143 |
} |
168 | 144 |
} |
169 | 145 |
|
170 | 146 |
return false; |
171 | 147 |
} |
172 | 148 |
|
173 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
174 |
|
|
175 |
private void computePosition(int face, float pointX, float pointY) |
|
176 |
{ |
|
177 |
switch(face) |
|
178 |
{ |
|
179 |
case 0: mPos[0] = (mX-1)/2; |
|
180 |
mPos[1] = (int)(+mY*pointY+mY/2)-(mY-1)/2; |
|
181 |
mPos[2] = (int)(-mZ*pointX-mZ/2)+(mZ-1)/2; |
|
182 |
break; |
|
183 |
case 1: mPos[0] =-(mX-1)/2; |
|
184 |
mPos[1] = (int)(+mY*pointY+mY/2)-(mY-1)/2; |
|
185 |
mPos[2] = (int)(+mZ*pointX+mZ/2)-(mZ-1)/2; |
|
186 |
break; |
|
187 |
case 2: mPos[0] = (int)(+mX*pointX+mX/2)-(mX-1)/2; |
|
188 |
mPos[1] = (mY-1)/2; |
|
189 |
mPos[2] = (int)(-mZ*pointY-mZ/2)+(mZ-1)/2; |
|
190 |
break; |
|
191 |
case 3: mPos[0] = (int)(+mX*pointX+mX/2)-(mX-1)/2; |
|
192 |
mPos[1] =-(mY-1)/2; |
|
193 |
mPos[2] = (int)(+mZ*pointY+mZ/2)-(mZ-1)/2; |
|
194 |
break; |
|
195 |
case 4: mPos[0] = (int)(+mX*pointX+mX/2)-(mX-1)/2; |
|
196 |
mPos[1] = (int)(+mY*pointY+mY/2)-(mY-1)/2; |
|
197 |
mPos[2] = (mZ-1)/2; |
|
198 |
break; |
|
199 |
case 5: mPos[0] = (int)(-mX*pointX-mX/2)+(mX-1)/2; |
|
200 |
mPos[1] = (int)(+mY*pointY+mY/2)-(mY-1)/2; |
|
201 |
mPos[2] =-(mZ-1)/2; |
|
202 |
break; |
|
203 |
} |
|
204 |
} |
|
205 |
|
|
206 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
207 |
|
|
208 |
private int whichCubitTouched(int face, float pointX, float pointY) |
|
209 |
{ |
|
210 |
computePosition(face,pointX,pointY); |
|
211 |
|
|
212 |
for(int c=0; c<mNumCubits; c++) |
|
213 |
if( mCubits[c].isAttached() ) |
|
214 |
{ |
|
215 |
float[] pos = mCubits[c].getPosition(); |
|
216 |
int len = pos.length/3; |
|
217 |
|
|
218 |
for(int p=0; p<len; p++) |
|
219 |
if( pos[3*p]==mPos[0] && pos[3*p+1]==mPos[1] && pos[3*p+2]==mPos[2] ) return c; |
|
220 |
} |
|
221 |
|
|
222 |
android.util.Log.e("D", "whichCubitTouched: IMPOSSIBLE!!"); |
|
223 |
return -1; |
|
224 |
} |
|
225 |
|
|
226 | 149 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
227 | 150 |
// PUBLIC API |
228 | 151 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
229 | 152 |
|
230 |
public BandagedCreatorTouchControl(float ratio, float fov) |
|
153 |
public BandagedCreatorTouchControl(float ratio, float fov, BandagedObject object)
|
|
231 | 154 |
{ |
155 |
mObject = object; |
|
232 | 156 |
mPoint = new float[3]; |
233 | 157 |
mCamera= new float[3]; |
234 | 158 |
mTouch = new float[3]; |
235 |
mPos = new float[3]; |
|
236 | 159 |
mPoint2D = new float[2]; |
237 | 160 |
mDist3D = new float[6]; |
238 |
mFaceAxis = TouchControlHexahedron.FACE_AXIS;
|
|
161 |
mFaceAxis = mObject.getFaceAxis();
|
|
239 | 162 |
mObjectRatio = ratio; |
240 | 163 |
|
241 | 164 |
double halfFOV = fov * (Math.PI/360); |
... | ... | |
247 | 170 |
|
248 | 171 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
249 | 172 |
|
250 |
public void setCubits(BandagedCubit[] cubits, int x, int y, int z)
|
|
173 |
public void setDist3D(float[] dist3d)
|
|
251 | 174 |
{ |
252 |
mCubits = cubits; |
|
253 |
mNumCubits = cubits.length; |
|
254 |
|
|
255 |
mX = x; |
|
256 |
mY = y; |
|
257 |
mZ = z; |
|
258 |
mMax = mX>mY ? Math.max(mX,mZ) : Math.max(mY,mZ); |
|
259 |
|
|
260 |
mDist3D[0] = mDist3D[1] = 0.5f*(mX/mMax); |
|
261 |
mDist3D[2] = mDist3D[3] = 0.5f*(mY/mMax); |
|
262 |
mDist3D[4] = mDist3D[5] = 0.5f*(mZ/mMax); |
|
175 |
mDist3D = dist3d; |
|
263 | 176 |
} |
264 | 177 |
|
265 | 178 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
282 | 195 |
|
283 | 196 |
if( !touched ) return -1; |
284 | 197 |
|
285 |
return whichCubitTouched(mLastTouchedFace,mPoint2D[0],mPoint2D[1]); |
|
198 |
return mObject.whichCubitTouched(mLastTouchedFace,mPoint2D[0],mPoint2D[1]);
|
|
286 | 199 |
} |
287 | 200 |
} |
288 | 201 |
|
src/main/java/org/distorted/bandaged/BandagedCreatorView.java | ||
---|---|---|
9 | 9 |
|
10 | 10 |
package org.distorted.bandaged; |
11 | 11 |
|
12 |
import android.annotation.SuppressLint; |
|
12 | 13 |
import android.app.ActivityManager; |
13 | 14 |
import android.content.Context; |
14 | 15 |
import android.content.pm.ConfigurationInfo; |
... | ... | |
19 | 20 |
|
20 | 21 |
import com.google.firebase.crashlytics.FirebaseCrashlytics; |
21 | 22 |
|
22 |
import org.distorted.library.main.DistortedScreen; |
|
23 |
|
|
24 | 23 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
25 | 24 |
|
26 | 25 |
public class BandagedCreatorView extends GLSurfaceView |
... | ... | |
53 | 52 |
{ |
54 | 53 |
BandagedCreatorActivity act = (BandagedCreatorActivity)context; |
55 | 54 |
mRenderer = new BandagedCreatorRenderer(this); |
56 |
DistortedScreen screen = mRenderer.getScreen(); |
|
57 |
mTouchControl = new BandagedCreatorTouchControl( mRenderer.getObjectRatio() , screen.getFOV() ); |
|
55 |
mTouchControl = mRenderer.createTouchControl(); |
|
58 | 56 |
|
59 | 57 |
final ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); |
60 | 58 |
|
... | ... | |
105 | 103 |
return mRenderer; |
106 | 104 |
} |
107 | 105 |
|
108 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
109 |
|
|
110 |
public void setCubits(BandagedCubit[] cubits, int x, int y, int z) |
|
111 |
{ |
|
112 |
mTouchControl.setCubits(cubits,x,y,z); |
|
113 |
} |
|
114 |
|
|
115 | 106 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
116 | 107 |
|
117 | 108 |
public void resetCubits() |
... | ... | |
321 | 312 |
|
322 | 313 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
323 | 314 |
|
315 |
@SuppressLint("ClickableViewAccessibility") |
|
324 | 316 |
@Override |
325 | 317 |
public boolean onTouchEvent(MotionEvent event) |
326 | 318 |
{ |
src/main/java/org/distorted/bandaged/BandagedCreatorWorkerThread.java | ||
---|---|---|
89 | 89 |
} |
90 | 90 |
|
91 | 91 |
try { mThis.wait(); } |
92 |
catch(InterruptedException ex) { }
|
|
92 |
catch(InterruptedException ignored) { }
|
|
93 | 93 |
} |
94 | 94 |
} |
95 | 95 |
} |
... | ... | |
313 | 313 |
if(bos!=null) |
314 | 314 |
{ |
315 | 315 |
try { bos.close(); } |
316 |
catch(IOException io) {}
|
|
316 |
catch(IOException ignored) {}
|
|
317 | 317 |
} |
318 | 318 |
} |
319 | 319 |
|
src/main/java/org/distorted/bandaged/BandagedObject.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2023 Leszek Koltunski // |
|
3 |
// // |
|
4 |
// This file is part of Magic Cube. // |
|
5 |
// // |
|
6 |
// 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 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
9 |
|
|
10 |
package org.distorted.bandaged; |
|
11 |
|
|
12 |
import org.distorted.library.main.DistortedNode; |
|
13 |
import org.distorted.library.main.DistortedScreen; |
|
14 |
import org.distorted.library.type.Static3D; |
|
15 |
import org.distorted.library.type.Static4D; |
|
16 |
import org.distorted.objectlib.main.InitData; |
|
17 |
import org.distorted.objectlib.main.TwistyObject; |
|
18 |
import org.distorted.objectlib.objects.TwistyBandagedCuboid; |
|
19 |
import org.distorted.objectlib.shape.ShapeHexahedron; |
|
20 |
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron; |
|
21 |
|
|
22 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
23 |
|
|
24 |
public class BandagedObject |
|
25 |
{ |
|
26 |
private static final float DIST2D = 0.5f; |
|
27 |
|
|
28 |
private final DistortedScreen mScreen; |
|
29 |
private final float[] mPos; |
|
30 |
|
|
31 |
private BandagedCubit[] mCubits; |
|
32 |
private int mX, mY, mZ; |
|
33 |
private int mNumCubits; |
|
34 |
|
|
35 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
36 |
|
|
37 |
BandagedObject(DistortedScreen screen) |
|
38 |
{ |
|
39 |
mScreen = screen; |
|
40 |
mPos = new float[3]; |
|
41 |
} |
|
42 |
|
|
43 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
44 |
|
|
45 |
void resetObject(float scale) |
|
46 |
{ |
|
47 |
for(int c=0; c<mNumCubits; c++) |
|
48 |
{ |
|
49 |
if( !mCubits[c].isAttached() ) |
|
50 |
{ |
|
51 |
mCubits[c].attach(); |
|
52 |
mScreen.attach(mCubits[c].getNode()); |
|
53 |
} |
|
54 |
if( mCubits[c].getPosition().length>3 ) |
|
55 |
{ |
|
56 |
mCubits[c].reset(scale); |
|
57 |
} |
|
58 |
mCubits[c].setUnmarked(); |
|
59 |
} |
|
60 |
} |
|
61 |
|
|
62 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
63 |
|
|
64 |
private boolean isAdjacent(float[] pos1, float[] pos2) |
|
65 |
{ |
|
66 |
int len1 = pos1.length/3; |
|
67 |
int len2 = pos2.length/3; |
|
68 |
|
|
69 |
for(int i=0; i<len1; i++) |
|
70 |
for(int j=0; j<len2; j++) |
|
71 |
{ |
|
72 |
float d0 = pos1[3*i ] - pos2[3*j ]; |
|
73 |
float d1 = pos1[3*i+1] - pos2[3*j+1]; |
|
74 |
float d2 = pos1[3*i+2] - pos2[3*j+2]; |
|
75 |
|
|
76 |
if( d0*d0 + d1*d1 + d2*d2 == 1 ) return true; |
|
77 |
} |
|
78 |
|
|
79 |
return false; |
|
80 |
} |
|
81 |
|
|
82 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
83 |
|
|
84 |
private int computeNumCubits(int x, int y, int z) |
|
85 |
{ |
|
86 |
return ( x<=1 || y<=1 || z<=1 ) ? x*y*z : x*y*z-(x-2)*(y-2)*(z-2); |
|
87 |
} |
|
88 |
|
|
89 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
90 |
|
|
91 |
float getSize() |
|
92 |
{ |
|
93 |
return mX>mY ? Math.max(mX, mZ) : Math.max(mY, mZ); |
|
94 |
} |
|
95 |
|
|
96 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
97 |
|
|
98 |
float[][] getCubitPositions() |
|
99 |
{ |
|
100 |
int numAttached = 0; |
|
101 |
|
|
102 |
for(int i=0; i<mNumCubits; i++) |
|
103 |
if( mCubits[i].isAttached() ) numAttached++; |
|
104 |
|
|
105 |
float[][] pos = new float[numAttached][]; |
|
106 |
int attached=0; |
|
107 |
|
|
108 |
for(int i=0; i<mNumCubits; i++) |
|
109 |
if( mCubits[i].isAttached() ) |
|
110 |
{ |
|
111 |
pos[attached++] = mCubits[i].getPosition(); |
|
112 |
} |
|
113 |
|
|
114 |
return pos; |
|
115 |
} |
|
116 |
|
|
117 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
118 |
|
|
119 |
TwistyObject createObject(int mode, float size) |
|
120 |
{ |
|
121 |
float[][] pos = getCubitPositions(); |
|
122 |
InitData data = new InitData( new int[] {mX,mY,mZ},pos); |
|
123 |
return new TwistyBandagedCuboid( TwistyObject.MESH_NICE, mode, ShapeHexahedron.DEFAULT_ROT, new Static3D(0,0,0), size, data, null ); |
|
124 |
} |
|
125 |
|
|
126 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
127 |
|
|
128 |
void tryConnectingCubits(int index1, int index2, float scale) |
|
129 |
{ |
|
130 |
if( index1!=index2 ) |
|
131 |
{ |
|
132 |
float[] pos1 = mCubits[index1].getPosition(); |
|
133 |
float[] pos2 = mCubits[index2].getPosition(); |
|
134 |
|
|
135 |
if( isAdjacent(pos1,pos2) ) |
|
136 |
{ |
|
137 |
mCubits[index2].join(pos1,scale); |
|
138 |
mCubits[index1].detach(); |
|
139 |
mScreen.detach(mCubits[index1].getNode()); |
|
140 |
} |
|
141 |
} |
|
142 |
} |
|
143 |
|
|
144 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
145 |
|
|
146 |
void attachCubits(float scale) |
|
147 |
{ |
|
148 |
for(int i=0; i<mNumCubits; i++) |
|
149 |
{ |
|
150 |
mCubits[i].scaleMove(scale); |
|
151 |
DistortedNode node = mCubits[i].getNode(); |
|
152 |
mScreen.attach(node); |
|
153 |
} |
|
154 |
} |
|
155 |
|
|
156 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
157 |
|
|
158 |
void attachAndMarkCubits(float scale, int touched) |
|
159 |
{ |
|
160 |
for(int i=0; i<mNumCubits; i++) |
|
161 |
{ |
|
162 |
if( mCubits[i].isAttached() ) |
|
163 |
{ |
|
164 |
mCubits[i].scaleMove(scale); |
|
165 |
if( touched==i ) mCubits[i].setMarked(); |
|
166 |
else mCubits[i].setUnmarked(); |
|
167 |
DistortedNode node = mCubits[i].getNode(); |
|
168 |
mScreen.attach(node); |
|
169 |
} |
|
170 |
} |
|
171 |
} |
|
172 |
|
|
173 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
174 |
|
|
175 |
boolean tryChangeObject(int x, int y, int z) |
|
176 |
{ |
|
177 |
if( mX!=x || mY!=y || mZ!=z ) |
|
178 |
{ |
|
179 |
mX = x; |
|
180 |
mY = y; |
|
181 |
mZ = z; |
|
182 |
mNumCubits = computeNumCubits(mX,mY,mZ); |
|
183 |
return true; |
|
184 |
} |
|
185 |
|
|
186 |
return false; |
|
187 |
} |
|
188 |
|
|
189 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
190 |
|
|
191 |
int computeProjectionAngle() |
|
192 |
{ |
|
193 |
float quot1 = mZ/ (float)mX; |
|
194 |
float quot2 = mZ/ (float)mY; |
|
195 |
float quot3 = mX/ (float)mZ; |
|
196 |
float quot4 = mX/ (float)mY; |
|
197 |
|
|
198 |
float quot5 = Math.max(quot1,quot2); |
|
199 |
float quot6 = Math.max(quot3,quot4); |
|
200 |
float quot7 = Math.max(quot5,quot6); |
|
201 |
|
|
202 |
if( quot7<=1.0f ) return 120; |
|
203 |
else if( quot7<=1.5f ) return 90; |
|
204 |
else if( quot7<=2.0f ) return 60; |
|
205 |
else return 30; |
|
206 |
} |
|
207 |
|
|
208 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
209 |
|
|
210 |
void scaleCubits(float scale) |
|
211 |
{ |
|
212 |
for(int i=0; i<mNumCubits; i++) mCubits[i].scaleMove(scale); |
|
213 |
} |
|
214 |
|
|
215 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
216 |
|
|
217 |
void recreateCubits(Static4D quatT, Static4D quatA, Static3D scale) |
|
218 |
{ |
|
219 |
if( mCubits==null ) |
|
220 |
{ |
|
221 |
createCubits(quatT,quatA,scale); |
|
222 |
} |
|
223 |
else |
|
224 |
{ |
|
225 |
for(int i=0; i<mNumCubits; i++) mCubits[i].recreateBitmap(); |
|
226 |
} |
|
227 |
} |
|
228 |
|
|
229 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
230 |
|
|
231 |
float[] getDist3D() |
|
232 |
{ |
|
233 |
float max = getSize(); |
|
234 |
|
|
235 |
float x = 0.5f*(mX/max); |
|
236 |
float y = 0.5f*(mY/max); |
|
237 |
float z = 0.5f*(mZ/max); |
|
238 |
|
|
239 |
return new float[] {x,x,y,y,z,z}; |
|
240 |
} |
|
241 |
|
|
242 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
243 |
|
|
244 |
void createCubits(Static4D quatT, Static4D quatA, Static3D scale) |
|
245 |
{ |
|
246 |
mCubits = new BandagedCubit[mNumCubits]; |
|
247 |
int c=0; |
|
248 |
|
|
249 |
float begX = 0.5f*(1-mX); |
|
250 |
float begY = 0.5f*(1-mY); |
|
251 |
float begZ = 0.5f*(1-mZ); |
|
252 |
|
|
253 |
for(int x=0; x<mX; x++) |
|
254 |
for(int y=0; y<mY; y++) |
|
255 |
for(int z=0; z<mZ; z++) |
|
256 |
if( x==0 || x==mX-1 || y==0 || y==mY-1 || z==0 || z==mZ-1 ) |
|
257 |
{ |
|
258 |
float[] pos = new float[] { begX+x,begY+y,begZ+z }; |
|
259 |
mCubits[c] = new BandagedCubit(pos,mX,mY,mZ,quatT,quatA,scale,false); |
|
260 |
c++; |
|
261 |
} |
|
262 |
} |
|
263 |
|
|
264 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
265 |
|
|
266 |
Static3D[] getFaceAxis() |
|
267 |
{ |
|
268 |
return TouchControlHexahedron.FACE_AXIS; |
|
269 |
} |
|
270 |
|
|
271 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
272 |
|
|
273 |
void touchCubit(int index) |
|
274 |
{ |
|
275 |
if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setMarked(); |
|
276 |
} |
|
277 |
|
|
278 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
279 |
|
|
280 |
void untouchCubit(int index) |
|
281 |
{ |
|
282 |
if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setUnmarked(); |
|
283 |
} |
|
284 |
|
|
285 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
286 |
|
|
287 |
void stretchPoint(int face, float[] output) |
|
288 |
{ |
|
289 |
float max = getSize(); |
|
290 |
|
|
291 |
switch(face/2) |
|
292 |
{ |
|
293 |
case 0: output[0] *= (max/mZ); output[1] *= (max/mY); break; |
|
294 |
case 1: output[0] *= (max/mX); output[1] *= (max/mZ); break; |
|
295 |
case 2: output[0] *= (max/mX); output[1] *= (max/mY); break; |
|
296 |
} |
|
297 |
} |
|
298 |
|
|
299 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
300 |
|
|
301 |
int whichCubitTouched(int face, float pointX, float pointY) |
|
302 |
{ |
|
303 |
switch(face) |
|
304 |
{ |
|
305 |
case 0: mPos[0] = (mX-1)/2.0f; |
|
306 |
mPos[1] = (int)( mY*pointY+mY/2.0f)-(mY-1)/2.0f; |
|
307 |
mPos[2] = (int)(-mZ*pointX-mZ/2.0f)+(mZ-1)/2.0f; |
|
308 |
break; |
|
309 |
case 1: mPos[0] =-(mX-1)/2.0f; |
|
310 |
mPos[1] = (int)( mY*pointY+mY/2.0f)-(mY-1)/2.0f; |
|
311 |
mPos[2] = (int)( mZ*pointX+mZ/2.0f)-(mZ-1)/2.0f; |
|
312 |
break; |
|
313 |
case 2: mPos[0] = (int)( mX*pointX+mX/2.0f)-(mX-1)/2.0f; |
|
314 |
mPos[1] = (mY-1)/2.0f; |
|
315 |
mPos[2] = (int)(-mZ*pointY-mZ/2.0f)+(mZ-1)/2.0f; |
|
316 |
break; |
|
317 |
case 3: mPos[0] = (int)( mX*pointX+mX/2.0f)-(mX-1)/2.0f; |
|
318 |
mPos[1] =-(mY-1)/2.0f; |
|
319 |
mPos[2] = (int)( mZ*pointY+mZ/2.0f)-(mZ-1)/2.0f; |
|
320 |
break; |
|
321 |
case 4: mPos[0] = (int)( mX*pointX+mX/2.0f)-(mX-1)/2.0f; |
|
322 |
mPos[1] = (int)( mY*pointY+mY/2.0f)-(mY-1)/2.0f; |
|
323 |
mPos[2] = (mZ-1)/2.0f; |
|
324 |
break; |
|
325 |
case 5: mPos[0] = (int)(-mX*pointX-mX/2.0f)+(mX-1)/2.0f; |
|
326 |
mPos[1] = (int)( mY*pointY+mY/2.0f)-(mY-1)/2.0f; |
|
327 |
mPos[2] =-(mZ-1)/2.0f; |
|
328 |
break; |
|
329 |
} |
|
330 |
|
|
331 |
for(int c=0; c<mNumCubits; c++) |
|
332 |
if( mCubits[c].isAttached() ) |
|
333 |
{ |
|
334 |
float[] pos = mCubits[c].getPosition(); |
|
335 |
int len = pos.length/3; |
|
336 |
|
|
337 |
for(int p=0; p<len; p++) |
|
338 |
if( pos[3*p]==mPos[0] && pos[3*p+1]==mPos[1] && pos[3*p+2]==mPos[2] ) return c; |
|
339 |
} |
|
340 |
|
|
341 |
android.util.Log.e("D", "whichCubitTouched: IMPOSSIBLE!!"); |
|
342 |
return -1; |
|
343 |
} |
|
344 |
|
|
345 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
346 |
|
|
347 |
boolean isInsideFace(int face, float[] p) |
|
348 |
{ |
|
349 |
return ( p[0]<=DIST2D && p[0]>=-DIST2D && p[1]<=DIST2D && p[1]>=-DIST2D ); |
|
350 |
} |
|
351 |
} |
Also available in: Unified diff
Introduce 'BandagedObject' - an abstraction and a step towards creator of Bandaged Pyraminxes.