1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

implement traverse_blocks

This commit is contained in:
mat 2023-03-09 22:09:32 +00:00
parent 0468379e59
commit 3fc92b914f

View file

@ -1,97 +1,104 @@
use azalea_core::{BlockPos, Vec3};
use azalea_core::{lerp, BlockPos, Vec3, EPSILON};
// static <T, C> T traverseBlocks(Vec3 from, Vec3 to, C context,
// BiFunction<C, BlockPos, T> getHitResult, Function<C, T> getMissResult) {
// if (from.equals(to)) {
// return getMissResult.apply(context);
// } else {
// double rightAfterEndX = Mth.lerp(-1.0E-7D, to.x, from.x); // var5
// double rightAfterEndY = Mth.lerp(-1.0E-7D, to.y, from.y); // var7
// double rightAfterEndZ = Mth.lerp(-1.0E-7D, to.z, from.z); // var9
// double rightBeforeStartX = Mth.lerp(-1.0E-7D, from.x, to.x); // var11
// double rightBeforeStartY = Mth.lerp(-1.0E-7D, from.y, to.y); // var13
// double rightBeforeStartZ = Mth.lerp(-1.0E-7D, from.z, to.z); // var15
// int currentBlockX = Mth.floor(rightBeforeStartX); // var17
// int currentBlockY = Mth.floor(rightBeforeStartY); // var18
// int currentBlockZ = Mth.floor(rightBeforeStartZ); // var19
// BlockPos.MutableBlockPos blockPos = new
// BlockPos.MutableBlockPos(currentBlockX, currentBlockY, currentBlockZ);
// Object data = getHitResult.apply(context, blockPos);
// if (data != null) {
// return data;
// } else {
// double vectorX = rightAfterEndX - rightBeforeStartX; // var22
// double vectorY = rightAfterEndY - rightBeforeStartX; // var24
// double vectorZ = rightAfterEndZ - rightBeforeStartX; // var26
// int vectorXSign = Mth.sign(vectorX); // var28
// int vectorYSign = Mth.sign(vectorY); // var29
// int vectorZSign = Mth.sign(vectorZ); // var30
// double percentageStepX = vectorXSign == 0 ? 1.7976931348623157E308D :
// ((double) vectorXSign / vectorX); // var31 double percentageStepY =
// vectorYSign == 0 ? 1.7976931348623157E308D : ((double) vectorYSign /
// vectorY); // var33 double percentageStepZ = vectorZSign == 0 ?
// 1.7976931348623157E308D : ((double) vectorZSign / vectorZ); // var35
// double xPercentage = percentageStepX * (vectorXSign > 0 ? 1.0D -
// Mth.frac(rightBeforeStartX) : Mth.frac(rightBeforeStartY)); // var37
// double yPercentage = percentageStepY * (vectorYSign > 0 ? 1.0D -
// Mth.frac(rightBeforeStartY) : Mth.frac(rightBeforeStartX)); // var39
// double zPercentage = percentageStepZ * (vectorZSign > 0 ? 1.0D -
// Mth.frac(rightBeforeStartZ) : Mth.frac(rightBeforeStartZ)); // var41
// Object data;
// do {
// if (xPercentage > 1.0D && yPercentage > 1.0D && zPercentage > 1.0D)
// { return getMissResult.apply(context);
// }
// if (xPercentage < yPercentage) {
// if (xPercentage < zPercentage) {
// currentBlockX += vectorXSign;
// xPercentage += percentageStepX;
// } else {
// currentBlockZ += vectorZSign;
// zPercentage += percentageStepZ;
// }
// } else if (posY < posZ) {
// currentBlockY += vectorYSign;
// yPercentage += percentageStepY;
// } else {
// currentBlockZ += vectorZSign;
// zPercentage += percentageStepZ;
// }
// data = getHitResult.apply(context, blockPos.set(currentBlockX,
// currentBlockY, currentBlockZ)); } while (data == null);
// return data;
// }
// }
// }
// static <T, C> T traverseBlocks(Vec3 from, Vec3 to, C context,
// BiFunction<C, BlockPos, T> getHitResult, Function<C, T> getMissResult) {
pub fn traverse_blocks<C, T>(
from: Vec3,
to: Vec3,
context: C,
get_hit_result: fn(C, BlockPos) -> T,
get_miss_result: fn(C) -> T,
) {
// if (from.equals(to)) {
// return getHitResult.apply(context);
// } else {
// double rightAfterEndX = Mth.lerp(-1.0E-7D, to.x, from.x); // var5
// double rightAfterEndY = Mth.lerp(-1.0E-7D, to.y, from.y); // var7
// double rightAfterEndZ = Mth.lerp(-1.0E-7D, to.z, from.z); // var9
// double rightBeforeStartX = Mth.lerp(-1.0E-7D, from.x, to.x); // var11
// double rightBeforeStartY = Mth.lerp(-1.0E-7D, from.y, to.y); // var13
// double rightBeforeStartZ = Mth.lerp(-1.0E-7D, from.z, to.z); // var15
get_hit_result: fn(&C, &BlockPos) -> Option<T>,
get_miss_result: fn(&C) -> T,
) -> T {
if from == to {
return get_miss_result(context);
return get_miss_result(&context);
}
let right_after_end = Vec3 {
x: lerp(-EPSILON, to.x, from.x),
y: lerp(-EPSILON, to.y, from.y),
z: lerp(-EPSILON, to.z, from.z),
};
let right_before_start = Vec3 {
x: lerp(-EPSILON, from.x, to.x),
y: lerp(-EPSILON, from.y, to.y),
z: lerp(-EPSILON, from.z, to.z),
};
let mut current_block = BlockPos::from(right_before_start);
if let Some(data) = get_hit_result(&context, &current_block) {
return data;
}
let vec = right_after_end - right_before_start;
/// Returns either -1, 0, or 1, depending on whether the number is negative,
/// zero, or positive.
///
/// This function exists because f64::signum doesn't check for 0.
fn get_number_sign(num: f64) -> f64 {
if num == 0. {
0.
} else {
num.signum()
}
}
let vec_sign = Vec3 {
x: get_number_sign(vec.x),
y: get_number_sign(vec.y),
z: get_number_sign(vec.z),
};
#[rustfmt::skip]
let percentage_step = Vec3 {
x: if vec_sign.x == 0. { f64::MAX } else { vec_sign.x / vec.x },
y: if vec_sign.y == 0. { f64::MAX } else { vec_sign.y / vec.y },
z: if vec_sign.z == 0. { f64::MAX } else { vec_sign.z / vec.z },
};
let mut percentage = Vec3 {
x: percentage_step.x
* if vec_sign.x > 0. {
1. - right_before_start.x.fract()
} else {
right_before_start.x.fract()
},
y: percentage_step.y
* if vec_sign.y > 0. {
1. - right_before_start.y.fract()
} else {
right_before_start.y.fract()
},
z: percentage_step.z
* if vec_sign.z > 0. {
1. - right_before_start.z.fract()
} else {
right_before_start.z.fract()
},
};
loop {
if percentage.x > 1. && percentage.y > 1. && percentage.z > 1. {
return get_miss_result(&context);
}
if percentage.x < percentage.y {
if percentage.x < percentage.z {
current_block.x += vec_sign.x as i32;
percentage.x += percentage_step.x;
} else {
current_block.z += vec_sign.z as i32;
percentage.z += percentage_step.z;
}
} else if percentage.y < percentage.z {
current_block.y += vec_sign.y as i32;
percentage.y += percentage_step.y;
} else {
current_block.z += vec_sign.z as i32;
percentage.z += percentage_step.z;
}
if let Some(data) = get_hit_result(&context, &current_block) {
return data;
}
}
}