/** * Offsets this bounding box by a given amount and returns a new box. * * @param x The amount of offset for the x coordinate * @param y The amount of offset for the y coordinate * @param z The amount of offset for the z coordinate * @return The new offset box */ public AABB offset(double x, double y, double z) { return new AABB(this.min.add(x, y, z), this.max.add(x, y, z)); }
private Vector3d getXyNormal() { if (this.xyNormal == null) { this.xyNormal = this.xNormal.add(this.yNormal).normalize(); } return this.xyNormal; }
private Vector3d getXzNormal() { if (this.xzNormal == null) { this.xzNormal = this.xNormal.add(this.zNormal).normalize(); } return this.xzNormal; }
private Vector3d getYzNormal() { if (this.yzNormal == null) { this.yzNormal = this.yNormal.add(this.zNormal).normalize(); } return this.yzNormal; }
/** * Add vector components to the position on this instance, returning a new * Location instance. * * @param x The x component * @param y The y component * @param z The z component * @return A new instance */ public Location<E> add(double x, double y, double z) { return setPosition(getPosition().add(x, y, z)); }
/** * Returns the center of the box, halfway between each corner. * * @return The center */ public Vector3d getCenter() { if (this.center == null) { this.center = this.min.add(getSize().div(2)); } return this.center; }
/** * Expands this bounding box by a given amount in both directions and * returns a new box. The expansion is applied half and half to the * minimum and maximum corners. * * @param x The amount of expansion for the x coordinate * @param y The amount of expansion for the y coordinate * @param z The amount of expansion for the z coordinate * @return The new expanded box */ public AABB expand(double x, double y, double z) { x /= 2; y /= 2; z /= 2; return new AABB(this.min.sub(x, y, z), this.max.add(x, y, z)); }
/** * Adds a translation to this transform. * * <p>Returns the results as a new copy.</p> * * @param translation The translation to add * @return A new transform */ public Transform<E> addTranslation(Vector3d translation) { checkNotNull(translation, "translation"); return new Transform<>(getExtent(), getPosition().add(translation), getRotation(), getScale()); }
private static AABB newAABB() { final Vector3d min = new Vector3d(RANDOM.nextDouble() * 20 - 10, RANDOM.nextDouble() * 20 - 10, RANDOM.nextDouble() * 20 - 10); return new AABB(min, min.add(RANDOM.nextDouble() * 4 + 4, RANDOM.nextDouble() * 4 + 4, RANDOM.nextDouble() * 4 + 4)); }
private static AABB newIntersectingAABB(AABB with) { final Vector3d wMin = with.getMin(); final Vector3d wSize = with.getSize(); final double iSizeX = RANDOM.nextDouble() * wSize.getX(); final double iSizeY = RANDOM.nextDouble() * wSize.getY(); final double iSizeZ = RANDOM.nextDouble() * wSize.getZ(); final double eSizeX = RANDOM.nextDouble() * 4 + 4; final double eSizeY = RANDOM.nextDouble() * 4 + 4; final double eSizeZ = RANDOM.nextDouble() * 4 + 4; final Vector3d min = wMin.sub(eSizeX, eSizeY, eSizeZ); final Vector3d max = wMin.add(iSizeX, iSizeY, iSizeZ); return new AABB(min, max); }
/** * "Adds" another transform to this one. This is equivalent to adding the * translation, rotation and scale individually. * * <p>Returns the results as a new copy.</p> * * @param other The transform to add * @return A new transform */ public Transform<E> add(Transform<E> other) { checkNotNull(other, "other"); return new Transform<>( getExtent(), getPosition().add(other.getPosition()), toAxesAngles(other.getRotationAsQuaternion().mul(getRotationAsQuaternion())), getScale().mul(other.getScale()) ); }
/** * Returns a new transform representing a rotation around an axis, * around a given point. The rotation is given is quarter turns. * The actual rotation is {@code quarterTurns * 90}. The block corner * flag change the point to be the block corner instead of the center. * * @param quarterTurns The number of quarter turns in this rotation * @param axis The axis to rotate around * @param point The point of rotation, as block coordinates * @param blockCorner Whether or not to use the corner of the block * instead of the center * @return The new rotation transform */ public static DiscreteTransform3 fromRotation(int quarterTurns, Axis axis, Vector3i point, boolean blockCorner) { Vector3d pointDouble = point.toDouble(); if (blockCorner) { pointDouble = pointDouble.add(0.5, 0.5, 0.5); } return new DiscreteTransform3(Matrix4d.createTranslation(pointDouble.negate()).rotate(Quaterniond.fromAngleDegAxis(quarterTurns * 90, axis .toVector3d())).translate(pointDouble)); }
/** * Adds a a rotation to this transform, around an axis, * around a given point, and returns it as a new transform. * The rotation is given is quarter turns. The actual rotation * is {@code quarterTurns * 90}. The block corner flag changes * the point to be the block upper corner instead of the center. * * @param quarterTurns The number of quarter turns in this rotation * @param axis The axis to rotate around * @param point The point of rotation, as block coordinates * @param blockCorner Whether or not to use the corner of the block * instead of the center * @return The rotated transform as a copy */ public DiscreteTransform3 withRotation(int quarterTurns, Axis axis, Vector3i point, boolean blockCorner) { Vector3d pointDouble = point.toDouble(); if (blockCorner) { pointDouble = pointDouble.add(0.5, 0.5, 0.5); } return new DiscreteTransform3( this.matrix.translate(pointDouble.negate()).rotate(Quaterniond.fromAngleDegAxis(quarterTurns * 90, axis.toVector3d())) .translate(pointDouble)); }
@Test public void testIntersectsAABB() { for (int i = 0; i < 1000; i++) { final AABB aabb1 = newAABB(); final AABB aabb2 = newIntersectingAABB(aabb1); final AABB aabb3 = aabb2.offset(aabb1.getSize().add(aabb2.getSize())); Assert.assertTrue(aabb1.intersects(aabb2)); Assert.assertTrue(aabb2.intersects(aabb1)); Assert.assertFalse(aabb1.intersects(aabb3)); Assert.assertFalse(aabb3.intersects(aabb1)); } }
@Test public void testLocation() { final Vector3d position1 = new Vector3d(1, 2, 3); final Vector3d position2 = new Vector3d(4, 5, 6); Transform<Extent> transform = new Transform<>(this.mockExtent1, position1); Assert.assertEquals(this.mockExtent1, transform.getExtent()); assertEquals(position1, transform.getPosition()); transform = transform.setLocation(new Location<>(this.mockExtent2, position2)); Assert.assertEquals(this.mockExtent2, transform.getExtent()); assertEquals(position2, transform.getPosition()); transform = transform.setExtent(this.mockExtent1); Assert.assertEquals(this.mockExtent1, transform.getExtent()); transform = transform.setPosition(position1); assertEquals(position1, transform.getPosition()); transform = transform.addTranslation(position2); assertEquals(position1.add(position2), transform.getPosition()); }
/** * Returns the center of the box, halfway between each corner. * * @return The center */ public Vector3d getCenter() { if (this.center == null) { this.center = this.min.add(getSize().div(2)); } return this.center; }