sk9zist :l
Исправился
- 981
- 18
- 157
Как сделать красный луч, который ведет от одного блока к другому с помощью GlStateManager ?
public static void translateToZeroCoord(float partialTicks)
{
Entity player = Minecraft.getMinecraft().player;
double x = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks;
double y = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks;
double z = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks;
GlStateManager.translate(-x, -y, -z);
}
private void drawLine(Vec3d first, Color color, BufferBuilder buffer)
{
buffer.pos(first.x, first.y, first.z).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex();
}
private void drawPolyChain(List<Vec3d> path, Color color)
{
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(3, DefaultVertexFormats.POSITION_COLOR);
for (Vec3d vec3d : path)
drawLine(vec3d, color, buffer);
tessellator.draw();
}
private List<Vec3d> makePath(World worldIn, Vec3d startPos, BlockPos targetPos)
{
Vec3d finalPos = new Vec3d(targetPos.getX() + 0.5, targetPos.getY() + 0.75, targetPos.getZ() + 0.5);
List<Vec3d> r = new ArrayList<>();
r.add(startPos);
Vec3d aboveFrame = new Vec3d(targetPos.getX() + 0.5, targetPos.getY() + 3, targetPos.getZ() + 0.5);
double height = aboveFrame.y - startPos.y;
if (height > 1 && startPos.squareDistanceTo(finalPos) > 25) {
Vector2d direction = new Vector2d(aboveFrame.x, aboveFrame.z);
direction.sub(new Vector2d(startPos.x, startPos.z));
direction.normalize();
r.add(new Vec3d(
startPos.x + height * direction.x,
startPos.y + height,
startPos.z + height * direction.y
));
}
r.add(aboveFrame);
r.add(finalPos);
return r;
}
public static Function<Double, Vec3d> bezierCurve(List<Vec3d> path)
{
Vec3d first = path.get(0);
Vec3d last = path.get(path.size() - 1);
float angle = (float) Math.atan2(last.x - first.x, last.z - first.z);
List<Vec3d> rotatedPath = path.stream().map(v -> v.rotateYaw(-angle)).collect(Collectors.toList());
return t -> {
double z = 0;
double y = 0;
int n = rotatedPath.size() - 1;
Vec3d vec = rotatedPath.get(0);
double pow_1_minus_t_n = Math.pow((1 - t), n);
z += vec.z * pow_1_minus_t_n;
y += vec.y * pow_1_minus_t_n;
double factorial_n = factorial(n);
for (int index = 1; index < rotatedPath.size(); index++) {
Vec3d item = rotatedPath.get(index);
z += factorial_n / factorial(index) / factorial(n - index) * item.z * Math.pow((1 - t), n - index) * Math.pow(t, index);
y += factorial_n / factorial(index) / factorial(n - index) * item.y * Math.pow((1 - t), n - index) * Math.pow(t, index);
}
return new Vec3d(vec.x, y, z).rotateYaw(angle);
};
}
private static Int2IntMap factorialCache = new Int2IntOpenHashMap();
private static double factorial(int num)
{
return factorialCache.computeIfAbsent(num, num1 -> factorial(num1, 1));
}
private static int factorial(int num, int acc)
{
if (num <= 1) {
return acc;
} else {
return factorial(num - 1, acc * num);
}
}
@Override
public void onUpdate(ItemStack stack, World worldIn, Entity entity, int itemSlot, boolean isSelected)
{
if(entity instanceof EntityPlayer)
{
GlStateManager.pushMatrix();
translateToZeroCoord(Minecraft.getMinecraft().getRenderPartialTicks());
GlStateManager.disableLighting();
GlStateManager.depthMask(false);
GlStateManager.glLineWidth(2.0F);
GlStateManager.disableTexture2D();
List<Vec3d> path = makePath(worldIn, entity.getPositionVector(), entity.getPosition().east(50));
drawPolyChain(path, Color.green);
drawPolyChain(IntStream.range(0, 100).mapToDouble(i -> ((double) i) / 100).mapToObj(entity.curve::apply).collect(Collectors.toList()), Color.red);
GlStateManager.enableLighting();
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.popMatrix();
}
}
@Override
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn)
{
return new ActionResult<ItemStack>(EnumActionResult.PASS, playerIn.getHeldItem(handIn));
}
public class RenderHelper
{
public static Function<Double, Vec3d> curve;
public static List<Vec3d> path;
public static void debugDrawing(Entity entity, float partialTicks, World world)
{
GlStateManager.pushMatrix();
translateToZeroCoord(Minecraft.getMinecraft().getRenderPartialTicks());
GlStateManager.disableLighting();
GlStateManager.depthMask(false);
GlStateManager.glLineWidth(2.0F);
GlStateManager.disableTexture2D();
path = makePath(world, entity.getPositionVector(), entity.getPosition().east(10));
drawPolyChain(path, Color.green);
GlStateManager.enableLighting();
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.popMatrix();
}
public static void translateToZeroCoord(float partialTicks)
{
Entity player = Minecraft.getMinecraft().player;
double x = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks;
double y = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks;
double z = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks;
GlStateManager.translate(-x, -y, -z);
}
public static void drawLine(Vec3d first, Color color, BufferBuilder buffer)
{
buffer.pos(first.x, first.y, first.z).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex();
}
public static void drawPolyChain(List<Vec3d> path, Color color)
{
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(3, DefaultVertexFormats.POSITION_COLOR);
for (Vec3d vec3d : path)
drawLine(vec3d, color, buffer);
tessellator.draw();
}
public static List<Vec3d> makePath(World worldIn, Vec3d startPos, BlockPos targetPos)
{
Vec3d finalPos = new Vec3d(targetPos.getX() + 0.5, targetPos.getY() + 0.75, targetPos.getZ() + 0.5);
List<Vec3d> r = new ArrayList<>();
r.add(startPos);
Vec3d aboveFrame = new Vec3d(targetPos.getX() + 0.5, targetPos.getY() + 3, targetPos.getZ() + 0.5);
double height = aboveFrame.y - startPos.y;
if (height > 1 && startPos.squareDistanceTo(finalPos) > 25) {
Vector2d direction = new Vector2d(aboveFrame.x, aboveFrame.z);
direction.sub(new Vector2d(startPos.x, startPos.z));
direction.normalize();
r.add(new Vec3d(
startPos.x + height * direction.x,
startPos.y + height,
startPos.z + height * direction.y
));
}
r.add(aboveFrame);
r.add(finalPos);
return r;
}
public static Function<Double, Vec3d> bezierCurve(List<Vec3d> path)
{
Vec3d first = path.get(0);
Vec3d last = path.get(path.size() - 1);
float angle = (float) Math.atan2(last.x - first.x, last.z - first.z);
List<Vec3d> rotatedPath = path.stream().map(v -> v.rotateYaw(-angle)).collect(Collectors.toList());
return t -> {
double z = 0;
double y = 0;
int n = rotatedPath.size() - 1;
Vec3d vec = rotatedPath.get(0);
double pow_1_minus_t_n = Math.pow((1 - t), n);
z += vec.z * pow_1_minus_t_n;
y += vec.y * pow_1_minus_t_n;
double factorial_n = factorial(n);
for (int index = 1; index < rotatedPath.size(); index++) {
Vec3d item = rotatedPath.get(index);
z += factorial_n / factorial(index) / factorial(n - index) * item.z * Math.pow((1 - t), n - index) * Math.pow(t, index);
y += factorial_n / factorial(index) / factorial(n - index) * item.y * Math.pow((1 - t), n - index) * Math.pow(t, index);
}
return new Vec3d(vec.x, y, z).rotateYaw(angle);
};
}
public static Int2IntMap factorialCache = new Int2IntOpenHashMap();
public static double factorial(int num)
{
return factorialCache.computeIfAbsent(num, num1 -> factorial(num1, 1));
}
public static int factorial(int num, int acc)
{
if (num <= 1) {
return acc;
} else {
return factorial(num - 1, acc * num);
}
}
}
@SubscribeEvent
public void onUpdate(RenderWorldLastEvent e)
{
RenderHelper.debugDrawing(Minecraft.getMinecraft().player, e.getPartialTicks(), Minecraft.getMinecraft().world);
}
curve::apply
drawPolyChain(IntStream.range(0, 100).mapToDouble(i -> ((double) i) / 100).mapToObj(curve::apply).collect(Collectors.toList()), Color.red);
@SubscribeEvent
public void onUpdate(RenderWorldLastEvent e)
{
float x = -231;
float y = 4;
float z = 218;
GlStateManager.pushMatrix();
RenderHelper.translateToZeroCoord(Minecraft.getMinecraft().getRenderPartialTicks());
GlStateManager.disableLighting();
GlStateManager.depthMask(false);
GlStateManager.glLineWidth(2.0F);
GlStateManager.disableTexture2D();
GlStateManager.glBegin(GL11.GL_LINES);
GlStateManager.color(255, 0, 0);
GlStateManager.glVertex3f((float) Minecraft.getMinecraft().player.posX, (float) Minecraft.getMinecraft().player.posY + 1, (float) Minecraft.getMinecraft().player.posZ);
GlStateManager.glVertex3f((float) (x + 0.5), (float) (y + 0.5), (float) (z + 0.5));
GlStateManager.glEnd();
GlStateManager.enableLighting();
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.popMatrix();
}
Про partialTicks не забывайдёргается при движении
GlStateManager.glVertex3f((float) Minecraft.getMinecraft().player.posX, (float) Minecraft.getMinecraft().player.posY + 1, (float) Minecraft.getMinecraft().player.posZ);
Потому что надо не тупо копипастить все, а взять только то, что нужно для твоей задачи. У мя там кривые безье рисовались.Но почему-то она какая-то кривая)
@SubscribeEvent
public void onUpdate(RenderWorldLastEvent e)
{
float x = -231;
float y = 4;
float z = 218;
GlStateManager.pushMatrix();
RenderHelper.translateToZeroCoord(e.getPartialTicks());
GlStateManager.disableLighting();
GlStateManager.depthMask(false);
GlStateManager.glLineWidth(2.0F);
GlStateManager.disableTexture2D();
GlStateManager.glBegin(GL11.GL_LINES);
GlStateManager.color(255, 0, 0);
GlStateManager.glVertex3f((float) (Minecraft.getMinecraft().player.lastTickPosX + (Minecraft.getMinecraft().player.posX - Minecraft.getMinecraft().player.lastTickPosX) * e.getPartialTicks()),
(float) (Minecraft.getMinecraft().player.lastTickPosY + (Minecraft.getMinecraft().player.posY - Minecraft.getMinecraft().player.lastTickPosY) * e.getPartialTicks()),
(float) (Minecraft.getMinecraft().player.lastTickPosZ + (Minecraft.getMinecraft().player.posZ - Minecraft.getMinecraft().player.lastTickPosZ) * e.getPartialTicks()));
GlStateManager.glVertex3f((float) (x + 0.5), (float) (y + 0.5), (float) (z + 0.5));
GlStateManager.glEnd();
GlStateManager.enableLighting();
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.popMatrix();
}