最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

graphics - Perspective projection for a 3D-engine in java - Stack Overflow

programmeradmin4浏览0评论

General about the project: I am trying to program my own 3D engine in java, but I have some issues with programming the camera right. What I have already programmed is a window and the 3d objects that can be displayed, rotate and do everything they need to. But as soon as I try to add a perspective to the camera (Perspective projection) something goes wrong and the object is not displayed right anymore.

Exact problem: The problem is that when the object rotates one of the points gets streched and the object is disformed. For example one point turns towards the camera and suddenly the tetraeda is out of shape:

This is how it looks without the perspective projection:

Here is the code of the two classes that calculate the displayed vectors: Calculates everything:

package Math;

import Objects.Triangle;
import Objects.Vector;

public class CalcView {
    // Updates all the meshes one by one
    public Triangle[] updateMesh(Triangle[] m, Camera cam, double time) {
        // I don't want to change the actual position of the object in the world, but only the displayed one
        Triangle[] nm = new Triangle[m.length];

        // Goes through all the meshes
        for (int i = 0; i < m.length; i++) {
            Triangle t = new Triangle(new Vector[3]);

            // This first changes the triangle by the wanted rotation in the axis
            // It's needed so that we don't just see one side of the object
            for (int j = 0; j < t.vectors.length; j++) {
                Rotate r = new Rotate();
                r.calcRotation(time);

                t.vectors[j] = vecMatToVec(m[i].vectors[j], r.rX); // X-Axis
                t.vectors[j] = vecMatToVec(t.vectors[j], r.rY); // Y-Axis
                t.vectors[j] = vecMatToVec(t.vectors[j], r.rZ); // Z-Axis
            }

            // After the object is rotated it's also moved by the camera position
            // I want to add a perspective projection matrix as well, but it doesn't work quite well yet
            for (int j = 0; j < t.vectors.length; j++) {
                //t.vectors[j] = cam.mProjToVec(t.vectors[j], cam.projMatrix);
                t.vectors[j] = moveVecByVec(t.vectors[j], cam.posCam);
            }

            nm[i] = t;
        }

        //printVectors(nm);

        return nm;
    }

    // This method moves a vector by another vector
    // Mostly needed to move the object by the position of the camera
    public static Vector moveVecByVec(Vector or, Vector mul) {
        Vector v = new Vector(0, 0, 0);

        for (int i = 0; i < or.vec.length; i++) v.vec[i] = or.vec[i] + mul.vec[i];

        return v;
    }

    // This is just a matrix-vector multiplication, which outputs a vector
    public Vector vecMatToVec(Vector i, double[][] m) {
        Vector v = new Vector(0, 0,0);

        for (int j = 0; j < 3; j++) v.vec[j] = i.vec[0] * m[0][j] + i.vec[1] * m[1][j] + i.vec[2] * m[2][j];

        return v;
    }

    // That's the same as in the meshes, but still only needed for debugging
    public void printVectors(Triangle[] t) {
        for (int i = 0; i < t.length; i++) {
            System.out.println("Triangle: " + i);

            for (int j = 0; j < 3; j++) {
                System.out.println(
                        "XYZ: " + t[i].vectors[j].vec[0] + " " + t[i].vectors[j].vec[1]+ " " + t[i].vectors[j].vec[2]);
            }

            System.out.println(" ");
        }
    }
}

And here is the camera:

package Math;

import Objects.Vector;

public class Camera {
    public double[][] projMatrix;

    public Vector posCam;

    // Screen width and height, used for the ratio
    public int sWidth = 690;
    public int sHeight = 690;

    public double r = sWidth / sHeight; // = r

    // Some settings of the camera
    public double dNear = 0.01;
    public double dFar = 100;
    public double fov = 90;

    public Camera() {
        // Sets the position of the camera in space
        // The starting object should be in the middle, so everything is moved by half the screen
        // The middle of the screen marks the origin (0 | 0)
        posCam = new Vector(sWidth / 2, sHeight / 2, 0);

        setProjection();
    }

    // This a perspective projection matrix, which is used to simulate the view of a camera
    // Some things here are wrong and I still need to correct them
    public void setProjection() {
        double s = (1 / Math.tan(Math.toRadians(fov / 2)));
        double range = dNear - dFar;

        projMatrix = new double[][] {
                {1 / (s * r), 0, 0, 0},
                {0, 1 / s, 0, 0},
                {0, 0, -range / range, 2 * dFar * dNear / range},
                {0, 0, 1, 0}
        };
    }

    // This method is used to update the meshes and their view relative to the camera
    public Vector mProjToVec(Vector i, double[][] m) {
        Vector v = new Vector(0, 0,0);

        for (int j = 0; j < 3; j++) v.vec[j] = i.vec[0] * m[0][j] + i.vec[1] * m[1][j] + i.vec[2] * m[2][j] + m[3][j];

        double w = i.vec[0] * m[0][3] + i.vec[1] * m[1][3] + i.vec[2] * m[2][3] + m[3][3];

        if (w != 0) {
            v.vec[0] /= w;
            v.vec[1] /= w;
            v.vec[2] /= w;
        }

        return v;
    }
}

I think the issue has something to do with the z-axis and the location of the camera, but I am not sure and don't know how to fix it.

If you need the rest of the code from the project: (The code from these two classes need to be updates though, as it's not updated yet)

发布评论

评论列表(0)

  1. 暂无评论