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.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.*
import net.minecraft.client.renderer.GameRenderer; import com.mojang.math.Matrix4f
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.GameRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.world.phys.Vec3; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntityBlackHole; 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> { private fun pushQuad(matrix4f: Matrix4f, builder: BufferBuilder, quad: Array<Vector>, fwdRotation: Double, rightRotation: Double, topRotation: Double, anim: Float) {
@Override var a = quad[0]
public void render(BlockEntityBlackHole blockEntityBlackHole, float v, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, int i1) { var b = quad[1]
RenderHelper.setDrawColor(RGBAColor.BLACK); var c = quad[2]
var d = quad[3]
RenderSystem.setShader(GameRenderer::getPositionColorShader); if (fwdRotation != 0.0) {
RenderSystem.depthFunc(GL_LESS); a = a.rotateAroundAxis(VECTOR_FORWARD, fwdRotation)
RenderSystem.depthMask(true); b = b.rotateAroundAxis(VECTOR_FORWARD, fwdRotation)
c = c.rotateAroundAxis(VECTOR_FORWARD, fwdRotation)
RenderSystem.enableDepthTest(); d = d.rotateAroundAxis(VECTOR_FORWARD, fwdRotation)
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();
} }
@Override if (rightRotation != 0.0) {
public boolean shouldRenderOffScreen(BlockEntityBlackHole p_112306_) { a = a.rotateAroundAxis(VECTOR_RIGHT, rightRotation)
return true; 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 builder.vertex(matrix4f, b.x.toFloat(), b.y.toFloat(), b.z.toFloat()).uv(0f, anim).endVertex()
public boolean shouldRender(BlockEntityBlackHole p_173568_, Vec3 p_173569_) { builder.vertex(matrix4f, c.x.toFloat(), c.y.toFloat(), c.z.toFloat()).uv(1f, anim).endVertex()
return true; 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()
}
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)
}
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 override fun shouldRenderOffScreen(p_112306_: BlockEntityBlackHole): Boolean {
public int getViewDistance() { return true
return 512;
} }
public BlackHoleRenderer(BlockEntityRendererProvider.Context context) { 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 package ru.dbotthepony.mc.otm.core
import net.minecraft.core.BlockPos import com.mojang.math.Quaternion
import net.minecraft.core.Direction import com.mojang.math.Vector3f
import net.minecraft.core.Vec3i
import net.minecraft.world.phys.Vec3 import net.minecraft.world.phys.Vec3
import kotlin.math.sin
import kotlin.math.cos
import kotlin.math.acos import kotlin.math.acos
import kotlin.math.cos
import kotlin.math.sin
typealias Vector = Vec3 typealias Vector = Vec3
val VECTOR_UP = Vector(0.0, 1.0, 0.0) 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_DOWN = Vector(0.0, -1.0, 0.0)
val VECTOR_BACK = Vector(0.0, 0.0, 1.0) val VECTOR_RIGHT = Vector(0.0, 0.0, 1.0)
val VECTOR_LEFT = Vector(0.0, 0.0, -1.0)
fun BlockPos.asVector(): Vector {
return Vector(x + 0.5, y + 0.5, z + 0.5)
}
fun Vector.asAngle(): Angle { fun Vector.asAngle(): Angle {
val norm = normalize() val norm = normalize()
if (norm.x < 0) { 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.plus(direction: Vector): Vector = this.add(direction)
operator fun Vector.minus(direction: Vector): Vector = this.subtract(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.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.left() = asAngle().left() * this.length()
fun Vector.right() = asAngle().right() * 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)) return this * cos(rotation) + axis.cross(this) * sin(rotation) + axis * axis.dot(this) * (1 - cos(rotation))
} }
operator fun Vector.component1() = x fun Vector.rotate(angle: Angle): Vector {
operator fun Vector.component2() = y val rotatedYaw = this.rotateAroundAxis(VECTOR_UP, angle.yaw)
operator fun Vector.component3() = z 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) { data class Angle(val pitch: Double = 0.0, val yaw: Double = 0.0, val roll: Double = 0.0) {
fun forward(): Vector { fun forward(): Vector {
val yaw = yaw - PI_HALF val yaw = yaw
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 x = cos(yaw) * cos(pitch) val x = cos(yaw) * cos(pitch)
val y = -sin(pitch) val y = -sin(pitch)
val z = sin(yaw) * cos(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 { fun left(): Vector {
return -right()
}
fun right(): Vector {
val yaw = yaw + PI_HALF val yaw = yaw + PI_HALF
val pitch = 0.0 val pitch = 0.0
val x = cos(yaw) * cos(pitch) 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)
}