[androidkit] Relative-sized cube sample
Update the cube sample to be centered and sized relative to the target surface. Also simplify projection handling: - pre-compute a full view matrix in onSurfaceInitialized() - set the origin to the surface center - compute perspective and camera transforms in local coordinates (instead of unit view cube) Also fix (invert) fling Y direction. Change-Id: I48a3d0b4547812fb3c9b49a9842fb18c0ed0d863 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/413436 Reviewed-by: Jorge Betancourt <jmbetancourt@google.com>
This commit is contained in:
parent
491f412c94
commit
4abf558c9f
@ -135,22 +135,10 @@ class VSphereAnimator {
|
||||
|
||||
class CubeRenderer extends SurfaceRenderer implements GestureDetector.OnGestureListener {
|
||||
private VSphereAnimator mVSphere;
|
||||
private Matrix mViewMatrix;
|
||||
private float mCubeSideLength;
|
||||
private long mPrevMS;
|
||||
|
||||
// TODO: make these relative to surface size
|
||||
private float mCubeSideLength = 500;
|
||||
private int DX = 200;
|
||||
private int DY = 300;
|
||||
|
||||
private long mPrevMS;
|
||||
|
||||
private float fAngle = (float)Math.PI / 12;
|
||||
private float eyeZ = (float)(1.0f/tan(fAngle/2) - 1);
|
||||
|
||||
private Matrix cam = Matrix.makeLookAt(0, 0, eyeZ, 0, 0, 0, 0, 1, 0);
|
||||
private Matrix perspective = Matrix.makePerspective(0.05f, 4, fAngle);
|
||||
private Matrix viewport;
|
||||
|
||||
private final float rot = (float) Math.PI;
|
||||
private Face[] faces;
|
||||
|
||||
public CubeRenderer(Resources res) {
|
||||
@ -164,6 +152,7 @@ class CubeRenderer extends SurfaceRenderer implements GestureDetector.OnGestureL
|
||||
brickPaint.setShader(shader);
|
||||
} catch (Exception e) {}
|
||||
|
||||
final float rot = (float) Math.PI;
|
||||
faces = new Face[] {
|
||||
new Face(0, -rot/2, brickPaint),
|
||||
new Face(0, 0 , new Paint().setColor(new Color(1, 0, 0, 1))),
|
||||
@ -176,12 +165,28 @@ class CubeRenderer extends SurfaceRenderer implements GestureDetector.OnGestureL
|
||||
|
||||
@Override
|
||||
protected void onSurfaceInitialized(Surface surface) {
|
||||
float hw = surface.getWidth() / 2,
|
||||
hh = surface.getHeight() / 2;
|
||||
mVSphere = new VSphereAnimator(hw, hh, Math.min(hw, hh));
|
||||
float cx = surface.getWidth() / 2,
|
||||
cy = surface.getHeight() / 2,
|
||||
r = Math.min(cx, cy);
|
||||
|
||||
viewport = new Matrix().translate(mCubeSideLength/2, mCubeSideLength/2, 0)
|
||||
.scale(mCubeSideLength/2, mCubeSideLength/2, surface.getWidth());
|
||||
mVSphere = new VSphereAnimator(cx, cy, r);
|
||||
|
||||
// square viewport size fitting the given surface
|
||||
float vsz = r * 2;
|
||||
|
||||
mCubeSideLength = vsz * 0.5f;
|
||||
|
||||
float viewAngle = (float)Math.PI / 4f,
|
||||
viewDistance = (float)(r / tan(viewAngle/2));
|
||||
|
||||
mViewMatrix = new Matrix()
|
||||
// centered viewport
|
||||
.translate(cx, cy)
|
||||
// perspective
|
||||
.scale(vsz/2, vsz/2, 1)
|
||||
.preConcat(Matrix.makePerspective(0.05f, viewDistance, viewAngle))
|
||||
// camera
|
||||
.preConcat(Matrix.makeLookAt(0, 0, -viewDistance, 0, 0, 0, 0, 1, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -198,24 +203,17 @@ class CubeRenderer extends SurfaceRenderer implements GestureDetector.OnGestureL
|
||||
canvas.drawColor(0xffffffff);
|
||||
|
||||
canvas.save();
|
||||
canvas.concat(new Matrix().translate(DX, DY, 0));
|
||||
canvas.concat(viewport.preConcat(perspective)
|
||||
.preConcat(cam)
|
||||
.preConcat(Matrix.makeInverse(viewport)));
|
||||
canvas.concat(mViewMatrix);
|
||||
canvas.concat(mVSphere.getMatrix());
|
||||
|
||||
for (Face f : faces) {
|
||||
//TODO: auto restore
|
||||
canvas.save();
|
||||
Matrix trans = new Matrix().translate(mCubeSideLength/2, mCubeSideLength/2, 0);
|
||||
Matrix m = new Matrix().preConcat(mVSphere.getMatrix())
|
||||
.preConcat(f.asMatrix(mCubeSideLength/2));
|
||||
|
||||
canvas.concat(trans);
|
||||
Matrix localToWorld = m.preConcat(Matrix.makeInverse(trans));
|
||||
canvas.concat(localToWorld);
|
||||
canvas.concat(f.asMatrix(mCubeSideLength/2));
|
||||
|
||||
if (front(canvas.getLocalToDevice())) {
|
||||
canvas.drawRect(0, 0, mCubeSideLength, mCubeSideLength, f.paint);
|
||||
canvas.drawRect(-mCubeSideLength/2, -mCubeSideLength/2,
|
||||
mCubeSideLength/2, mCubeSideLength/2, f.paint);
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
@ -224,7 +222,7 @@ class CubeRenderer extends SurfaceRenderer implements GestureDetector.OnGestureL
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float dx, float dy) {
|
||||
mVSphere.fling(dx, dy);
|
||||
mVSphere.fling(dx, -dy);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user