2016-06-11 16 views
1

Vor ein paar Wochen habe ich beschlossen, meine eigene einfache 3D-Spiel-Engine zu machen. Ich habe ein paar Tutorials online verfolgt, und ich habe mir viele Videos angesehen, und bis jetzt habe ich einen ziemlich guten Motor bekommen. Aber ich habe ein Problem. Wenn ich ein Objekt rotiere oder skaliere, scheint es, dass sein Mittelpunkt die obere linke Ecke des Bildschirms ist, anstatt seinen wirklichen Mittelpunkt. Wenn ich zum Beispiel ein Objekt rotiere, dreht es sich um den linken Bildschirmrand, und wenn ich es skaliere, wird es zur Ecke des Bildschirms oder von der Ecke des Bildschirms weg skaliert. Hier ist mein Code:Warum gibt meine Rotationsmatrix eine zusätzliche Übersetzung?

Mesh-Klasse

package com.cub.cubefront.mesh; 

import com.cub.cubefront.math.Matrix4f; 
import com.cub.cubefront.math.Vector3f; 

public class Mesh { 

    private Vector3f[] verts; 
    private Vector3f center; 

    private double rotX = 0; 
    private double rotY = 0; 
    private double rotZ = 0; 

    private double scaleX = 1; 
    private double scaleY = 1; 
    private double scaleZ = 1; 

    private double translateX = 0; 
    private double translateY = 0; 
    private double translateZ = 0; 

public Mesh(int arg0) { 
    verts = new Vector3f[arg0]; 
} 

public Vector3f getVertexAt(int arg0) { 
    return verts[arg0 - 1]; 
} 

public Vector3f[] getVerticies() { 
    return verts; 
} 

public int getVerticiesCount() { 
    return verts.length; 
} 

public void setVertexAt(int arg0, Vector3f arg1) { 
    verts[arg0 - 1] = arg1; 
} 

public void setRotationPoint(Vector3f arg0) { 
    this.center = arg0; 
} 

public Vector3f getRotationPoint() { 
    return center; 
} 

public Vector3f getCenter() { 
    int arg0 = verts.length; 
    double centerX = 0; 
    double centerY = 0; 
    double centerZ = 0; 
    for (int i = 0; i < arg0; i++) { 
     centerX += verts[i].getX(); 
     centerY += verts[i].getY(); 
     centerZ += verts[i].getZ(); 
    } 
    return new Vector3f((float)(centerX/arg0), (float)(centerY/arg0), (float)(centerZ/arg0)); 
} 

public void rotateX(double arg0) { 
    this.rotX += Math.toRadians(arg0); 
} 

public void setRotationX(double arg0) { 
    this.rotX = Math.toRadians(arg0); 
} 

public Matrix4f getXRotationAsMatrix() { 
    return new Matrix4f(new double[][] { // YZ rotation matrix (X) 
     { 1, 0, 0, 0 }, 
     { 0, Math.cos(rotX), Math.sin(rotX), 0 }, 
     { 0, -Math.sin(rotX), Math.cos(rotX), 0 }, 
     { 0, 0, 0, 1 } 
    }); 
} 

public Matrix4f getZRotationAsMatrix() { 
    return new Matrix4f(new double[][] { // XY rotation matrix (Z) 
     { Math.cos(rotZ), -Math.sin(rotZ), 0, 0 }, 
     { Math.sin(rotZ), Math.cos(rotZ), 0, 0 }, 
     { 0, 0, 1, 0 }, 
     { 0, 0, 0, 1 } 
    }); 
} 

public void rotateY(double arg0) { 
    this.rotY += Math.toRadians(arg0); 
} 

public void setRotationY(double arg0) { 
    this.rotY = Math.toRadians(arg0); 
} 

public Matrix4f getYRotationAsMatrix() { 
    return new Matrix4f(new double[][] { // XZ rotation matrix (Y) 
     { Math.cos(rotY), 0, Math.sin(rotY), 0 }, 
     { 0, 1, 0, 0 }, 
     { -Math.sin(rotY), 0, Math.cos(rotY), 0}, 
     { 0, 0, 0, 1 } 
    }); 
} 

public void setRotationZ(double arg0) { 
    this.rotZ = Math.toRadians(arg0); 
} 

public void rotateZ(double arg0) { 
    this.rotZ += Math.toRadians(arg0); 
} 

public Matrix4f getRotation() { 
    return getZRotationAsMatrix().multiply(getXRotationAsMatrix()).multiply(getYRotationAsMatrix()); 
} 

public void setScaleX(double arg0) { 
    this.scaleX = arg0; 
} 

public void scaleX(double arg0) { 
    this.scaleX += arg0; 
} 

public double getScaleX() { 
    return scaleX; 
} 

public void setScaleY(double arg0) { 
    this.scaleY = arg0; 
} 

public void scaleY(double arg0) { 
    this.scaleY += arg0; 
} 

public double getScaleY() { 
    return scaleY; 
} 

public void setScaleZ(double arg0) { 
    this.scaleZ = arg0; 
} 

public void scaleZ(double arg0) { 
    this.scaleZ += arg0; 
} 

public double getScaleZ() { 
    return scaleZ; 
} 

public void setScale(double arg0) { 
    setScaleX(arg0); 
    setScaleY(arg0); 
    setScaleZ(arg0); 
} 

public void setScale(double[][] arg0) { 
    this.scaleX = arg0[0][0]; 
    this.scaleY = arg0[1][1]; 
    this.scaleZ = arg0[2][2]; 
} 

public void setScale(Matrix4f arg0) { 
    this.scaleX = arg0.getValueAt(0, 0); 
    this.scaleY = arg0.getValueAt(1, 1); 
    this.scaleZ = arg0.getValueAt(2, 2); 
} 

public void scale(double arg0) { 
    scaleX(arg0); 
    scaleY(arg0); 
    scaleZ(arg0); 
} 

public Matrix4f getScale() { 
    return new Matrix4f(new double[][] { 
      { getScaleX(), 0, 0, 0 }, 
      { 0, getScaleY(), 0, 0 }, 
      { 0, 0, getScaleZ(), 0 }, 
      { 0, 0, 0, 1 } 
    }); 
} 

public void translateX(double arg0) { 
    this.translateX += arg0; 
} 

public void translateY(double arg0) { 
    this.translateY += arg0; 
} 

public void translateZ(double arg0) { 
    this.translateZ += arg0; 
} 

public Matrix4f getTranslation() { 
    return new Matrix4f(new double[][] { 
     { 1, 0, 0, translateX }, 
     { 0, 1, 0, translateY }, 
     { 0, 0, 1, translateZ }, 
     { 0, 0, 0, 1 } 
    }); 
} 

} 

Szene Klasse

package com.cub.cubefront; 

import com.cub.cubefront.graphics.Bitmap; 
import com.cub.cubefront.input.InputHandler; 
import com.cub.cubefront.math.Matrix4f; 
import com.cub.cubefront.math.Vector2f; 
import com.cub.cubefront.math.Vector3f; 
import com.cub.cubefront.mesh.Camera; 
import com.cub.cubefront.mesh.Mesh; 

public class Scene extends Bitmap { 

private Camera defaultCam; 

public InputHandler input = new InputHandler(); 

public Scene() { 
    super(MainEngine.getWidth(), MainEngine.getHeight()); 
    defaultCam = new Camera(); 
} 

public void update() { } 

public void start() { } 

public void render() { } 

public void render(Mesh arg0) { 
    Matrix4f trans = arg0.getRotation().multiply(arg0.getScale().multiply(arg0.getTranslation())); 
    for (int i = 1; i < arg0.getVerticiesCount()+1; i++) { // Depth: Manipulate x and y with z 
     Vector3f v1 = trans.transform(arg0.getVertexAt(i)); 
     for (int n = 1; n < i; n++) { 
      Vector3f v2 = trans.transform(arg0.getVertexAt(n)); 
      drawLine(
       new Vector2f((v1.getX()), (v1.getY())), 
       new Vector2f((v2.getX()), (v2.getY())) 
      ); 
     } 
    } 
} 

public void clear() { 
    for (int i = 0; i < pixels.length; i++) { 
     pixels[i] = 0; 
    } 
} 

public Camera getCamera() { 
    return defaultCam; 
} 

public void setCamera(Camera defaultCam) { 
    this.defaultCam = defaultCam; 
} 

}

Matrix4f Klasse

package com.cub.cubefront.math; 

public class Matrix4f { 

private double[][] values; 

public Matrix4f() { 
    values = new double[4][4]; 
    setValues(); 
} 

public Matrix4f(double[][] arg0) { 
    setValues(arg0); 
} 

private Matrix4f setValues() { 
    values[0][0] = 1; values[0][1] = 0; values[0][2] = 0; values[0][3] = 0; 
    values[1][0] = 0; values[1][1] = 1; values[1][2] = 0; values[1][3] = 0; 
    values[2][0] = 0; values[2][1] = 0; values[2][2] = 1; values[2][3] = 0; 
    values[3][0] = 0; values[3][1] = 0; values[3][2] = 0; values[3][3] = 1; 
    return this; 
} 

public Matrix4f multiply(Matrix4f arg0) { 
    double res[][] = new double[4][4]; 
    for (int i = 0; i < 4; i++) { 
     for (int j = 0; j < 4; j++) { 
      for (int k = 0; k < 4; k++) { 
       res[i][j] += values[i][k] * arg0.getValueAt(k, j); 
      } 
     } 
    } 

    return new Matrix4f(res); 
} 

public double[][] getValues() { 
    return values; 
} 

public double getValueAt(int arg0, int arg1) { 
    return values[arg0][arg1]; 
} 

public void setValues(double[][] arg0) { 
    this.values = arg0; 
} 

public void setValueAt(int arg0, int arg1, double arg2) { 
    values[arg0][arg1] = arg2; 
} 

public Vector3f transform(Vector3f arg0) { 
    return new Vector3f(
     (float)(arg0.getX() * values[0][0] + arg0.getY() * values[1][0] + arg0.getZ() * values[2][0]), 
     (float)(arg0.getX() * values[0][1] + arg0.getY() * values[1][1] + arg0.getZ() * values[2][1]), 
     (float)(arg0.getY() * values[0][2] + arg0.getY() * values[1][2] + arg0.getZ() * values[2][2]) 
    ); 
} 

} 

Bitte schauen Sie sich diese Bilder, wenn Sie noch don‘ Ich weiß wh Ich meine.

Bild # 1:

Still Triangle

Bild # 2:

Triangle Rotated 30 Degrees

Siehst du, wie es dreht sich um die Ecke statt seiner Mitte? Danke für deine Mühe, zu helfen!

Antwort

0

Dies passiert normalerweise, wenn Sie Transformationen durchführen, ohne Ihr Objekt auf Ursprung zurückzusetzen, bevor Sie es beeinflussen. Denken Sie daran, dass Matrix-Reihenfolge wichtig ist. Rotationen finden relativ zum Ursprung statt. Wenn sich Ihr Objekt also nicht auf Origin befindet, wird es sich merkwürdig drehen.

Versuchen Sie, es nach der Übersetzung zu (0,0,0) zu drehen. Dann wenden Sie die gewünschte Übersetzung auf das Dreieck an (Das heißt übersetzt in Ursprung, drehen, zurück zur ursprünglichen Position).

Ich hoffe, es hilft.

EDIT

Im Allgemeinen, wenn Sie ein Polygon nahe einem festen Punkt drehen möchten, sollten Sie das Polygon in einer solchen Art und Weise übersetzen, dass der gewünschte Punkt in (0,0,0) ist. Dann mit Drehung fortfahren und schließlich zur ursprünglichen Position zurückkehren.

Angenommen, Sie haben ein Dreieck mit Vertex (1,1), (3,1) und (2,3). Wenn Sie dieses Dreiecks um das Zentrum drehen möchten (die (2,2) ist) sollten Sie:

  1. Substract (2,2) von jedem Scheitelpunkt (Herstellung (2,2) der Ursprung)
  2. Dann drehen Sie den gewünschten Winkel
  3. hinzufügen (2,2) zu jedem Scheitelpunkt, Rückkehr zur ursprünglichen Position.

Die gleichen Prinzipien gelten für 3 Dimensionen.

+1

Danke, ich habe die kleine Übersetzung hinzugefügt und es hat gut funktioniert. –

+1

Warte, eigentlich, egal, wenn ich die Form auf den Ursprung setze, rotiert sie immer noch herum, sie fixiert nur den Teil des Teils. Wenn du nicht verstehst, was ich sagen will, werde ich ein anderes Bild veröffentlichen, wie es sein soll. –

+0

Ich denke, ich verstehe dich. Sie sollten '(0,0,0)' den Fixpunkt machen, an dem Sie rotieren möchten. Wenn Sie möchten, dass eine Ecke dieser Fixpunkt ist, dann machen Sie diesen Eckpunkt '(0,0,0)' und übersetzen Sie die anderen entsprechend. Wenn Sie möchten, dass der Mittelpunkt des Dreiecks der Fixpunkt dasselbe tut (berechnen Sie den Mittelpunkt, machen Sie den Mittelpunkt, drehen Sie, kehren Sie zur Position zurück) – DarkCygnus

Verwandte Themen