Cardboard : Android 를 위한 저렴한 VR

1,229 views

Published on

Cardboard : Android 를 위한 저렴한 VR

Published in: Software
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,229
On SlideShare
0
From Embeds
0
Number of Embeds
23
Actions
Shares
0
Downloads
14
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Cardboard : Android 를 위한 저렴한 VR

  1. 1. Cardboard Android 를 위한 저렴한 VR Youngbin Han <sukso96100@gmail.com>
  2. 2. VR(Virtual Reality)?
  3. 3. http://blogs-images.forbes.com/danielnyegriffiths/files/2014/05/OculusRift1.jpg
  4. 4. https://s3.amazonaws.com/ksr/projects/476061/photo-main.jpg?1397812032
  5. 5. http://www.realareal.com/wp-content/uploads/2013/08/Oculus_VR_Immeractive_Haeva.jpg
  6. 6. $$$$$$$$
  7. 7. https://www.oculusvr.com/order/
  8. 8. g.co/cardboard
  9. 9. g.co/cardboard
  10. 10. http://www.dodocase.com/products/google-cardboard-vr-goggle-toolkit
  11. 11. Cardboard VR Toolkit https://developers.google.com/cardboard/overview
  12. 12. Toolkit을 이용하면 다음을 포함한 많은 공통된 VR 개발을 단순화 할 수 있습니다. ● 렌즈 왜곡 보정 ● 머리 추적 ● 3D 교정 ● 양쪽에 나란히 렌더링 ● 입체 형상 구성 ● 사용자 입력 이벤트 처리
  13. 13. 간단한 Cardboard 앱 만들기. 만들기 어려운 건 함정 https://developers.google.com/cardboard/get-started
  14. 14. 준비할 것들... ...
  15. 15. 프로젝트에 라이브러리 추가 https://github.com/googlesamples/cardboard/blob/master/CardboardSample/libs/cardboard.jar
  16. 16. 권장되는 Manifest.xml 설정 <manifest ... <uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.VIBRATE" /> ... <uses-sdk android:minSdkVersion="16"/> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <application ... <activity android:screenOrientation="landscape" ... </activity> </application> </manifest> 가로 모드 Open GL ES 사용 NFC 및 진동 권한 Android 4.1 +
  17. 17. CardboardActivity 상속받기 public class CardboardActivityExample extends CardboardActivity { … }
  18. 18. CardboardView.StereoRenderer 구현하기 public class CardboardActivityExample extends CardboardActivity implements CardboardView.StereoRenderer { … }
  19. 19. CardboardView 초기화
  20. 20. private float[] mModelCube; private float[] mCamera; private float[] mView; private float[] mHeadView; private float[] mModelViewProjection; private float[] mModelView; private float[] mModelFloor; private Vibrator mVibrator; … * * * Sets the view to our CardboardView and initializes the transformation matrices we will use * to render our scene. * @param savedInstanceState */ … @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.common_ui); CardboardView cardboardView = (CardboardView) findViewById(R.id. common_paperscope_view); // Associate a CardboardView.StereoRenderer with cardboardView. cardboardView.setRenderer(this); // Associate the cardboardView with this activity. setCardboardView(cardboardView); mModelCube = new float[16]; mCamera = new float[16]; mView = new float[16]; mModelViewProjection = new float[16]; mModelView = new float[16]; mModelFloor = new float[16]; mHeadView = new float[16]; mVibrator = (Vibrator) getSystemService (Context.VIBRATOR_SERVICE); … }
  21. 21. 뷰 렌더링 하기 CardboardView.StereoRenderer 를 통해 구현한, onNewFrame(), onDrawEye() 사용.
  22. 22. onNewFrame() 구현하기 private int mGlProgram = GLES20.glCreateProgram(); private int mPositionParam; private int mNormalParam; private int mColorParam; private int mModelViewProjectionParam; private int mLightPosParam; private int mModelViewParam; private int mModelParam; private int mIsFloorParam; private float[] mHeadView; ... /** * Prepares OpenGL ES before we draw a frame. * @param headTransform The head transformation in the new frame. */ … … @Override public void onNewFrame(HeadTransform headTransform) { GLES20.glUseProgram(mGlProgram); mModelViewProjectionParam = GLES20. glGetUniformLocation(mGlProgram, "u_MVP"); mLightPosParam = GLES20.glGetUniformLocation (mGlProgram, "u_LightPos"); mModelViewParam = GLES20.glGetUniformLocation (mGlProgram, "u_MVMatrix"); mModelParam = GLES20.glGetUniformLocation (mGlProgram, "u_Model"); mIsFloorParam = GLES20.glGetUniformLocation (mGlProgram, "u_IsFloor"); // Build the Model part of the ModelView matrix. Matrix.rotateM(mModelCube, 0, TIME_DELTA, 0.5f, 0.5 f, 1.0f); // Build the camera matrix and apply it to the ModelView. Matrix.setLookAtM(mCamera, 0, 0.0f, 0.0f, CAMERA_Z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); headTransform.getHeadView(mHeadView, 0); checkGLError("onReadyToDraw"); }
  23. 23. onDrawEye() 구현하기 private int mPositionParam; private int mNormalParam; private int mColorParam; // We keep the light always position just above the user. private final float[] mLightPosInEyeSpace = new float[] {0.0f, 2.0f, 0.0f, 1.0f}; ... /** * Draws a frame for an eye. The transformation for that eye (from the camera) is passed in as * a parameter. * @param transform The transformations to apply to render this eye. */ … @Override public void onDrawEye(EyeTransform transform) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20. GL_DEPTH_BUFFER_BIT); mPositionParam = GLES20.glGetAttribLocation(mGlProgram, "a_Position"); mNormalParam = GLES20.glGetAttribLocation(mGlProgram, "a_Normal"); mColorParam = GLES20.glGetAttribLocation(mGlProgram, "a_Color"); GLES20.glEnableVertexAttribArray(mPositionParam); GLES20.glEnableVertexAttribArray(mNormalParam); GLES20.glEnableVertexAttribArray(mColorParam); checkGLError("mColorParam"); // Apply the eye transformation to the camera. Matrix.multiplyMM(mView, 0, transform.getEyeView(), 0, mCamera, 0); // Set the position of the light Matrix.multiplyMV(mLightPosInEyeSpace, 0, mView, 0, mLightPosInWorldSpace, 0); GLES20.glUniform3f(mLightPosParam, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]); // Build the ModelView and ModelViewProjection matrices // for calculating cube position and light. Matrix.multiplyMM(mModelView, 0, mView, 0, mModelCube, 0); Matrix.multiplyMM(mModelViewProjection, 0, transform.getPerspective(), 0, mModelView, 0); drawCube(); // Set mModelView for the floor, so we draw floor in the correct location Matrix.multiplyMM(mModelView, 0, mView, 0, mModelFloor, 0); Matrix.multiplyMM(mModelViewProjection, 0, transform.getPerspective(), 0, mModelView, 0); ... }
  24. 24. 자석 버튼 누름 감지하기 MagnetSensor.OnCardboardTriggerListener 사용
  25. 25. private Vibrator mVibrator; private CardboardOverlayView mOverlayView; ... /** * Increment the score, hide the object, and give feedback if the user pulls the magnet while * looking at the object. Otherwise, remind the user what to do. */ @Override public void onCardboardTrigger() { if (isLookingAtObject()) { mScore++; mOverlayView.show3DToast("Found it! Look around for another one.nScore = " + mScore); ... } else { mOverlayView.show3DToast("Look around to find the object!"); } // Always give user feedback mVibrator.vibrate(50); } /** * Check if user is looking at object by calculating where the object is in eye- space. * @return */ private boolean isLookingAtObject() { float[] initVec = {0, 0, 0, 1.0f}; float[] objPositionVec = new float[4]; // Convert object space to camera space. Use the headView from onNewFrame. Matrix.multiplyMM(mModelView, 0, mHeadView, 0, mModelCube, 0); Matrix.multiplyMV(objPositionVec, 0, mModelView, 0, initVec, 0); float pitch = (float)Math.atan2 (objPositionVec[1], -objPositionVec[2]); float yaw = (float)Math.atan2 (objPositionVec[0], -objPositionVec[2]); ... return (Math.abs(pitch) < PITCH_LIMIT) && (Math.abs(yaw) < YAW_LIMIT); }
  26. 26. Cardboard 앱 시연 (예제 앱) Treasure Hunt Cardboard Demo 앱
  27. 27. 참고자료 ● https://developers.google.com/cardboard/get-started ● g.co/cardboard ● http://www.khronos.org/opengles/sdk/docs/man/
  28. 28. Thank You!

×