diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java index 848e82dda..4d48a1e37 100644 --- a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java +++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java @@ -20,7 +20,6 @@ import com.example.android.apis.R; import android.content.Context; import android.graphics.*; -import android.graphics.utils.BoundaryPatch; import android.os.Bundle; import android.view.*; import android.util.FloatMath; @@ -32,83 +31,97 @@ public class BitmapMesh extends GraphicsActivity { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } - + private static class SampleView extends View { - private static final int ROWS = 16; - private static final int COLS = 16; + private static final int WIDTH = 20; + private static final int HEIGHT = 20; + private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1); + + private final Bitmap mBitmap; + private final float[] mVerts = new float[COUNT*2]; + private final float[] mOrig = new float[COUNT*2]; + + private final Matrix mMatrix = new Matrix(); + private final Matrix mInverse = new Matrix(); - private BoundaryPatch mPatch; - private float[] mCubics; - private Paint mPaint0; - private Paint mPaint1; - private int mCurrIndex = -1; + private static void setXY(float[] array, int index, float x, float y) { + array[index*2 + 0] = x; + array[index*2 + 1] = y; + } public SampleView(Context context) { super(context); setFocusable(true); - Bitmap bm = BitmapFactory.decodeResource(getResources(), + mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.beach); - - mPatch = new BoundaryPatch(); - mPatch.setTexture(bm); - - float unit = 90; - mCubics = new float[] { - 0, 0, 1, 0, 2, 0, - 3, 0, 3, 1, 3, 2, - 3, 3, 2, 3, 1, 3, - 0, 3, 0, 2, 0, 1 - }; - for (int i = 0; i < 24; i++) { - mCubics[i] *= 90; - mCubics[i] += 20; - } - mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS); - - mPaint0 = new Paint(); - mPaint0.setAntiAlias(true); - mPaint0.setStrokeWidth(12); - mPaint0.setStrokeCap(Paint.Cap.ROUND); - mPaint1 = new Paint(mPaint0); - mPaint1.setColor(0xFFFFFFFF); - mPaint1.setStrokeWidth(10); - } - - @Override protected void onDraw(Canvas canvas) { - canvas.drawColor(0xFFCCCCCC); - mPatch.draw(canvas); - canvas.drawPoints(mCubics, mPaint0); - canvas.drawPoints(mCubics, mPaint1); - } - - private int findPtIndex(float x, float y) { - final float tolerance = 25; - final float[] pts = mCubics; - for (int i = 0; i < (pts.length >> 1); i++) { - if (Math.abs(pts[i*2 + 0] - x) <= tolerance && - Math.abs(pts[i*2 + 1] - y) <= tolerance) { - return i*2; + + float w = mBitmap.getWidth(); + float h = mBitmap.getHeight(); + // construct our mesh + int index = 0; + for (int y = 0; y <= HEIGHT; y++) { + float fy = h * y / HEIGHT; + for (int x = 0; x <= WIDTH; x++) { + float fx = w * x / WIDTH; + setXY(mVerts, index, fx, fy); + setXY(mOrig, index, fx, fy); + index += 1; + } + } + + mMatrix.setTranslate(10, 10); + mMatrix.invert(mInverse); + } + + @Override protected void onDraw(Canvas canvas) { + canvas.drawColor(0xFFCCCCCC); + + canvas.concat(mMatrix); + canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0, + null, 0, null); + } + + private void warp(float cx, float cy) { + final float K = 10000; + float[] src = mOrig; + float[] dst = mVerts; + for (int i = 0; i < COUNT*2; i += 2) { + float x = src[i+0]; + float y = src[i+1]; + float dx = cx - x; + float dy = cy - y; + float dd = dx*dx + dy*dy; + float d = FloatMath.sqrt(dd); + float pull = K / (dd + 0.000001f); + + pull /= (d + 0.000001f); + // android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull); + + if (pull >= 1) { + dst[i+0] = cx; + dst[i+1] = cy; + } else { + dst[i+0] = x + dx * pull; + dst[i+1] = y + dy * pull; } } - return -1; } + private int mLastWarpX = -9999; // don't match a touch coordinate + private int mLastWarpY; + @Override public boolean onTouchEvent(MotionEvent event) { - float x = event.getX(); - float y = event.getY(); - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mCurrIndex = findPtIndex(x, y); - break; - case MotionEvent.ACTION_MOVE: - if (mCurrIndex >= 0) { - mCubics[mCurrIndex + 0] = x; - mCubics[mCurrIndex + 1] = y; - mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS); - invalidate(); - } - break; + float[] pt = { event.getX(), event.getY() }; + mInverse.mapPoints(pt); + + int x = (int)pt[0]; + int y = (int)pt[1]; + if (mLastWarpX != x || mLastWarpY != y) { + mLastWarpX = x; + mLastWarpY = y; + warp(pt[0], pt[1]); + invalidate(); } return true; }