bekomme die Camera Bewegung nich richtig hin

Started by webster, March 10, 2013, 05:59:25 PM

Previous topic - Next topic

webster

Hallo,

leider schaff ich es nicht die Camera so zu bewegen wie ich es gerne hätte.
Mit gedrückter linker Maustaste sollte die Camera auf der z-Achse über ein Spielfeld vor und zurück fahren (y-koordinaten der Maus) oder sich nach rechts oder links über das Spielfeld bewegen (x-koordinate der Maus).
Mit gedrückter rechter Maustaste sollte die Kamera um das Spielfeld kreisen. Dabei sollte die x-koordinate (genauer delta-x) der Maus die Rotation um die y-Achse des Spielfeldes bestimmen, während delta-y vom mousedragged event den Sichtwinkel auf das Spielfeld manipuliert, also eigentlich eine Rotation um die x-Achse der aktuellen Blickrichtung. Was nicht passieren sollte, dass das Spielfeld in der z-Achse kippt (das Spielfeld bewegt sich ja garnicht, ich meine die Sicht auf das Spielfeld).
Hoffentlich kann man das jetzt verstehen, aber viele Spiele (z. B. Black and White) haben eine ähnliche Steuerung.
Das Verhalten mit gedückter linker Maustaste funktioniert, solange keine Rotation der Camera mit der rechten Maustaste ausgeführt wurde. Wenn sich aber die Camera um 90 Grad um das Spielfeld gedreht hat, bewegt sich die Camera nicht mehr seitlich, sonder vor und zurück wenn der mousedragged event ein delta-x produziert und umgekehrt. Die Rotation der Blickrichtung um die x-Achse bekomme ich überhaupt nicht hin. Genug gelabbert, hier ist mein Code:

import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;

import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Lights;
import com.threed.jpct.Matrix;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.Light;

public class CameraMoveDemo {
private static float PI = (float) Math.PI;
private static SimpleVector direction = null;
private static float distance = 100;
private static Matrix camBack = null;

private FrameBuffer buffer = null;
private World world = null;
private Object3D plane = null;
private Light sun = null;

private Ticker ticker = new Ticker(15);

public static void main(String[] args) throws Exception {
Config.glVerbose = true;
CameraMoveDemo cd = new CameraMoveDemo();
cd.init();
cd.gameLoop();
}

public CameraMoveDemo() {
Config.glAvoidTextureCopies = true;
Config.maxPolysVisible = 1000;
Config.glColorDepth = 24;
Config.glFullscreen = false;
Config.farPlane = 4000;
Config.glShadowZBias = 0.8f;
Config.lightMul = 1;
Config.collideOffset = 500;
Config.glTrilinear = true;
}

private void init() throws Exception {
// Initialize frame buffer
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL, IRenderer.MODE_OPENGL);

// Load textures
TextureManager tm = TextureManager.getInstance();
tm.addTexture("playground", new Texture("resources/playground.gif"));

// Initialize worlds
world = new World();
world.setAmbientLight(30, 30, 30);
world.getLights().setRGBScale(Lights.RGB_SCALE_2X);

// Load/create and setup objects
plane = Primitives.getPlane(20, 10);
plane.rotateX(PI / 2f);
plane.setSpecularLighting(true);
plane.setTexture("playground");

// Add objects to the worlds
world.addObject(plane);

// Build all world's objects
world.buildAllObjects();

// Setup dynamic light source
sun = new Light(world);
sun.setPosition(new SimpleVector(.0f, 10.f, 0.0f));
sun.setIntensity(250, 250, 250);
// sun.setAttenuation(800);

// Move camera
Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, distance + 50);
cam.moveCamera(Camera.CAMERA_MOVEUP, distance);
cam.lookAt(plane.getTransformedCenter());
direction = cam.getDirection();
camBack = cam.getBack();
System.out.println("plane-center=" + plane.getTransformedCenter());
System.out.println("cam-position=" + cam.getPosition());
System.out.println("cam-direction=" + direction);

Mouse.create();
}

private void move(long ticks) {
if (ticks == 0) {
return;
}
int x = Mouse.getDX();
int y = Mouse.getDY();
int w = Mouse.getDWheel();
Camera cam = world.getCamera();
if (Mouse.isButtonDown(0) && Mouse.isInsideWindow()) {
// camBack.translate(new SimpleVector(x * ticks, 0, y * ticks));
SimpleVector pos = cam.getPosition();
pos.add(new SimpleVector(-x * ticks, 0, -y * ticks));
cam.setPosition(pos);
}
if (Mouse.isButtonDown(1) && Mouse.isInsideWindow()) {
direction.length();
cam.moveCamera(Camera.CAMERA_MOVEIN, distance);
cam.rotateX(direction.y);
cam.rotateY(x * .01f * ticks);
cam.rotateX(-direction.y);
// direction = cam.getDirection();
// cam.rotateY(direction.x);
// cam.rotateX(y * .01f * ticks);
// cam.rotateY(-direction.x);
// direction = cam.getDirection();
cam.moveCamera(Camera.CAMERA_MOVEOUT, distance);

}

if (w != 0) {
float d = w * .1f;
distance -= d;
cam.moveCamera(Camera.CAMERA_MOVEIN, d);
}
}

private void gameLoop() throws Exception {
long ticks = 0;
while (!Display.isCloseRequested()) {
ticks = ticker.getTicks();
if (ticks > 0) {
// move the camera
move(ticks);
}
buffer.clear();
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.displayGLOnly();
}
Mouse.destroy();
System.exit(0);
}

private static class Ticker {

private int rate;
private long s2;

public static long getTime() {
return System.currentTimeMillis();
}

public Ticker(int tickrateMS) {
rate = tickrateMS;
s2 = Ticker.getTime();
}

public int getTicks() {
long i = Ticker.getTime();
if (i - s2 > rate) {
int ticks = (int) ((i - s2) / (long) rate);
s2 += (long) rate * ticks;
return ticks;
}
return 0;
}
}
}

Wahrscheinlich kann man alles mit ein paar Zeilen Code hinbekommen, wenn man nur die back-Matrix der Camera richtig manipuliert, ich habe leider keine Ahnung welche Manipulationen zum Ziel führen. Irgenwie habe ich das Gefühl, dass dafür eine weiter Matrix nötig ist, welche Zwischenergebnisse speichert.
Hoffentlich kann mir jemand helfen.
Viele Grüsse
Roland

EgonOlsen

Also so ganz konnte ich jetzt folgen... ;) Aber was die Bewegung angeht: Das Koordinatensystem der Kamera ändert sich auch bei einer Drehung nicht. D.h. was vorher vielleicht eine Bewegung nach links und recht war, wird nach einer 90°-Drehung eine Bewegung vor und zurück, einfach weil die Kamera jetzt relativ zu dem fixen Koordinatensystem anders steht. Für Bewegungen relativ zur Drehung/Position gibt es die get?Axis()-Methoden in Camera. Eine Bewegung entlang des Vektors von getXAxis() wird die Kamera z.B. immer nach rechts bewegen (relativ zur Blickrichtung). Vielleicht hilft das erstmal weiter!?

webster

Hallo Egon,

erstmal vielen Dank für die schnelle Antwort.
Quote
Das Koordinatensystem der Kamera ändert sich auch bei einer Drehung nicht. D.h. was vorher vielleicht eine Bewegung nach links und recht war, wird nach einer 90°-Drehung eine Bewegung vor und zurück, einfach weil die Kamera jetzt relativ zu dem fixen Koordinatensystem anders steht.
Das ist genau mein Problem, leider habe ich die gedachte Camerabewegung noch nicht hinbekommen.
Wenn ich also in einem bestimmten Winkel (x= 30, y = 0,  z=0) auf die Spielfläche schau und dann eine 90 Grad Drehung um die Y-Achse auslöse, erscheint die Scene für den Betrachter so, als hätte sich die Spielfläche in der Z-Achse um 30 Grad gekippt. Man muss also bei einer Drehung (bsp. Y-Achse) die beiden anderen (Blick)-Achsen auch anpassen, damit für den Betrachter der Eindruck erhalten bleibt er würde im selben Winkel auf die Spielfläche schauen (abgesehen von der Rotation um die Y-Achse).
Keine Ahnung wie ich dafür direction- und point-vector der Camera manipulieren muss.

Viele Grüsse
Roland

webster

Hi nochmals,

hat sich erstmal erledigt. Ich hab einfach die Rotation aus den AdvancedExample übernommen und vorher noch die z-position auf 0 gesetzt und nachher die z-position zurück gesetzt.
Das macht genau das was ich wollte.

Viele Grüsse
Roland