[WIP] move AbstractParticles
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
package mods.betterfoliage.render.particle
|
||||
|
||||
import mods.betterfoliage.util.Double3
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.client.particle.SpriteBillboardParticle
|
||||
import net.minecraft.client.render.Camera
|
||||
import net.minecraft.client.render.VertexConsumer
|
||||
import net.minecraft.client.texture.Sprite
|
||||
import net.minecraft.client.util.math.Vector3f
|
||||
import net.minecraft.util.math.MathHelper
|
||||
import net.minecraft.world.World
|
||||
|
||||
abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) : SpriteBillboardParticle(world, x, y, z) {
|
||||
|
||||
companion object {
|
||||
// @JvmStatic val sin = Array(64) { idx -> Math.sin(PI2 / 64.0 * idx) }
|
||||
// @JvmStatic val cos = Array(64) { idx -> Math.cos(PI2 / 64.0 * idx) }
|
||||
}
|
||||
|
||||
val billboardRot = Pair(Double3.zero, Double3.zero)
|
||||
val currentPos = Double3.zero
|
||||
val prevPos = Double3.zero
|
||||
val velocity = Double3.zero
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
currentPos.setTo(x, y, z)
|
||||
prevPos.setTo(prevPosX, prevPosY, prevPosZ)
|
||||
velocity.setTo(velocityX, velocityY, velocityZ)
|
||||
update()
|
||||
x = currentPos.x; y = currentPos.y; z = currentPos.z;
|
||||
velocityX = velocity.x; velocityY = velocity.y; velocityZ = velocity.z;
|
||||
}
|
||||
|
||||
/** Update particle on world tick. */
|
||||
abstract fun update()
|
||||
|
||||
/** True if the particle is renderable. */
|
||||
abstract val isValid: Boolean
|
||||
|
||||
/** Add the particle to the effect renderer if it is valid. */
|
||||
fun addIfValid() { if (isValid) MinecraftClient.getInstance().particleManager.addParticle(this) }
|
||||
|
||||
override fun buildGeometry(vertexConsumer: VertexConsumer, camera: Camera, tickDelta: Float) {
|
||||
renderParticleQuad(vertexConsumer, camera, tickDelta)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a particle quad.
|
||||
*
|
||||
* @param[tessellator] the [Tessellator] instance to use
|
||||
* @param[tickDelta] partial tick time
|
||||
* @param[currentPos] render position
|
||||
* @param[prevPos] previous tick position for interpolation
|
||||
* @param[size] particle size
|
||||
* @param[currentAngle] viewpoint-dependent particle rotation (64 steps)
|
||||
* @param[sprite] particle texture
|
||||
* @param[isMirrored] mirror particle texture along V-axis
|
||||
* @param[alpha] aplha blending
|
||||
*/
|
||||
fun renderParticleQuad(vertexConsumer: VertexConsumer,
|
||||
camera: Camera,
|
||||
tickDelta: Float,
|
||||
currentPos: Double3 = this.currentPos,
|
||||
prevPos: Double3 = this.prevPos,
|
||||
size: Double = scale.toDouble(),
|
||||
currentAngle: Float = this.angle,
|
||||
prevAngle: Float = this.prevAngle,
|
||||
sprite: Sprite = this.sprite,
|
||||
alpha: Float = this.colorAlpha) {
|
||||
|
||||
val center = Double3.lerp(tickDelta.toDouble(), prevPos, currentPos)
|
||||
val angle = MathHelper.lerp(tickDelta, prevAngle, currentAngle)
|
||||
val rotation = camera.rotation.copy().apply { hamiltonProduct(Vector3f.POSITIVE_Z.getRadialQuaternion(angle)) }
|
||||
val lightmapCoord = getColorMultiplier(tickDelta)
|
||||
|
||||
val coords = arrayOf(
|
||||
Double3(-1.0, -1.0, 0.0),
|
||||
Double3(-1.0, 1.0, 0.0),
|
||||
Double3(1.0, 1.0, 0.0),
|
||||
Double3(1.0, -1.0, 0.0)
|
||||
).map { it.rotate(rotation).mul(size).add(center).sub(camera.pos.x, camera.pos.y, camera.pos.z) }
|
||||
|
||||
fun renderVertex(vertex: Double3, u: Float, v: Float) = vertexConsumer
|
||||
.vertex(vertex.x, vertex.y, vertex.z).texture(u, v)
|
||||
.color(colorRed, colorGreen, colorBlue, alpha).light(lightmapCoord)
|
||||
.next()
|
||||
|
||||
renderVertex(coords[0], sprite.maxU, sprite.maxV)
|
||||
renderVertex(coords[1], sprite.maxU, sprite.minV)
|
||||
renderVertex(coords[2], sprite.minU, sprite.minV)
|
||||
renderVertex(coords[3], sprite.minU, sprite.maxV)
|
||||
}
|
||||
|
||||
fun setColor(color: Int) {
|
||||
colorBlue = (color and 255) / 256.0f
|
||||
colorGreen = ((color shr 8) and 255) / 256.0f
|
||||
colorRed = ((color shr 16) and 255) / 256.0f
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user