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 | |
|---|---|---|---|
|
|
ea99b339ea |
@@ -105,7 +105,7 @@ public abstract class LivingEntityMixin extends Entity implements OrientationCon
|
||||
|
||||
@Inject(method = "tick", at = @At("HEAD"))
|
||||
private void cobblemon$updateRenderOrientation(CallbackInfo ci) {
|
||||
this.cobblemon$orientationController.tick();
|
||||
//this.cobblemon$orientationController.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+95
-11
@@ -10,13 +10,17 @@ package com.cobblemon.mod.common.api.orientation
|
||||
|
||||
import com.cobblemon.mod.common.util.math.geometry.toDegrees
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import com.mojang.blaze3d.Blaze3D
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import org.joml.AxisAngle4f
|
||||
import org.joml.Matrix3f
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3f
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.asin
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sign
|
||||
|
||||
open class OrientationController(val entity: LivingEntity) {
|
||||
@@ -35,6 +39,11 @@ open class OrientationController(val entity: LivingEntity) {
|
||||
private var renderOrientationO: Matrix3f? = null
|
||||
private var renderOrientation: Matrix3f? = null
|
||||
|
||||
|
||||
private var angularVelocity: Vector3f = Vector3f(0.0f, 0.0f, 0.0f)
|
||||
private var lastHandledRotationTime = Double.MIN_VALUE
|
||||
private var frameTime = 0.0
|
||||
|
||||
/** Adding this simply because it irritates me seeing `getActive` when most of this is Java. */
|
||||
fun isActive() = active
|
||||
|
||||
@@ -72,18 +81,93 @@ open class OrientationController(val entity: LivingEntity) {
|
||||
}
|
||||
|
||||
fun tick() {
|
||||
if (!active || orientation == null) return
|
||||
renderOrientationO = renderOrientation
|
||||
val current = orientation
|
||||
val renderMatrix = this.renderOrientation ?: current
|
||||
val renderQuat = Quaternionf().setFromUnnormalized(renderMatrix)
|
||||
val targetQuat = Quaternionf().setFromUnnormalized(current)
|
||||
val dampingFactor = 0.66f // We can change this factor for faster transitions
|
||||
renderQuat.slerp(targetQuat, dampingFactor)
|
||||
// val d = Blaze3D.getTime();
|
||||
// this.frameTime =
|
||||
// if (this.lastHandledRotationTime != Double.MIN_VALUE) d - this.lastHandledRotationTime else 0.0;
|
||||
// this.lastHandledRotationTime = d;
|
||||
//
|
||||
// if (!active || orientation == null) return
|
||||
//
|
||||
// // Find the desired angular velocity
|
||||
// // lerp the current ang vel towards the desired at a set rate (does this need to take into account frametime?
|
||||
// val current = orientation
|
||||
// val renderMatrix = this.renderOrientation ?: Matrix3f()
|
||||
// val renderQuat = Quaternionf().setFromUnnormalized(renderMatrix)
|
||||
// val targetQuat = Quaternionf().setFromUnnormalized(current)
|
||||
//
|
||||
// // Max rate of angular change in radians per second
|
||||
// val maxAngVel = Math.toRadians(180.0).toFloat()
|
||||
//
|
||||
// // Find the difference between the current render orientation and the target orientation
|
||||
// val qDiff: Quaternionf = targetQuat.mul(renderQuat.invert())
|
||||
//
|
||||
// // Construct the target rate of change from the difference quat
|
||||
// val axAng = qDiff.get(AxisAngle4f())
|
||||
// val capdRate = axAng.angle.coerceIn(-maxAngVel, maxAngVel)
|
||||
// val targetAngVel = Vector3f(
|
||||
// axAng.x,
|
||||
// axAng.y,
|
||||
// axAng.z
|
||||
// ).mul(capdRate)
|
||||
//
|
||||
// // lerp the current angular velocity towards the target
|
||||
// val k = 10.0f // Some smoothing constant k
|
||||
// val smoothingFactor = Math.min(1.0f, this.frameTime.toFloat() * k)
|
||||
// angularVelocity = angularVelocity.lerp(targetAngVel, smoothingFactor)
|
||||
//
|
||||
// // Use the angular velocity to slerp the renderQuat toward the targetQuat
|
||||
// val frameDisplacement =
|
||||
// angularVelocity.mul(this.frameTime.toFloat()) // Angular displacement happening on this frame
|
||||
//
|
||||
// val fAng = frameDisplacement.length() // Angle of displacement for this given pass/frame
|
||||
// if (fAng > 0.0001f) { // Ensure that the angle is significant enough that its worth normalizing and carrying out rotation
|
||||
// val fAx = frameDisplacement.normalize()
|
||||
// // Construct a rotation quat from the
|
||||
// val rotQuat = Quaternionf().fromAxisAngleRad(fAx, fAng)
|
||||
//
|
||||
// // Set the new orientation post frame stepped rotation.
|
||||
// renderOrientation = Matrix3f().set(renderQuat.mul(rotQuat))
|
||||
// }
|
||||
//
|
||||
//// this.renderOrientation = orientation
|
||||
//
|
||||
// // apply the new current angular velocity to the current render orientation
|
||||
// // construct a quat out of the angular velocity
|
||||
// // slerp the quat with a value of frametime
|
||||
|
||||
val newRenderOrientation = Matrix3f()
|
||||
renderQuat.get(newRenderOrientation)
|
||||
renderOrientation = newRenderOrientation
|
||||
val d = Blaze3D.getTime();
|
||||
this.frameTime = if (this.lastHandledRotationTime != Double.MIN_VALUE) d - this.lastHandledRotationTime else 0.0;
|
||||
this.lastHandledRotationTime = d;
|
||||
|
||||
if (!active || orientation == null) return
|
||||
|
||||
val current = orientation
|
||||
val renderMatrix = this.renderOrientation ?: Matrix3f()
|
||||
|
||||
// Create mutable copies for manipulation
|
||||
val renderQuat = Quaternionf().setFromUnnormalized(renderMatrix)
|
||||
var targetQuat = Quaternionf().setFromUnnormalized(current)
|
||||
|
||||
// --- Shortest Path Check (Still mandatory for Slerp) ---
|
||||
if (renderQuat.dot(targetQuat) < 0) {
|
||||
targetQuat = targetQuat.invert()
|
||||
}
|
||||
// --------------------------------------------------------
|
||||
|
||||
// K is the speed (rad/s) we want to close the gap at.
|
||||
val k_rate = 10.0f // E.g., target 10 units/second closing rate.
|
||||
|
||||
// Calculate the frame-rate independent alpha (t) for Slerp.
|
||||
// This makes the smoothing constant 'k_rate' a rate of change, not an arbitrary alpha value.
|
||||
val slerpAlpha = 1.0f - Math.exp(-(k_rate * this.frameTime)).toFloat()
|
||||
|
||||
// Use Slerp to interpolate the renderQuat towards the targetQuat
|
||||
val newRenderQuat = renderQuat.slerp(targetQuat, slerpAlpha, Quaternionf())
|
||||
|
||||
// Set the new orientation
|
||||
renderOrientation = Matrix3f().set(newRenderQuat)
|
||||
|
||||
// Angular velocity is now redundant for rendering, but could be used for particle effects, etc.
|
||||
}
|
||||
|
||||
val forwardVector: Vector3f
|
||||
|
||||
+3
-3
@@ -57,9 +57,9 @@ class SubmarineBehaviour : RidingBehaviour<SubmarineSettings, SubmarineState> {
|
||||
}
|
||||
|
||||
val poseProvider = PoseProvider<SubmarineSettings, SubmarineState>(PoseType.FLOAT)
|
||||
.with(PoseOption(PoseType.SWIM) { _, state, entity -> state.rideVelocity.get().z > 0.05 && !state.onSurface.get()})
|
||||
.with(PoseOption(PoseType.STAND) { _, state, entity -> state.rideVelocity.get().z <= 0.05 && state.onSurface.get()})
|
||||
.with(PoseOption(PoseType.STAND) { _, state, entity -> state.rideVelocity.get().z > 0.05 && state.onSurface.get()})
|
||||
.with(PoseOption(PoseType.SWIM) { _, state, entity -> abs(state.rideVelocity.get().z) > 0.05 && !state.onSurface.get()})
|
||||
.with(PoseOption(PoseType.STAND) { _, state, entity -> abs(state.rideVelocity.get().z) <= 0.05 && state.onSurface.get()})
|
||||
.with(PoseOption(PoseType.STAND) { _, state, entity -> abs(state.rideVelocity.get().z) > 0.05 && state.onSurface.get()})
|
||||
|
||||
override fun isActive(settings: SubmarineSettings, state: SubmarineState, vehicle: PokemonEntity): Boolean {
|
||||
return vehicle.isInWater || !vehicle.onGround()
|
||||
|
||||
+10
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.client.render.entity
|
||||
|
||||
import com.cobblemon.mod.common.OrientationControllable
|
||||
import com.cobblemon.mod.common.api.riding.Rideable
|
||||
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
|
||||
@@ -30,11 +31,20 @@ object MountedLivingEntityRenderer {
|
||||
partialTicks: Float,
|
||||
i: Float
|
||||
) {
|
||||
val vehicle = entity.vehicle
|
||||
if (entity.vehicle !is Rideable) return
|
||||
val matrix = stack.last().pose()
|
||||
val delegate = pokemon.delegate as PokemonClientDelegate
|
||||
val locator = delegate.locatorStates[delegate.getSeatLocator(entity)]
|
||||
|
||||
|
||||
if (vehicle is OrientationControllable) {
|
||||
val vehicleController = vehicle.orientationController
|
||||
if (vehicleController.isActive() && vehicleController.orientation != null) {
|
||||
vehicleController.tick()
|
||||
}
|
||||
}
|
||||
|
||||
//Positions entity
|
||||
if (locator != null) {
|
||||
MountedPokemonAnimationRenderController.setup(pokemon, partialTicks)
|
||||
|
||||
Reference in New Issue
Block a user