我正在使用Java 3D API编写一个小游戏,并且使用javax.media.j3d.BoundingBox对象存储模型的边界。

BoundingBox的构造函数如下:

public BoundingBox(Point3d lower, Point3d upper) {
    boundId = BOUNDING_BOX;
    this.lower = new Point3d(lower);
    this.upper = new Point3d(upper);
    updateBoundsStates();
}


现在,我想平移和旋转BoundingBox,因为模型本身可以,并且我使用以下BoundingBox方法:

/**
 * Transforms this bounding box by the given matrix.
 * @param matrix a transformation matrix
 */
public void transform(Transform3D matrix) {
    if(boundsIsInfinite)
        return;

    if (tmpP3d == null)
        tmpP3d = new Point3d();

    double ux, uy, uz, lx, ly, lz;
    ux = upper.x;
    uy = upper.y;
    uz = upper.z;

    lx = lower.x;
    ly = lower.y;
    lz = lower.z;

    tmpP3d.set(ux, uy, uz);
    matrix.transform( tmpP3d );

    upper.x = tmpP3d.x;
    upper.y = tmpP3d.y;
    upper.z = tmpP3d.z;

    lower.x = tmpP3d.x;
    lower.y = tmpP3d.y;
    lower.z = tmpP3d.z;

    tmpP3d.set(lx, uy, uz);
    matrix.transform( tmpP3d );

    if ( tmpP3d.x  > upper.x ) upper.x = tmpP3d.x;
    if ( tmpP3d.y  > upper.y ) upper.y = tmpP3d.y;
    if ( tmpP3d.z  > upper.z ) upper.z = tmpP3d.z;

    if ( tmpP3d.x  < lower.x ) lower.x = tmpP3d.x;
    if ( tmpP3d.y  < lower.y ) lower.y = tmpP3d.y;
    if ( tmpP3d.z  < lower.z ) lower.z = tmpP3d.z;

    tmpP3d.set(lx, ly, uz);
    matrix.transform( tmpP3d );

    if ( tmpP3d.x  > upper.x ) upper.x = tmpP3d.x;
    if ( tmpP3d.y  > upper.y ) upper.y = tmpP3d.y;
    if ( tmpP3d.z  > upper.z ) upper.z = tmpP3d.z;

    if ( tmpP3d.x  < lower.x ) lower.x = tmpP3d.x;
    if ( tmpP3d.y  < lower.y ) lower.y = tmpP3d.y;
    if ( tmpP3d.z  < lower.z ) lower.z = tmpP3d.z;

    tmpP3d.set(ux, ly, uz);
    matrix.transform( tmpP3d );

    if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x;
    if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y;
    if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z;

    if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x;
    if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y;
    if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z;

    tmpP3d.set(lx, uy, lz);
    matrix.transform( tmpP3d );

    if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x;
    if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y;
    if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z;

    if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x;
    if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y;
    if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z;

    tmpP3d.set(ux, uy, lz);
    matrix.transform( tmpP3d );

    if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x;
    if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y;
    if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z;

    if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x;
    if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y;
    if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z;

    tmpP3d.set(lx, ly, lz);
    matrix.transform( tmpP3d );

    if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x;
    if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y;
    if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z;

    if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x;
    if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y;
    if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z;

    tmpP3d.set(ux, ly, lz);
    matrix.transform( tmpP3d );

    if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x;
    if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y;
    if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z;

    if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x;
    if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y;
    if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z;

    if (VirtualUniverse.mc.releaseBoundingBoxMemory) {
        // Free memory
        tmpP3d = null;
    }
}


但是:如果使用此方法旋转BoundingBox,它将生成一个新的BoundingBox,其体积可能大于旧的BoundingBox。仅当您精确旋转90、180、270或360度时,它才会提供相同的音量。

附加信息:我必须手动计算BoundingBox,因为我通过在模型上调用setAutoComputeBounds(false)和setBounds(XYZ)使用手动边界(而不是太大的自动计算的边界)(在这种情况下,它实际上是javax的一个实例)。 media.j3d指向javax.media.j3d.SharedGroup),并且在转换/旋转相应模型的情况下,Java 3d Engine(至少在这种情况下)似乎不会自动重新计算手动边界。

我的问题是:我应该如何(重新)实现上面显示的方法transform()以获得始终具有相同体积的BoundingBoxes?

最佳答案

实际上,无论BoundingBox的两个点在哪里,它都始终与轴对齐。两点不能定义任意立方体。无论您如何重写转换函数,它都将无法工作。

您可以考虑BoundingPolytope类。尽管它确实具有接受另一个Bounds对象的构造函数,但它提供了由平面形成的更一般的边界,因此您实际上不必自己定义平面。

09-27 08:18