final double txMax; final Vector3d xNormal; if (Math.copySign(1, direction.getX()) > 0) { txMin = (this.min.getX() - start.getX()) / direction.getX(); txMax = (this.max.getX() - start.getX()) / direction.getX(); xNormal = Vector3d.UNIT_X; } else { txMin = (this.max.getX() - start.getX()) / direction.getX(); txMax = (this.min.getX() - start.getX()) / direction.getX(); xNormal = Vector3d.UNIT_X.negate(); final double tyMax; final Vector3d yNormal; if (Math.copySign(1, direction.getY()) > 0) { tyMin = (this.min.getY() - start.getY()) / direction.getY(); tyMax = (this.max.getY() - start.getY()) / direction.getY(); yNormal = Vector3d.UNIT_Y; } else { tyMin = (this.max.getY() - start.getY()) / direction.getY(); tyMax = (this.min.getY() - start.getY()) / direction.getY(); yNormal = Vector3d.UNIT_Y.negate(); if (tyMin == txMin) { tMin = tyMin; normalMin = xNormal.negate().sub(yNormal); } else if (tyMin > txMin) { tMin = tyMin; normalMin = yNormal.negate(); } else {
/** * Return a collection of entities contained within {@code distance} blocks * of the specified location. This uses a sphere to test distances. * * <p>For world implementations, only some parts of the world is usually * loaded, so this method will only return entities within those loaded * parts.</p> * * @param location The location at the center of the search radius * @param distance The search radius * @return A collection of nearby entities */ default Collection<Entity> getNearbyEntities(Vector3d location, double distance) { checkNotNull(location, "location"); checkArgument(distance > 0, "distance must be > 0"); return this.getIntersectingEntities(new AABB(location.getX() - distance, location.getY() - distance, location.getZ() - distance, location.getX() + distance, location.getY() + distance, location.getZ() + distance), entity -> entity.getLocation().getPosition().distanceSquared(location) <= distance * distance); }
/** * Gets the Vector3d with the given {@link AxisDirection}. * * @param axisDirection The direction along the axis. * @return the Vector3d */ public Vector3d toVector3dWithDirection(final AxisDirection axisDirection) { return this.direction.mul(axisDirection.getSignum()); }
private void xIntersect() { this.xCurrent = this.xPlaneNext; this.yCurrent = this.direction.getY() * this.xPlaneT + this.position.getY(); this.zCurrent = this.direction.getZ() * this.xPlaneT + this.position.getZ(); this.normalCurrent = this.xNormal; // Prepare next intersection this.xPlaneNext += this.xPlaneIncrement; this.xPlaneT = (this.xPlaneNext - this.position.getX()) / this.direction.getX(); }
/** * Returns whether the given vector is along this axis. * * @param vector The vector to test * @return True if it is along this axis */ public boolean isVectorAlongAxis(final Vector3d vector) { return vector.abs().normalize().sub(this.direction).lengthSquared() == 0; }
@Listener public void onEntityMove(MoveEntityEvent event) { if(event.getTargetEntity().isOnGround()) { if(BlockUtil.doesStatePassFilters(allowedBlocks.getValue(), event.getTargetEntity().getLocation().getRelative(Direction.DOWN).getBlock())) { FootprintData data = getFootprintData(event.getTargetEntity().getUniqueId()); if (data.canPlaceFootprint(event.getToTransform().getPosition())) { Vector3d footprintLocation = event.getToTransform().getPosition().add(0, 0.19, 0); //Flip these, it should 'roughly' rotate 90 or -90 degrees. Vector3d footOffset = new Vector3d(footprintLocation.getZ(), 0, footprintLocation.getX()).normalize().div(2); event.getTargetEntity().getWorld().spawnParticles(footprintParticle, footprintLocation.add(footOffset.mul(data.side ? -1 : 1))); data.position = event.getToTransform().getPosition(); data.side = !data.side; } } } }
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); }
/** * Create a new instance. * * @param extent The extent * @param x The X-axis position * @param y The Y-axis position * @param z The Z-axis position */ public Location(E extent, double x, double y, double z) { this(extent, new Vector3d(x, y, z)); }
/** * Sets the direction and ending location. This or setting the direction * is required and can only be done once. * * @param end The ending location * @return This for chained calls */ public BlockRayBuilder<E> to(Vector3d end) { checkState(this.direction == null, "Direction has already been set"); checkNotNull(end, "end"); checkArgument(!this.position.equals(end), "Start and end cannot be equal"); this.direction = end.sub(this.position).normalize(); return stopFilter(new TargetBlockFilter<>(end)); }
/** * "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()) ); }
Direction(Vector3d direction, Division division) { if (direction.lengthSquared() == 0) { // Prevent normalization of the zero direction this.offset = direction; } else { this.offset = direction.normalize(); } this.blockOffset = direction.round().toInt(); this.division = division; }
@Test public void testIntersectsRay() { final AABB aabb = new AABB(new Vector3d(0, 0, 0), new Vector3d(2, 2, 2)); Assert.assertEquals(new Tuple<>(new Vector3d(2, 1, 1), new Vector3d(1, 0, 0)), aabb.intersects(new Vector3d(1, 1, 1), new Vector3d(1, 0, 0)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(1, 2, 1), new Vector3d(0, 1, 0)), aabb.intersects(new Vector3d(1, 1, 1), new Vector3d(0, 1, 0)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(1, 1, 2), new Vector3d(0, 0, 1)), aabb.intersects(new Vector3d(1, 1, 1), new Vector3d(0, 0, 1)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(0, 0, 0), new Vector3d(-1, -1, -1).normalize()), aabb.intersects(new Vector3d(-1, -1, -1), new Vector3d(1, 1, 1)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(0, 0, 1), new Vector3d(-1, -1, -0.0).normalize()), aabb.intersects(new Vector3d(-1, -1, 1), new Vector3d(1, 1, 0)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(0, 1, 1), new Vector3d(-1, -0.0, -0.0)), aabb.intersects(new Vector3d(-1, 1, 1), new Vector3d(1, 0, 0)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(2, 1, 1), new Vector3d(1, 0, 0)), aabb.intersects(new Vector3d(3, 1, 1), new Vector3d(-1, 0, 0)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(1, 0, 1), new Vector3d(-0.0, -1, -0.0)), aabb.intersects(new Vector3d(1, -1, 1), new Vector3d(0, 1, 0)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(1, 2, 1), new Vector3d(0, 1, 0)), aabb.intersects(new Vector3d(1, 3, 1), new Vector3d(0, -1, 0)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(1, 1, 0), new Vector3d(-0.0, -0.0, -1)), aabb.intersects(new Vector3d(1, 1, -1), new Vector3d(0, 0, 1)).get()); Assert.assertEquals(new Tuple<>(new Vector3d(1, 1, 2), new Vector3d(0, 0, 1)), aabb.intersects(new Vector3d(1, 1, 3), new Vector3d(0, 0, -1)).get()); Assert.assertFalse(aabb.intersects(new Vector3d(-1, -1, -1), new Vector3d(0, 1, 0)).isPresent()); }
/** * 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)); }
@Test public void testScale() { final Vector3d scale1 = new Vector3d(1, 2, 3); final Vector3d scale2 = new Vector3d(4, 5, 6); Transform<Extent> transform = new Transform<>(this.mockExtent1, Vector3d.ZERO, Vector3d.ZERO, scale1); assertEquals(scale1, transform.getScale()); transform = transform.addScale(scale2); assertEquals(scale2.mul(scale1), transform.getScale()); }
/** * Gets the size of the box. * * @return The size */ public Vector3d getSize() { if (this.size == null) { this.size = this.max.sub(this.min); } return this.size; }