ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java OpenGL – 计算等轴测视图的正交平截头体

2019-06-28 10:49:13  阅读:184  来源: 互联网

标签:java opengl jogl


我正在试图弄清楚如何在Orthographic Projection下正确计算我的openGL场景的平截头体边界.我用来做的代码如下:

public void setFrustum(GL gl, GLU glu){

    double[] forwardAxis = properties.getForwardAxis();
    double[] leftAxis = VecMath.normalVector(properties.getUpDir(), forwardAxis);
    double[] upAxis = VecMath.normalVector(forwardAxis, leftAxis);

    double[] v = bounds.getWidthVector();

    double width = VecMath.magnitude(VecMath.project(v, leftAxis));
    double height = VecMath.magnitude(VecMath.project(v, upAxis));

    double modelRatio = width / height;
    double canvasRatio = properties.getAspectRatio();
    // -- height bigger than width --
    if (modelRatio < canvasRatio){
        // -- update width --
        width = height * canvasRatio;
    } else{
        // -- update height --
        height = width / canvasRatio;
    }

    double l = width / 2. * 1.15;
    double b = height / 2. * 1.15;
    double n = properties.getNear();
    double f = properties.getFar();
    gl.glOrtho(-l, l, -b, b, n, f);
}

所以你可以看到我得到了我的轴和我的宽度向量:

widthVector = (xWidth, yWidth, zWidth)

然后通过沿leftAxis和upAxis投影此宽度向量来获得gl场景的宽度和高度.然后我将aspectRatio与我正在显示此场景的画布匹配,并使用宽度和高度来计算正字截头体的边界(使用1.15比例因子添加填充).

除了等轴测视图外,这对所有视图都很有效.以下是这方面的一些屏幕截图:

BottomView
LeftView
FrontView

IsometricView

如您所见,底部,左侧和前部视图都很好.然而,等轴测视图被切断(并且在拍摄屏幕截图时没有我没有错误地剪辑它!).我必须将我使用的填充比例因子增加到1.5而不是1.15,但我必须在这里做错事.

任何帮助将不胜感激.谢谢!

解决方法:

这是我的fitAllIn简化版

public void fitAllIn(float[] boundingMinMaxWorldSpace) {

        Vec4 centerWorldSpace = new Vec4((boundingMinMaxWorldSpace[0] + boundingMinMaxWorldSpace[1]) / 2,
                (boundingMinMaxWorldSpace[2] + boundingMinMaxWorldSpace[3]) / 2,
                (boundingMinMaxWorldSpace[4] + boundingMinMaxWorldSpace[5]) / 2, 1f);

        Vec3 min = new Vec3(boundingMinMaxWorldSpace[0], boundingMinMaxWorldSpace[2], boundingMinMaxWorldSpace[4]);
        Vec3 max = new Vec3(boundingMinMaxWorldSpace[1], boundingMinMaxWorldSpace[3], boundingMinMaxWorldSpace[5]);

        float diameter = (float) Math.sqrt(
                (max.x - min.x) * (max.x - min.x)
                + (max.y - min.y) * (max.y - min.y)
                + (max.z - min.z) * (max.z - min.z));

        if (getCurrView().orthographicProj) {

            if (glViewer.getAspect() > 1) {
                // projection * scale = y
                getCurrView().scale = diameter / 2 / projectionSide;

            } else {
                // projection * aspect * scale = x
                getCurrView().scale = diameter / 2 / (projectionSide * glViewer.getAspect());
            }
            getCurrView().scale = viewScale.clampScale(projectionSide, getCurrView().scale);
        }
    getCurrView().targetPos = new Vec3(centerWorldSpace);

    glViewer.refresh();

基本上我通过了世界空间中的边界框,我计算了我的相机将要定位的中心,我计算了最小点(minX,minY,minZ)和最大点.我得到直径,然后是一个简单的方程来检索缩放.

scale和projectionSide稍后将用于制作我的正交矩阵

        float x = projectionSide * glViewer.getAspect() * getCurrView().scale;
        float y = projectionSide * getCurrView().scale;
        float z = projectionSide;

        return Jglm.orthographic(-x, x, -y, y, -z, z);

标签:java,opengl,jogl
来源: https://codeday.me/bug/20190628/1314743.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有