我正在用 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,它的体积可能比旧的要大。如果您精确旋转 90、180、270 或 360 度,它只会提供相同的音量。
附加信息:我必须手动计算 BoundingBox,因为我通过在模型上调用 setAutoComputeBounds(false) 和 setBounds(XYZ) 来使用手动边界(而不是自动计算的太大的边界)(在这种情况下,它实际上是 javax. media.j3d 指向 javax.media.j3d.SharedGroup),并且似乎 Java 3d 引擎(至少在这种情况下)在相应模型的平移/旋转的情况下不会自动重新计算您的手动边界。
我的问题是:我必须如何(重新)实现上面显示的方法 transform() 以获得始终具有相同体积的边界框?