Render guiding beams when holding gravitation stabilizer

This commit is contained in:
DBotThePony 2022-01-18 17:01:04 +07:00
parent 72911e0208
commit 891a8a6dd8
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 219 additions and 84 deletions

View File

@ -1,55 +1,155 @@
package ru.dbotthepony.mc.otm.client.render;
package ru.dbotthepony.mc.otm.client.render
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.world.phys.Vec3;
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntityBlackHole;
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.*
import com.mojang.math.Matrix4f
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.phys.Vec3
import org.lwjgl.opengl.GL30
import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntityBlackHole
import ru.dbotthepony.mc.otm.core.*
import static org.lwjgl.opengl.GL33.*;
private const val BEAM_WIDTH = 0.2
public class BlackHoleRenderer implements BlockEntityRenderer<BlockEntityBlackHole> {
@Override
public void render(BlockEntityBlackHole blockEntityBlackHole, float v, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, int i1) {
RenderHelper.setDrawColor(RGBAColor.BLACK);
private fun pushQuad(matrix4f: Matrix4f, builder: BufferBuilder, quad: Array<Vector>, fwdRotation: Double, rightRotation: Double, topRotation: Double, anim: Float) {
var a = quad[0]
var b = quad[1]
var c = quad[2]
var d = quad[3]
RenderSystem.setShader(GameRenderer::getPositionColorShader);
RenderSystem.depthFunc(GL_LESS);
RenderSystem.depthMask(true);
RenderSystem.enableDepthTest();
RenderSystem.disableCull();
poseStack.pushPose();
poseStack.translate(0.5, -blockEntityBlackHole.getGravitationStrength() / 2 + 0.5, 0.5);
RenderHelper.colorSphere(poseStack, (float) blockEntityBlackHole.getGravitationStrength());
poseStack.popPose();
RenderSystem.enableCull();
RenderSystem.enableTexture();
if (fwdRotation != 0.0) {
a = a.rotateAroundAxis(VECTOR_FORWARD, fwdRotation)
b = b.rotateAroundAxis(VECTOR_FORWARD, fwdRotation)
c = c.rotateAroundAxis(VECTOR_FORWARD, fwdRotation)
d = d.rotateAroundAxis(VECTOR_FORWARD, fwdRotation)
}
@Override
public boolean shouldRenderOffScreen(BlockEntityBlackHole p_112306_) {
return true;
if (rightRotation != 0.0) {
a = a.rotateAroundAxis(VECTOR_RIGHT, rightRotation)
b = b.rotateAroundAxis(VECTOR_RIGHT, rightRotation)
c = c.rotateAroundAxis(VECTOR_RIGHT, rightRotation)
d = d.rotateAroundAxis(VECTOR_RIGHT, rightRotation)
} else if (topRotation != 0.0) {
a = a.rotateAroundAxis(VECTOR_UP, topRotation)
b = b.rotateAroundAxis(VECTOR_UP, topRotation)
c = c.rotateAroundAxis(VECTOR_UP, topRotation)
d = d.rotateAroundAxis(VECTOR_UP, topRotation)
}
@Override
public boolean shouldRender(BlockEntityBlackHole p_173568_, Vec3 p_173569_) {
return true;
builder.vertex(matrix4f, b.x.toFloat(), b.y.toFloat(), b.z.toFloat()).uv(0f, anim).endVertex()
builder.vertex(matrix4f, c.x.toFloat(), c.y.toFloat(), c.z.toFloat()).uv(1f, anim).endVertex()
builder.vertex(matrix4f, d.x.toFloat(), d.y.toFloat(), d.z.toFloat()).uv(1f, anim + 64f).endVertex()
builder.vertex(matrix4f, a.x.toFloat(), a.y.toFloat(), a.z.toFloat()).uv(0f, anim + 64f).endVertex()
}
@Override
public int getViewDistance() {
return 512;
private val quadA = quadY(-BEAM_WIDTH)
private val quadB = quadY(BEAM_WIDTH)
private val quadC = quadZ(-BEAM_WIDTH)
private val quadD = quadZ(BEAM_WIDTH)
private fun beam(matrix4f: Matrix4f, builder: BufferBuilder, fwdRotation: Double, rightRotation: Double, topRotation: Double, anim: Float) {
pushQuad(matrix4f, builder, quadA, fwdRotation, rightRotation, topRotation, anim)
pushQuad(matrix4f, builder, quadB, fwdRotation, rightRotation, topRotation, anim)
pushQuad(matrix4f, builder, quadC, fwdRotation, rightRotation, topRotation, anim)
pushQuad(matrix4f, builder, quadD, fwdRotation, rightRotation, topRotation, anim)
}
public BlackHoleRenderer(BlockEntityRendererProvider.Context context) {
private fun quadY(z: Double): Array<Vector> {
return arrayOf(
Vector(0.0, -BEAM_WIDTH, z),
Vector(64.0, -BEAM_WIDTH, z),
Vector(64.0, BEAM_WIDTH, z),
Vector(0.0, BEAM_WIDTH, z)
)
}
private fun quadZ(y: Double): Array<Vector> {
return arrayOf(
Vector(0.0, y, -BEAM_WIDTH),
Vector(64.0, y, -BEAM_WIDTH),
Vector(64.0, y, BEAM_WIDTH),
Vector(0.0, y, BEAM_WIDTH)
)
}
class BlackHoleRenderer(private val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<BlockEntityBlackHole> {
override fun render(
blockEntityBlackHole: BlockEntityBlackHole,
v: Float,
poseStack: PoseStack,
multiBufferSource: MultiBufferSource,
i: Int,
i1: Int
) {
RenderHelper.setDrawColor(RGBAColor.BLACK)
RenderSystem.setShader(GameRenderer::getPositionColorShader)
RenderSystem.depthFunc(GL30.GL_LESS)
RenderSystem.depthMask(true)
RenderSystem.enableDepthTest()
RenderSystem.disableCull()
poseStack.pushPose()
poseStack.translate(0.5, -blockEntityBlackHole.gravitationStrength / 2 + 0.5, 0.5)
RenderHelper.colorSphere(poseStack, blockEntityBlackHole.gravitationStrength.toFloat())
RenderSystem.enableCull()
RenderSystem.enableTexture()
poseStack.popPose()
val ply = Minecraft.getInstance().player
if (ply != null && ply.mainHandItem.item == Registry.Items.GRAVITATION_STABILIZER) {
RenderSystem.setShader(GameRenderer::getPositionTexShader)
RenderSystem.setShaderTexture(0, ResourceLocation("minecraft", "textures/entity/beacon_beam.png"))
RenderSystem.disableCull()
val builder = Tesselator.getInstance().builder
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX)
val anim = (((System.currentTimeMillis().toDouble() / 100.0) % 100.0).toFloat() / 100f) * 64f
val rotation = System.currentTimeMillis().toDouble() / 1000.0
poseStack.pushPose()
poseStack.translate(0.5, 0.5, 0.5)
val matrix = poseStack.last().pose()
beam(matrix, builder, rotation, 0.0, 0.0, anim)
beam(matrix, builder, rotation, 0.0, Math.PI / 2, anim)
beam(matrix, builder, rotation, 0.0, -Math.PI / 2, anim)
beam(matrix, builder, rotation, 0.0, Math.PI, anim)
beam(matrix, builder, rotation, Math.PI / 2, 0.0, anim)
beam(matrix, builder, rotation, -Math.PI / 2, 0.0, anim)
beam(matrix, builder, rotation, Math.PI, 0.0, anim)
poseStack.popPose()
builder.end()
BufferUploader.end(builder)
RenderSystem.enableCull()
}
}
override fun shouldRenderOffScreen(p_112306_: BlockEntityBlackHole): Boolean {
return true
}
override fun shouldRender(p_173568_: BlockEntityBlackHole, p_173569_: Vec3): Boolean {
return true
}
override fun getViewDistance(): Int {
return 512
}
companion object {
private val BEACON_BEAM = ResourceLocation("minecraft", "textures/entity/beacon_beam")
}
}

View File

@ -1,49 +1,42 @@
package ru.dbotthepony.mc.otm.core
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.Vec3i
import com.mojang.math.Quaternion
import com.mojang.math.Vector3f
import net.minecraft.world.phys.Vec3
import kotlin.math.sin
import kotlin.math.cos
import kotlin.math.acos
import kotlin.math.cos
import kotlin.math.sin
typealias Vector = Vec3
val VECTOR_UP = Vector(0.0, 1.0, 0.0)
val VECTOR_FORWARD = Vector(1.0, 0.0, 0.0)
val VECTOR_BACKWARD = Vector(1.0, 0.0, 0.0)
val VECTOR_DOWN = Vector(0.0, -1.0, 0.0)
val VECTOR_BACK = Vector(0.0, 0.0, 1.0)
fun BlockPos.asVector(): Vector {
return Vector(x + 0.5, y + 0.5, z + 0.5)
}
val VECTOR_RIGHT = Vector(0.0, 0.0, 1.0)
val VECTOR_LEFT = Vector(0.0, 0.0, -1.0)
fun Vector.asAngle(): Angle {
val norm = normalize()
if (norm.x < 0) {
return Angle(acos(norm.dot(VECTOR_UP)) - Angle.PI_HALF, -acos(Vector(norm.x, 0.0, norm.z).normalize().dot(VECTOR_BACK)))
return Angle(acos(norm.dot(VECTOR_UP)) - Angle.PI_HALF, -acos(Vector(norm.x, 0.0, norm.z).normalize().dot(VECTOR_RIGHT)))
}
return Angle(acos(norm.dot(VECTOR_UP)) - Angle.PI_HALF, acos(Vector(norm.x, 0.0, norm.z).normalize().dot(VECTOR_BACK)))
return Angle(acos(norm.dot(VECTOR_UP)) - Angle.PI_HALF, acos(Vector(norm.x, 0.0, norm.z).normalize().dot(VECTOR_RIGHT)))
}
operator fun BlockPos.plus(direction: Vec3i): BlockPos = this.offset(direction)
operator fun BlockPos.plus(direction: Direction): BlockPos = this.offset(direction.normal)
operator fun BlockPos.minus(direction: Vec3i): BlockPos = this.subtract(direction)
operator fun BlockPos.minus(direction: Direction): BlockPos = this.subtract(direction.normal)
operator fun Vec3i.plus(direction: Vec3i): Vec3i = this.offset(direction)
operator fun Vec3i.plus(direction: Direction): Vec3i = this.offset(direction.normal)
operator fun Vec3i.minus(direction: Vec3i): Vec3i = this.subtract(direction)
operator fun Vec3i.minus(direction: Direction): Vec3i = this.subtract(direction.normal)
operator fun Vec3i.times(int: Int): Vec3i = this.multiply(int)
operator fun Vector.plus(direction: Vector): Vector = this.add(direction)
operator fun Vector.minus(direction: Vector): Vector = this.subtract(direction)
operator fun Vector.unaryMinus(): Vector = Vector(-x, -y, -z)
operator fun Vector.component1() = x
operator fun Vector.component2() = y
operator fun Vector.component3() = z
operator fun Vector.times(v: Double): Vector = this.multiply(v, v, v)
operator fun Vector.div(v: Double): Vector {
val inv = 1.0 / v
return this.multiply(inv, inv, inv)
}
fun Vector.left() = asAngle().left() * this.length()
fun Vector.right() = asAngle().right() * this.length()
@ -54,22 +47,39 @@ fun Vector.rotateAroundAxis(axis: Vector, rotation: Double): Vector {
return this * cos(rotation) + axis.cross(this) * sin(rotation) + axis * axis.dot(this) * (1 - cos(rotation))
}
operator fun Vector.component1() = x
operator fun Vector.component2() = y
operator fun Vector.component3() = z
fun Vector.rotate(angle: Angle): Vector {
val rotatedYaw = this.rotateAroundAxis(VECTOR_UP, angle.yaw)
return rotatedYaw.rotateAroundAxis(rotatedYaw.asAngle().left(), angle.pitch)
}
fun Vector.asVector3f(): Vector3f {
return Vector3f(x.toFloat(), y.toFloat(), z.toFloat())
}
fun Quaternion(vec: Vector, rotation: Float, isDegrees: Boolean): Quaternion {
return Quaternion(vec.asVector3f(), rotation, isDegrees)
}
fun Vector(x: Double): Vector {
return Vector(x, 0.0, 0.0)
}
fun Vector(x: Double, y: Double): Vector {
return Vector(x, y, 0.0)
}
fun Vector.rotate(q: Quaternion): Vector {
val quaternion = Quaternion(q)
quaternion.mul(Quaternion(x.toFloat(), y.toFloat(), z.toFloat(), 0.0f))
val quaternion1 = Quaternion(q)
quaternion1.conj()
quaternion.mul(quaternion1)
return Vector(quaternion.i().toDouble(), quaternion.j().toDouble(), quaternion.k().toDouble())
}
data class Angle(val pitch: Double = 0.0, val yaw: Double = 0.0, val roll: Double = 0.0) {
fun forward(): Vector {
val yaw = yaw - PI_HALF
val x = cos(yaw) * cos(pitch)
val y = -sin(pitch)
val z = sin(yaw) * cos(pitch)
return Vector(x, y, z)
}
fun right(): Vector {
val pitch = 0.0
val yaw = yaw
val x = cos(yaw) * cos(pitch)
val y = -sin(pitch)
val z = sin(yaw) * cos(pitch)
@ -78,6 +88,10 @@ data class Angle(val pitch: Double = 0.0, val yaw: Double = 0.0, val roll: Doubl
}
fun left(): Vector {
return -right()
}
fun right(): Vector {
val yaw = yaw + PI_HALF
val pitch = 0.0
val x = cos(yaw) * cos(pitch)

View File

@ -0,0 +1,21 @@
package ru.dbotthepony.mc.otm.core
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.Vec3i
operator fun BlockPos.plus(direction: Vec3i): BlockPos = this.offset(direction)
operator fun BlockPos.plus(direction: Direction): BlockPos = this.offset(direction.normal)
operator fun BlockPos.minus(direction: Vec3i): BlockPos = this.subtract(direction)
operator fun BlockPos.minus(direction: Direction): BlockPos = this.subtract(direction.normal)
operator fun Vec3i.plus(direction: Vec3i): Vec3i = this.offset(direction)
operator fun Vec3i.plus(direction: Direction): Vec3i = this.offset(direction.normal)
operator fun Vec3i.minus(direction: Vec3i): Vec3i = this.subtract(direction)
operator fun Vec3i.minus(direction: Direction): Vec3i = this.subtract(direction.normal)
operator fun Vec3i.times(int: Int): Vec3i = this.multiply(int)
fun BlockPos.asVector(): Vector {
return Vector(x + 0.5, y + 0.5, z + 0.5)
}