2012-11-16 8 views
5

मैं एक साधारण ऐप बनाने की कोशिश कर रहा हूं जो आपको स्क्रीन को स्पर्श करके .obj से 3 डी मॉडल लोड करने और ज़ूम/घुमाएगा।libgdx स्पर्श पर 3 डी मॉडल को ज़ूम और घुमाने के लिए कैसे करें

मैं कोड लिखने में कामयाब रहा जो फ़ाइल से 3 डी मॉडल लोड करता है और इशारे का पता लगाता है लेकिन अब मुझे यकीन नहीं है कि स्क्रीन को स्पर्श करके ज़ूम/घुमाने वाली सुविधाओं को सक्षम करने के लिए क्या करना है।

यहाँ अभी तो मैं अपना कोड है:

public class RenderObjApp implements ApplicationListener, GestureDetector.GestureListener { 
    public static int SCREEN_WIDTH = 800; 
    public static int SCREEN_HEIGHT = 600; 

    private static final String TAG = RenderObjApp.class.getSimpleName(); 

    private Mesh model; 
    private PerspectiveCamera camera; 

    private float scale = 1f; 

    @Override 
    public void create() { 
     model = ObjLoader.loadObj(Gdx.files.internal("data/cessna.obj").read(), true); 
     Gdx.gl.glEnable(GL10.GL_DEPTH_TEST); 
     Gdx.input.setInputProcessor(new GestureDetector(this)); 
    } 

    @Override 
    public void dispose() { 
    } 

    @Override 
    public void pause() { 
    } 


    @Override 
    public void render() { 
     Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
     Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
     camera.update(); 
     camera.apply(Gdx.gl10); 
     model.render(GL10.GL_TRIANGLES); 
    } 

    @Override 
    public void resize(int arg0, int arg1) { 
     float aspectRatio = (float) arg0/(float) arg1; 
     camera = new PerspectiveCamera(75, 2f * aspectRatio, 2f); 
     camera.near = 0.1f; 
     camera.translate(0, 0, 0); 
    } 

    @Override 
    public void resume() { 
    } 

    @Override 
    public boolean touchDown(float x, float y, int pointer) { 
     Gdx.app.log(TAG, "touchDown: "); 
     return false; 
    } 

    @Override 
    public boolean tap(float x, float y, int count, int pointer, int button) { 
     Gdx.app.log(TAG, "tap: "); 
     return false; 
    } 

    @Override 
    public boolean longPress(float x, float y) { 
     Gdx.app.log(TAG, "zoom: "); 
     return false; 
    } 

    @Override 
    public boolean fling(float velocityX, float velocityY, int pointer, int button) { 
     Gdx.app.log(TAG, "fling: "); 
     return false; 
    } 

    @Override 
    public boolean pan(float x, float y, float deltaX, float deltaY) { 
     Gdx.app.log(TAG, "pan: "); 
     return false; 
    } 

    @Override 
    public boolean zoom(float initialDistance, float distance) { 
     Gdx.app.log(TAG, "zoom: initialDistance=" + initialDistance + ", distance=" + distance); 
     return false; 
    } 

    @Override 
    public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) { 
     Gdx.app.log(TAG, "pinch: "); 
     return false; 
    } 
} 

तो मैं PerspectiveCamera बारी बारी से और खुद जाल करने के लिए कैसे देख रहा हूँ।

उत्तर

0

आपको या तो कैमरे को घुमाने या मॉडल को घुमाए जाने की आवश्यकता है।

मेरा मानना ​​है कि libGDX Camera.rotateAround विधि आपको जो चाहिए वह करता है। "पॉइंट" को अपने मॉडल के केंद्र के रूप में छोड़ दें और "अक्ष" पैरामीटर सेट करें जिस पर उपयोगकर्ता फ़्लिंग/पैनिंग कर रहा है। "कोण" या तो निश्चित मान हो सकता है, या फ़्लिंग/पैन की तीव्रता के सापेक्ष हो सकता है।

1

कृपया इसे देखें: Mesh rendering issue libgdx

विधि प्रस्तुत करने के लिए आवश्यक कोड शामिल है।

2

मैं "ब्लेंडर-स्टाइल" कैमरे पर काम कर रहा हूं जिसमें ब्लेंडर के कैमरे के साथ मिलकर अधिकांश कार्यक्षमता चुटकी-टू-ज़ूम क्षमता और डेस्कटॉप पर है। यह एक काम प्रगति पर है - यह ब्लेंडर के कैमरे (अभी तक) के व्यवहार की पूरी तरह नकल नहीं करता है। मुझे लगता है कि यह आपको सही दिशा में इंगित करेगा। कुछ चीजें आपको जाननी चाहिए:

  1. आपको अपने मॉडल का अनुवाद करना पड़ सकता है ताकि यह मूल पर बैठे। जब तक आप इसका अनुवाद नहीं करते हैं तब तक कैमरे मूल पर इंगित होता है। (आप केवल डेस्कटॉप पर अनुवाद कर सकते हैं, न कि अब तक एंड्रॉइड पर);

  2. मुझे यहां सबसे चुटकी-टू-ज़ूम हैंडलिंग कोड मिला है: https://code.google.com/p/libgdx-users/wiki/PinchToZoom

  3. जादू संख्याओं के लिए खेद है। मैं भविष्य में उन स्थिरांक बना दूंगा।

  4. यदि आप या कोई अन्य इस कोड को बेहतर बनाता है, तो मुझे प्यार होगा अगर आपने मेरे साथ एक प्रति साझा की है।

सार वर्ग:

/* Author: Christopher Grabowski, yourchristopher6334 gmail.com */ 

package ...; 

import com.badlogic.gdx.InputProcessor; 
import com.badlogic.gdx.graphics.PerspectiveCamera; 
import com.badlogic.gdx.input.GestureDetector.GestureListener; 
import com.badlogic.gdx.math.Vector2; 

abstract public class ControllableCamera extends PerspectiveCamera implements InputProcessor{ 

    abstract public void resize(int width, int height); 
    abstract public void render(); 

    public ControllableCamera(int fieldOfView, int width, int height) { 
     super(fieldOfView, width, height); 
    } 

    @Override 
    public boolean keyDown(int keyCode) { 
     return false; 
    } 

    @Override 
    public boolean keyTyped(char arg0) { 
     return false; 
    } 

    @Override 
    public boolean keyUp(int arg0) { 
     return false; 
    } 

    @Override 
    public boolean touchDown(int x, int y, int pointer, int button) { 
     return false; 
    } 

    @Override 
    public boolean touchDragged(int screenX, int screenY, int pointer) { 
     return false; 
    } 

    @Override 
    public boolean touchUp(int x, int y, int pointer, int button) { 
     return false; 
    } 

    @Override 
    public boolean mouseMoved(int arg0, int arg1) { 
     return false; 
    } 

    @Override 
    public boolean scrolled(int direction) { 
     return false; 
    } 
} 

ठोस वर्ग:

/* Author: Christopher Grabowski, yourchristopher6334 gmail.com */ 

package ...; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.Input.Keys; 
import com.badlogic.gdx.math.Vector3; 

/* 
* the pause, resize, and render methods must be called within their corresponding 
* methods in the ApplicationListener 
*/ 

public class BlenderStyleCamera extends ControllableCamera { 
    public static final Vector3 ORIGIN = new Vector3(0, 0, 0); 

    private static boolean shiftIsPressed = false, controlIsPressed = false, 
      isScrollingUp = false, isScrollingDown = false, 
      isSingleTouched = false, justSingleTouched = false; 

    private float aspectRatio; 
    private int x = -1, y = -1; 
    private float dx = 0.0f, dy = 0.0f; 
    private final Vector3 tmp = new Vector3(); 

    // fields related to pinch-to-zoom 
    private int numberOfFingers = 0; 
    private int fingerOnePointer; 
    private int fingerTwoPointer; 
    private float lastDistance = 0; 
    private final Vector3 fingerOne = new Vector3(); 
    private final Vector3 fingerTwo = new Vector3(); 

    public BlenderStyleCamera(int fieldOfView, int width, int height) { 
     super(fieldOfView, width, height); 
     aspectRatio = viewportHeight/viewportWidth; 
     Gdx.input.setInputProcessor(this); 
     up.set(0.0f, 1.0f, 0.0f); 
     position.set(0.0f, 0.0f, 30.0f); 
     far = 300.0f; 
     lookAt(0, 0, 0); 
     translate(0.0f, 0.0f, 2.1f); 
     lookAt(0, 0, 0); 
     update(); 
    } 

    public void pause() { 
     numberOfFingers = 0; 
    } 

    @Override 
    public void resize(int width, int height) { 
     viewportWidth = width; 
     viewportHeight = height; 
     aspectRatio = viewportHeight/viewportWidth; 
     update(); 
    } 

    @Override 
    public void render() { 
     if (isSingleTouched) { 

      // This gets the change in touch position and 
      // compensates for the aspect ratio. 
      if (x == -1 || y == -1 || justSingleTouched) { 
       x = Gdx.input.getX(); 
       y = Gdx.input.getY(); 
      } else { 
       dx = (x - Gdx.input.getX()); 
       dy = (y - Gdx.input.getY())/aspectRatio; 
      } 

      // This zooms when control is pressed. 
      if (controlIsPressed && dy > 0) { 
       scrollIn(); 
      } else if (controlIsPressed && dy < 0) { 
       scrollOut(); 
      } 

      // This translates the camera blender-style 
      // if shift is pressed. 
      // Note that this will look weird with a 
      // perspective camera. 
      else if (shiftIsPressed) { 
       translateTangentially(); 
      } 

      // Default is to rotate the object 
      // (actually rotate the camera about a sphere 
      // that surrounds the object). 
      else { 
       travelAround(); 
      } 

      x = Gdx.input.getX(); 
      y = Gdx.input.getY(); 

      justSingleTouched = false; 
     } 

     // this zooms when the mouse wheel is rotated 
     if (isScrollingUp) { 
      scrollIn(); 
      isScrollingUp = false; 
     } else if (isScrollingDown) { 
      scrollOut(); 
      isScrollingDown = false; 
     } 

     // Some key controls 
     if (Gdx.input.isKeyPressed(Keys.LEFT) || Gdx.input.isKeyPressed(Keys.A)) { 
      translateTangentially(1, 0); 
     } else if (Gdx.input.isKeyPressed(Keys.RIGHT) 
       || Gdx.input.isKeyPressed(Keys.D)) { 
      translateTangentially(-1, 0); 
     } 

     if (Gdx.input.isKeyPressed(Keys.UP) || Gdx.input.isKeyPressed(Keys.W)) { 
      translateTangentially(0, 1); 
     } else if (Gdx.input.isKeyPressed(Keys.DOWN) 
       || Gdx.input.isKeyPressed(Keys.S)) { 
      translateTangentially(0, -1); 
     } 

     update(); 
    } 

    // These methods create the pinch zoom 
    // and set some flags for logic in render method. 
    @Override 
    public boolean touchDown(int x, int y, int pointer, int button) { 
     // for pinch-to-zoom 
     numberOfFingers++; 
     if (numberOfFingers == 1) { 
      isSingleTouched = true; 
      justSingleTouched = true; 
      fingerOnePointer = pointer; 
      fingerOne.set(x, y, 0); 
     } else if (numberOfFingers == 2) { 
      isSingleTouched = false; 
      fingerTwoPointer = pointer; 
      fingerTwo.set(x, y, 0); 

      float distance = fingerOne.dst(fingerTwo); 
      lastDistance = distance; 
     } 
     return true; 
    } 

    @Override 
    public boolean touchDragged(int x, int y, int pointer) { 
     if (numberOfFingers > 1) { 
      if (pointer == fingerOnePointer) { 
       fingerOne.set(x, y, 0); 
      } 
      if (pointer == fingerTwoPointer) { 
       fingerTwo.set(x, y, 0); 
      } 

      float distance = fingerOne.dst(fingerTwo); 

      if (lastDistance > distance) { 
       scrollOut(); 
      } else if (lastDistance < distance) { 
       scrollIn(); 
      } 

      lastDistance = distance; 
      update(); 
     } 
     return true; 
    } 

    @Override 
    public boolean touchUp(int x, int y, int pointer, int button) { 
     isSingleTouched = false; 
     if (numberOfFingers == 1) { 
      Vector3 touchPoint = new Vector3(x, y, 0); 
      unproject(touchPoint); 
     } 
     numberOfFingers--; 

     // just some error prevention... clamping number of fingers (ouch! :-) 
     if (numberOfFingers < 0) { 
      numberOfFingers = 0; 
     } 

     lastDistance = 0; 
     return false; 
    } 

    // These methods set flags for logic in render method. 
    @Override 
    public boolean keyDown(int keycode) { 

     switch (keycode) { 
     case (Keys.SHIFT_LEFT): 
     case (Keys.SHIFT_RIGHT): 
      shiftIsPressed = true; 
      break; 
     case (Keys.CONTROL_LEFT): 
     case (Keys.CONTROL_RIGHT): 
      controlIsPressed = true; 
      break; 
     case (Keys.O): 
      this.up.set(0.0f, 1.0f, 0.0f); 
      this.position.set(0.0f, 0.0f, 30.0f); 
      this.lookAt(0, 0, 0); 
      this.update(); 
     } 
     return true; 
    } 

    @Override 
    public boolean keyUp(int arg0) { 
     shiftIsPressed = controlIsPressed = false; 
     return true; 
    } 

    @Override 
    public boolean scrolled(int direction) { 
     if (direction == -1) { 
      isScrollingUp = true; 
     } else if (direction == 1) { 
      isScrollingDown = true; 
     } 
     return true; 
    } 

    // The rest of the methods translate the camera. 
    public void scrollIn() { 
     float magnitude = 1.0f; 
     scrollIn(magnitude); 
    } 

    public void scrollIn(float magnitude) { 
     if (position.dst2(ORIGIN) > 2.0f) { 
      tmp.set(position); 
      tmp.nor(); 
      this.translate(-tmp.x * magnitude, -tmp.y * magnitude, -tmp.z 
        * magnitude); 
      update(); 
     } 
    } 

    public void scrollOut() { 
     float magnitude = 1.0f; 
     scrollOut(magnitude); 
    } 

    public void scrollOut(float magnitude) { 
     tmp.set(position); 
     tmp.nor(); 
     this.translate(tmp.x * magnitude, tmp.y * magnitude, tmp.z * magnitude); 
     update(); 
    } 

    private void travelAround() { 
     tmp.set(up); 
     rotateAround(ORIGIN, tmp, dx); 
     tmp.crs(position).nor(); 
     rotateAround(ORIGIN, tmp, dy); 
    } 

    private void translateTangentially() { 
     translateTangentially(dx, dy); 
    } 

    private void translateTangentially(float dx, float dy) { 
     tmp.set(up); 
     tmp.crs(position); 
     if (dx > 0) { 
      translate(tmp.x/15.0f, tmp.y/15.0f, tmp.z/15.0f); 
     } else if (dx < 0) { 
      translate(-tmp.x/15.0f, -tmp.y/15.0f, -tmp.z/15.0f); 
     } 

     if (dy > 0) { 
      translate(-up.x, -up.y, -up.z); 
     } else if (dy < 0) { 
      translate(up); 
     } 
    } 

} 
संबंधित मुद्दे