Render guiding beams when holding gravitation stabilizer
This commit is contained in:
parent
72911e0208
commit
891a8a6dd8
@ -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")
|
||||
}
|
||||
}
|
@ -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)
|
21
src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt
Normal file
21
src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt
Normal 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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user