下面列出了net.minecraft.util.math.AxisAlignedBB#calculateIntercept ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static boolean traceToSelectionBoxCorner(SelectionBox box, Corner corner, Vec3d start, Vec3d end)
{
BlockPos pos = (corner == Corner.CORNER_1) ? box.getPos1() : (corner == Corner.CORNER_2) ? box.getPos2() : null;
if (pos != null)
{
AxisAlignedBB bb = PositionUtils.createAABBForPosition(pos);
RayTraceResult hit = bb.calculateIntercept(start, end);
if (hit != null)
{
double dist = hit.hitVec.distanceTo(start);
if (closestCornerDistance < 0 || dist < closestCornerDistance)
{
closestCornerDistance = dist;
closestCorner = new RayTraceWrapper(box, corner, hit.hitVec);
}
return true;
}
}
return false;
}
private static boolean traceToSelectionBoxBody(SelectionBox box, Vec3d start, Vec3d end)
{
if (box.getPos1() != null && box.getPos2() != null)
{
AxisAlignedBB bb = PositionUtils.createEnclosingAABB(box.getPos1(), box.getPos2());
RayTraceResult hit = bb.calculateIntercept(start, end);
if (hit != null)
{
double dist = hit.hitVec.distanceTo(start);
if (closestBoxDistance < 0 || dist < closestBoxDistance)
{
closestBoxDistance = dist;
closestBox = new RayTraceWrapper(box, Corner.NONE, hit.hitVec);
}
return true;
}
}
return false;
}
public static void rayTrace(Beam beam, Function<Entity, Boolean> consumer) {
// Based on EntityRender.getMouseOver(float partialTicks) which we can't use because that's client only
Vec3d start = beam.getStart();
Vec3d lookVec = beam.getLookVec();
Vec3d end = beam.getEnd();
double dist = beam.getDist();
World world = beam.getWorld();
EntityPlayer player = beam.getPlayer();
List<Entity> targets = world.getEntitiesInAABBexcluding(player, player.getEntityBoundingBox().expand(lookVec.x * dist, lookVec.y * dist, lookVec.z * dist).grow(1.0D, 1.0D, 1.0D),
Predicates.and(EntitySelectors.NOT_SPECTATING, ent -> ent != null && ent.canBeCollidedWith()));
List<Pair<Entity, Double>> hitTargets = new ArrayList<>();
for (Entity target : targets) {
AxisAlignedBB targetBB = target.getEntityBoundingBox().grow(target.getCollisionBorderSize());
if (targetBB.contains(start)) {
hitTargets.add(Pair.of(target, 0.0));
} else {
RayTraceResult targetResult = targetBB.calculateIntercept(start, end);
if (targetResult != null) {
double d3 = start.distanceTo(targetResult.hitVec);
if (d3 < dist) {
hitTargets.add(Pair.of(target, d3));
}
}
}
}
hitTargets.sort(Comparator.comparing(Pair::getRight));
hitTargets.stream().filter(pair -> consumer.apply(pair.getLeft())).findFirst();
}
private static boolean traceToPlacementBox(SchematicPlacement placement, Vec3d start, Vec3d end)
{
ImmutableMap<String, SelectionBox> boxes = placement.getSubRegionBoxes(RequiredEnabled.PLACEMENT_ENABLED);
boolean hitSomething = false;
for (Map.Entry<String, SelectionBox> entry : boxes.entrySet())
{
String boxName = entry.getKey();
SelectionBox box = entry.getValue();
if (box.getPos1() != null && box.getPos2() != null)
{
AxisAlignedBB bb = PositionUtils.createEnclosingAABB(box.getPos1(), box.getPos2());
RayTraceResult trace = bb.calculateIntercept(start, end);
if (trace != null)
{
double dist = trace.hitVec.distanceTo(start);
if (closestBoxDistance < 0 || dist < closestBoxDistance)
{
closestBoxDistance = dist;
closestBox = new RayTraceWrapper(placement, trace.hitVec, boxName);
hitSomething = true;
}
}
}
}
return hitSomething;
}
private static boolean traceToOrigin(BlockPos pos, Vec3d start, Vec3d end, HitType type, @Nullable SchematicPlacement placement)
{
if (pos != null)
{
AxisAlignedBB bb = PositionUtils.createAABBForPosition(pos);
RayTraceResult trace = bb.calculateIntercept(start, end);
if (trace != null)
{
double dist = trace.hitVec.distanceTo(start);
if (closestOriginDistance < 0 || dist < closestOriginDistance)
{
closestOriginDistance = dist;
originType = type;
if (type == HitType.PLACEMENT_ORIGIN)
{
closestOrigin = new RayTraceWrapper(placement, trace.hitVec, null);
}
return true;
}
}
}
return false;
}
/**
* Returns the index of the BB in the given list that the given vectors are currently pointing at.
* @return the list index of the pointed box, or -1 of no hit was detected
*/
public static int getPointedBox(Vec3d eyesVec, Vec3d lookVec, double reach, List<AxisAlignedBB> boxes)
{
Vec3d lookEndVec = eyesVec.add(lookVec.x * reach, lookVec.y * reach, lookVec.z * reach);
//AxisAlignedBB box = null;
//Vec3d hitVec = null;
double distance = reach;
int index = -1;
for (int i = 0; i < boxes.size(); ++i)
{
AxisAlignedBB bb = boxes.get(i);
RayTraceResult rayTrace = bb.calculateIntercept(eyesVec, lookEndVec);
if (bb.contains(eyesVec))
{
if (distance >= 0.0D)
{
//box = bb;
//hitVec = rayTrace == null ? eyesVec : rayTrace.hitVec;
distance = 0.0D;
index = i;
}
}
else if (rayTrace != null)
{
double distanceTmp = eyesVec.distanceTo(rayTrace.hitVec);
if (distanceTmp < distance)
{
//box = bb;
//hitVec = rayTrace.hitVec;
distance = distanceTmp;
index = i;
}
}
}
return index;
}
/**
* Returns the index of the BB in the given list that the given vectors are currently pointing at.
* @return the list index of the pointed box, or null of no hit was detected
*/
@Nullable
public static <T> T getPointedBox(Vec3d eyesVec, Vec3d lookVec, double reach, Map<T, AxisAlignedBB> boxMap)
{
Vec3d lookEndVec = eyesVec.add(lookVec.x * reach, lookVec.y * reach, lookVec.z * reach);
double distance = reach;
T key = null;
for (Map.Entry<T, AxisAlignedBB> entry : boxMap.entrySet())
{
AxisAlignedBB bb = entry.getValue();
RayTraceResult rayTrace = bb.calculateIntercept(eyesVec, lookEndVec);
if (bb.contains(eyesVec))
{
if (distance >= 0.0D)
{
distance = 0.0D;
key = entry.getKey();
}
}
else if (rayTrace != null)
{
double distanceTmp = eyesVec.distanceTo(rayTrace.hitVec);
if (distanceTmp < distance)
{
distance = distanceTmp;
key = entry.getKey();
}
}
}
return key;
}
public static RayTraceResult getViewTrace(
Entity entity, Vec3d direction, float partialTicks, double reach, double reachAttack) {
if (entity == null) {
return null;
}
Vec3d eyes = entity.getPositionEyes(partialTicks);
RayTraceResult trace = entity.rayTrace(reach, partialTicks);
Vec3d dir = direction.scale(reach);
Vec3d lookDir = eyes.add(dir);
double hitDistance = trace == null ? reachAttack : trace.hitVec.distanceTo(eyes);
Entity hitEntity = null;
Vec3d hitEntityVec = null;
for (Entity ent :
getWorld()
.getEntitiesInAABBexcluding(
entity,
entity.getEntityBoundingBox().expand(dir.x, dir.y, dir.y).grow(1.D),
Predicates.and(
EntitySelectors.NOT_SPECTATING,
ent -> ent != null && ent.canBeCollidedWith()))) {
AxisAlignedBB bb = ent.getEntityBoundingBox().grow(ent.getCollisionBorderSize());
RayTraceResult tr = bb.calculateIntercept(eyes, lookDir);
if (bb.contains(eyes)) {
if (hitDistance > 0.D) {
hitEntity = ent;
hitEntityVec = tr == null ? eyes : tr.hitVec;
hitDistance = 0.D;
}
} else if (tr != null) {
double dist = eyes.distanceTo(tr.hitVec);
if (dist < hitDistance || hitDistance == 0.D) {
if (entity.getLowestRidingEntity() == ent.getLowestRidingEntity()
&& !ent.canRiderInteract()) {
if (hitDistance == 0.D) {
hitEntity = ent;
hitEntityVec = tr.hitVec;
}
} else {
hitEntity = ent;
hitEntityVec = tr.hitVec;
hitDistance = dist;
}
}
}
}
if (hitEntity != null && reach > 3.D && eyes.distanceTo(hitEntityVec) > 3.D) {
return new RayTraceResult(Type.MISS, hitEntityVec, EnumFacing.UP, new BlockPos(hitEntityVec));
} else if (hitEntity != null && trace == null && hitDistance < reachAttack) {
return new RayTraceResult(hitEntity, hitEntityVec);
} else {
return trace;
}
}