mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-20 22:26:24 -04:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
514853d7b1 |
+22
-30
@@ -10,7 +10,9 @@ package com.cobblemon.mod.common.api.snowstorm
|
||||
|
||||
import com.cobblemon.mod.common.api.codec.CodecMapped
|
||||
import com.cobblemon.mod.common.api.data.ArbitrarilyMappedSerializableCompanion
|
||||
import com.cobblemon.mod.common.api.orientation.OrientationController
|
||||
import com.cobblemon.mod.common.client.render.MatrixWrapper
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import com.cobblemon.mod.common.util.math.hamiltonProduct
|
||||
import com.cobblemon.mod.common.util.set
|
||||
import com.mojang.math.Axis
|
||||
@@ -26,6 +28,7 @@ import kotlin.math.pow
|
||||
import kotlin.math.sqrt
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import org.joml.AxisAngle4d
|
||||
import org.joml.AxisAngle4f
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3f
|
||||
|
||||
@@ -88,7 +91,7 @@ class RotateXYZCameraMode : ParticleCameraMode {
|
||||
cameraPitch: Float,
|
||||
viewDirection: Vec3
|
||||
): Quaternionf {
|
||||
val i = if (angle == 0.0f) 0F else Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val i = Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val q = Quaternionf(cameraAngle)
|
||||
q.hamiltonProduct(Axis.ZP.rotationDegrees(i))
|
||||
return q
|
||||
@@ -122,7 +125,7 @@ class RotateYCameraMode : ParticleCameraMode {
|
||||
cameraPitch: Float,
|
||||
viewDirection: Vec3
|
||||
): Quaternionf {
|
||||
val i = if (angle == 0F) 0F else Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val i = Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val q2 = Axis.YP.rotationDegrees(-cameraYaw)
|
||||
q2.hamiltonProduct(Axis.ZP.rotationDegrees(i))
|
||||
q2.hamiltonProduct(Axis.YP.rotationDegrees(180F))
|
||||
@@ -160,7 +163,7 @@ class LookAtXYZ : ParticleCameraMode {
|
||||
cameraPitch: Float,
|
||||
viewDirection: Vec3
|
||||
): Quaternionf {
|
||||
val i = if (angle == 0F) 0F else Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val i = Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val rotation = Quaternionf()
|
||||
rotation.hamiltonProduct(Axis.YP.rotationDegrees(-cameraYaw - 180))
|
||||
rotation.hamiltonProduct(Axis.XP.rotationDegrees(cameraPitch))
|
||||
@@ -190,7 +193,7 @@ class LookAtY : ParticleCameraMode {
|
||||
cameraPitch: Float,
|
||||
viewDirection: Vec3
|
||||
): Quaternionf {
|
||||
val i = if (angle == 0F) 0F else Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val i = Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val q2 = Axis.YP.rotationDegrees(-cameraYaw + 180)
|
||||
q2.hamiltonProduct(Axis.ZP.rotationDegrees(i))
|
||||
return q2
|
||||
@@ -257,15 +260,11 @@ class EmitterYZPlane : ParticleCameraMode {
|
||||
cameraPitch: Float,
|
||||
viewDirection: Vec3
|
||||
): Quaternionf {
|
||||
val rotation = Quaternionf(0F, 0F, 0F, 1F)
|
||||
|
||||
val quat = AxisAngle4d(rotation)
|
||||
matrixWrapper.matrix.getRotation(quat)
|
||||
rotation.set(quat)
|
||||
|
||||
rotation.hamiltonProduct(Axis.YP.rotationDegrees(180F)) // Don't worry about it.
|
||||
rotation.hamiltonProduct(Axis.YP.rotationDegrees(90F))
|
||||
return rotation
|
||||
val i = Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val forward = matrixWrapper.matrix.transformDirection(OrientationController.LEFT)
|
||||
val q = Quaternionf(AxisAngle4f(i.toRadians(), forward))
|
||||
q.mul(Axis.YP.rotationDegrees(90F))
|
||||
return q
|
||||
}
|
||||
|
||||
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
|
||||
@@ -296,14 +295,11 @@ class EmitterXZPlane : ParticleCameraMode {
|
||||
cameraPitch: Float,
|
||||
viewDirection: Vec3
|
||||
): Quaternionf {
|
||||
val rotation = Quaternionf(0F, 0F, 0F, 1F)
|
||||
|
||||
val quat = AxisAngle4d(rotation)
|
||||
matrixWrapper.matrix.getRotation(quat)
|
||||
rotation.set(quat)
|
||||
rotation.hamiltonProduct(Axis.YP.rotationDegrees(180F)) // Don't worry about it.
|
||||
rotation.hamiltonProduct(Axis.XP.rotationDegrees(-90F))
|
||||
return rotation
|
||||
val i = Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val up = matrixWrapper.matrix.transformDirection(OrientationController.UP)
|
||||
val q = Quaternionf(AxisAngle4f(-i.toRadians(), up))
|
||||
q.mul(Axis.XP.rotationDegrees(-90F))
|
||||
return q
|
||||
}
|
||||
|
||||
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
|
||||
@@ -334,15 +330,11 @@ class EmitterXYPlane : ParticleCameraMode {
|
||||
cameraPitch: Float,
|
||||
viewDirection: Vec3
|
||||
): Quaternionf {
|
||||
val rotation = Quaternionf(0F, 0F, 0F, 1F)
|
||||
|
||||
val quat = AxisAngle4d(rotation)
|
||||
matrixWrapper.matrix.getRotation(quat)
|
||||
rotation.set(quat)
|
||||
|
||||
rotation.hamiltonProduct(Axis.YP.rotationDegrees(180F)) // Don't worry about it.
|
||||
|
||||
return rotation
|
||||
val i = Mth.lerp(deltaTicks, prevAngle, angle)
|
||||
val forward = matrixWrapper.matrix.transformDirection(OrientationController.FORWARDS)
|
||||
val q = Quaternionf(AxisAngle4f(i.toRadians(), forward))
|
||||
q.mul(Axis.ZP.rotationDegrees(90F))
|
||||
return q
|
||||
}
|
||||
|
||||
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.mojang.serialization.DynamicOps
|
||||
import com.mojang.serialization.codecs.PrimitiveCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import kotlin.math.abs
|
||||
|
||||
interface ParticleRotation : CodecMapped {
|
||||
companion object : ArbitrarilyMappedSerializableCompanion<ParticleRotation, ParticleRotationType>(
|
||||
@@ -40,9 +39,7 @@ interface ParticleRotation : CodecMapped {
|
||||
|
||||
val type: ParticleRotationType
|
||||
|
||||
fun getInitialRotation(runtime: MoLangRuntime): Double
|
||||
fun getInitialAngularVelocity(runtime: MoLangRuntime): Double
|
||||
fun getAngularVelocity(runtime: MoLangRuntime, angle: Double, angularVelocity: Double): Double
|
||||
fun getAngle(runtime: MoLangRuntime, age: Int): Double
|
||||
}
|
||||
|
||||
class ParametricParticleRotation(var expression: Expression = NumberExpression(0.0)): ParticleRotation {
|
||||
@@ -59,9 +56,12 @@ class ParametricParticleRotation(var expression: Expression = NumberExpression(0
|
||||
|
||||
override val type = ParticleRotationType.PARAMETRIC
|
||||
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
|
||||
override fun getInitialRotation(runtime: MoLangRuntime) = runtime.resolveDouble(expression)
|
||||
override fun getInitialAngularVelocity(runtime: MoLangRuntime) = 0.0
|
||||
override fun getAngularVelocity(runtime: MoLangRuntime, angle: Double, angularVelocity: Double) = runtime.resolveDouble(expression) - angle
|
||||
override fun getAngle(
|
||||
runtime: MoLangRuntime,
|
||||
age: Int,
|
||||
): Double {
|
||||
return runtime.resolveDouble(expression)
|
||||
}
|
||||
|
||||
override fun readFromBuffer(buffer: RegistryFriendlyByteBuf) {
|
||||
expression = MoLang.createParser(buffer.readString()).parseExpression()
|
||||
@@ -92,19 +92,12 @@ class DynamicParticleRotation(
|
||||
}
|
||||
}
|
||||
|
||||
var angularVelocity: Double? = null
|
||||
|
||||
override val type = ParticleRotationType.DYNAMIC
|
||||
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
|
||||
override fun getInitialRotation(runtime: MoLangRuntime) = runtime.resolveDouble(startRotation)
|
||||
override fun getInitialAngularVelocity(runtime: MoLangRuntime) = runtime.resolveDouble(speed) / 20
|
||||
override fun getAngularVelocity(runtime: MoLangRuntime, angle: Double, angularVelocity: Double): Double {
|
||||
val acceleration = runtime.resolveDouble(acceleration)
|
||||
val nextVelocity = angularVelocity * 20 + acceleration
|
||||
val drag = nextVelocity * runtime.resolveDouble(drag)
|
||||
return angularVelocity + (if (abs(drag) > abs(nextVelocity)) {
|
||||
0.0
|
||||
} else {
|
||||
nextVelocity - drag - angularVelocity * 20
|
||||
})
|
||||
override fun getAngle(runtime: MoLangRuntime, age: Int): Double {
|
||||
return getInitialRotation(runtime) + getAngularVelocity(runtime) * age
|
||||
}
|
||||
|
||||
override fun readFromBuffer(buffer: RegistryFriendlyByteBuf) {
|
||||
@@ -120,6 +113,18 @@ class DynamicParticleRotation(
|
||||
buffer.writeString(acceleration.getString())
|
||||
buffer.writeString(drag.getString())
|
||||
}
|
||||
|
||||
fun getInitialRotation(runtime: MoLangRuntime) = runtime.resolveDouble(startRotation)
|
||||
fun getInitialAngularVelocity(runtime: MoLangRuntime) = runtime.resolveDouble(speed) / 20
|
||||
fun getAngularVelocity(runtime: MoLangRuntime): Double {
|
||||
if (angularVelocity == null) angularVelocity = getInitialAngularVelocity(runtime)
|
||||
|
||||
val drag = runtime.resolveDouble(drag)
|
||||
var acceleration = runtime.resolveDouble(acceleration)
|
||||
acceleration += -drag * angularVelocity!!
|
||||
val nextVelocity = angularVelocity!! + acceleration / 20
|
||||
return nextVelocity
|
||||
}
|
||||
}
|
||||
|
||||
enum class ParticleRotationType {
|
||||
|
||||
@@ -60,7 +60,6 @@ class SnowstormParticle(
|
||||
val sprite = getSpriteFromAtlas()
|
||||
|
||||
val particleTextureSheet: ParticleRenderType
|
||||
var angularVelocity = 0.0
|
||||
var colliding = false
|
||||
|
||||
var texture = storm.effect.particle.texture
|
||||
@@ -110,9 +109,8 @@ class SnowstormParticle(
|
||||
|
||||
init {
|
||||
setParticleSpeed(initialVelocity.x, initialVelocity.y, initialVelocity.z)
|
||||
roll = -storm.effect.particle.rotation.getInitialRotation(runtime).toFloat()
|
||||
roll = -storm.effect.particle.rotation.getAngle(runtime, 0).toFloat()
|
||||
oRoll = roll
|
||||
angularVelocity = storm.effect.particle.rotation.getInitialAngularVelocity(runtime)
|
||||
friction = 1F
|
||||
lifetime = (runtime.resolveDouble(storm.effect.particle.maxAge) * 20).toInt()
|
||||
storm.particles.add(this)
|
||||
@@ -247,9 +245,8 @@ class SnowstormParticle(
|
||||
setParticleAgeInRuntime()
|
||||
storm.effect.curves.forEach { it.apply(runtime) }
|
||||
runtime.execute(storm.effect.particle.updateExpressions)
|
||||
angularVelocity = storm.effect.particle.rotation.getAngularVelocity(runtime, -roll.toDouble(), angularVelocity) / 20
|
||||
|
||||
if (age >= lifetime || runtime.resolveBoolean(storm.effect.particle.killExpression)) {
|
||||
if (age > lifetime || runtime.resolveBoolean(storm.effect.particle.killExpression)) {
|
||||
runExpirationEvents()
|
||||
remove()
|
||||
return
|
||||
@@ -261,8 +258,8 @@ class SnowstormParticle(
|
||||
yd = velocity.y
|
||||
zd = velocity.z
|
||||
oRoll = roll
|
||||
// Subtract because Bedrock particles are counter-clockwise and Java Edition is clockwise.
|
||||
roll = oRoll - angularVelocity.toFloat()
|
||||
// negative because Bedrock particles are counter-clockwise and Java Edition is clockwise.
|
||||
roll = -storm.effect.particle.rotation.getAngle(runtime, age).toFloat()
|
||||
}
|
||||
|
||||
viewDirection = storm.effect.particle.viewDirection.getDirection(
|
||||
|
||||
Reference in New Issue
Block a user