Skip to content

Commit

Permalink
Deduplicate rotating a PoseStack by a Rotation object
Browse files Browse the repository at this point in the history
  • Loading branch information
AMereBagatelle committed Jun 2, 2024
1 parent 6057175 commit a2b805c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package io.github.amerebagatelle.mods.nuit.components;

import com.google.common.collect.ImmutableList;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.github.amerebagatelle.mods.nuit.util.CodecUtils;
import io.github.amerebagatelle.mods.nuit.util.Utils;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.client.multiplayer.ClientLevel;
import org.joml.Quaternionf;

import java.util.HashMap;
import java.util.Map;

public class Rotation {
Expand All @@ -19,28 +23,51 @@ public class Rotation {
}, (vec) -> ImmutableList.of(vec.x(), vec.y(), vec.z()));
public static final Codec<Rotation> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.BOOL.optionalFieldOf("skyboxRotation", true).forGetter(Rotation::getSkyboxRotation),
CodecUtils.unboundedMapFixed(Long.class, QUAT_FROM_VEC_3_F, HashMap::new)
.optionalFieldOf("mapping", Map.of())
CodecUtils.unboundedMapFixed(Long.class, QUAT_FROM_VEC_3_F, Long2ObjectOpenHashMap::new)
.optionalFieldOf("mapping", CodecUtils.fastUtilLong2ObjectOpenHashMap())
.forGetter(Rotation::getMapping),
CodecUtils.unboundedMapFixed(Long.class, QUAT_FROM_VEC_3_F, HashMap::new)
.optionalFieldOf("axis", Map.of())
CodecUtils.unboundedMapFixed(Long.class, QUAT_FROM_VEC_3_F, Long2ObjectOpenHashMap::new)
.optionalFieldOf("axis", CodecUtils.fastUtilLong2ObjectOpenHashMap())
.forGetter(Rotation::getAxis),
Codec.LONG.optionalFieldOf("duration", 24000L).forGetter(Rotation::getRotationDuration),
Codec.LONG.optionalFieldOf("duration", 24000L).forGetter(Rotation::getDuration),
Codec.FLOAT.optionalFieldOf("speed", 1f).forGetter(Rotation::getSpeed)
).apply(instance, Rotation::new));
private final boolean skyboxRotation;
private final Map<Long, Quaternionf> mapping, axis;
private final long rotationDuration;
private final long duration;
private final float speed;

public Rotation(boolean skyboxRotation, Map<Long, Quaternionf> mapping, Map<Long, Quaternionf> axis, long rotationDuration, float speed) {
public Rotation(boolean skyboxRotation, Map<Long, Quaternionf> mapping, Map<Long, Quaternionf> axis, long duration, float speed) {
this.skyboxRotation = skyboxRotation;
this.mapping = mapping;
this.axis = axis;
this.rotationDuration = rotationDuration;
this.duration = duration;
this.speed = speed;
}

public void rotateStack(PoseStack matrixStack, long currentTime, ClientLevel world) {
// static
var possibleMappingKeyframes = Utils.findClosestKeyframes(mapping, currentTime);
Quaternionf mappingRot = new Quaternionf();
if (possibleMappingKeyframes.isPresent()) {
mappingRot.set(Utils.interpolateQuatKeyframes(mapping, possibleMappingKeyframes.get(), currentTime));
matrixStack.mulPose(mappingRot);
}

var possibleAxisKeyframes = Utils.findClosestKeyframes(axis, currentTime);
Quaternionf axisRot = new Quaternionf();
if (possibleAxisKeyframes.isPresent()) {
axisRot.set(Utils.interpolateQuatKeyframes(axis, possibleAxisKeyframes.get(), currentTime));
axisRot.difference(mappingRot.conjugate());
matrixStack.mulPose(axisRot);

double timeRotation = Utils.calculateRotation(speed, skyboxRotation, world);
matrixStack.mulPose(Axis.XP.rotationDegrees((float) timeRotation));

matrixStack.mulPose(axisRot.conjugate());
}
}

public boolean getSkyboxRotation() {
return skyboxRotation;
}
Expand All @@ -57,8 +84,8 @@ public float getSpeed() {
return this.speed;
}

public long getRotationDuration() {
return rotationDuration;
public long getDuration() {
return duration;
}

public static Rotation of() {
Expand All @@ -68,5 +95,4 @@ public static Rotation of() {
public static Rotation decorations() {
return new Rotation(false, Map.of(0L, new Quaternionf()), Map.of(), 24000L, 1f);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Axis;
import io.github.amerebagatelle.mods.nuit.NuitClient;
import io.github.amerebagatelle.mods.nuit.api.skyboxes.NuitSkybox;
import io.github.amerebagatelle.mods.nuit.components.Conditions;
Expand All @@ -26,7 +25,6 @@
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.material.FogType;
import org.joml.Matrix4f;
import org.joml.Quaternionf;

import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -253,37 +251,16 @@ protected boolean checkWeather() {

public void renderDecorations(LevelRendererAccessor worldRendererAccess, PoseStack matrixStack, Matrix4f projectionMatrix, float tickDelta, BufferBuilder bufferBuilder, float alpha, Runnable fogCallback) {
RenderSystem.enableBlend();
var mappingFrames = this.decorations.getRotation().getMapping();
var axisFrames = this.decorations.getRotation().getAxis();
var world = Minecraft.getInstance().level;
assert world != null;
long currentTime = world.getDayTime() % this.decorations.getRotation().getRotationDuration();
long currentTime = world.getDayTime() % this.decorations.getRotation().getDuration();

// Custom Blender
this.decorations.getBlend().applyBlendFunc(alpha);
matrixStack.pushPose();

// static
var possibleMappingKeyframes = Utils.findClosestKeyframes(mappingFrames, currentTime);
Quaternionf mappingRot = new Quaternionf();
if (possibleMappingKeyframes.isPresent()) {
mappingRot.set(Utils.interpolateQuatKeyframes(mappingFrames, possibleMappingKeyframes.get(), currentTime));
matrixStack.mulPose(mappingRot);
}

var possibleAxisKeyframes = Utils.findClosestKeyframes(axisFrames, currentTime);
Quaternionf axisRot = new Quaternionf();
if (possibleAxisKeyframes.isPresent()) {
axisRot.set(Utils.interpolateQuatKeyframes(axisFrames, possibleAxisKeyframes.get(), currentTime));
axisRot.difference(mappingRot.conjugate());
matrixStack.mulPose(axisRot);

double timeRotation = Utils.calculateRotation(this.decorations.getRotation().getSpeed(), this.decorations.getRotation().getSkyboxRotation(), world);
matrixStack.mulPose(Axis.XP.rotationDegrees((float) timeRotation));

matrixStack.mulPose(axisRot.conjugate());
}

this.decorations.getRotation().rotateStack(matrixStack, currentTime, world);

// Iris Compat
//matrixStack.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(IrisCompat.getSunPathRotation()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,15 @@
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Axis;
import io.github.amerebagatelle.mods.nuit.api.skyboxes.RotatableSkybox;
import io.github.amerebagatelle.mods.nuit.components.*;
import io.github.amerebagatelle.mods.nuit.mixin.LevelRendererAccessor;
import io.github.amerebagatelle.mods.nuit.skybox.AbstractSkybox;
import io.github.amerebagatelle.mods.nuit.util.Utils;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.GameRenderer;
import org.joml.Matrix4f;
import org.joml.Quaternionf;

import java.util.Objects;

Expand Down Expand Up @@ -48,33 +45,12 @@ public final void render(LevelRendererAccessor worldRendererAccess, PoseStack ma
this.blend.applyBlendFunc(this.alpha);

ClientLevel world = Objects.requireNonNull(Minecraft.getInstance().level);
long currentTime = world.getDayTime() % this.rotation.getRotationDuration();

var mappingFrames = this.rotation.getMapping();
var axisFrames = this.rotation.getAxis();
long currentTime = world.getDayTime() % this.rotation.getDuration();

matrixStack.pushPose();

// static
var possibleMappingKeyframes = Utils.findClosestKeyframes(mappingFrames, currentTime);
Quaternionf mappingRot = new Quaternionf();
if (possibleMappingKeyframes.isPresent()) {
mappingRot.set(Utils.interpolateQuatKeyframes(mappingFrames, possibleMappingKeyframes.get(), currentTime));
matrixStack.mulPose(mappingRot);
}

var possibleAxisKeyframes = Utils.findClosestKeyframes(axisFrames, currentTime);
Quaternionf axisRot = new Quaternionf();
if (possibleAxisKeyframes.isPresent()) {
axisRot.set(Utils.interpolateQuatKeyframes(axisFrames, possibleAxisKeyframes.get(), currentTime));
axisRot.difference(mappingRot.conjugate());
matrixStack.mulPose(axisRot);

double timeRotation = Utils.calculateRotation(this.getRotation().getSpeed(), this.getRotation().getSkyboxRotation(), world);
matrixStack.mulPose(Axis.XP.rotationDegrees((float) timeRotation));

matrixStack.mulPose(axisRot.conjugate());
}
this.rotation.rotateStack(matrixStack, currentTime, world);

this.renderSkybox(worldRendererAccess, matrixStack, tickDelta, camera, thickFog, fogCallback);
matrixStack.popPose();
Expand Down

0 comments on commit a2b805c

Please sign in to comment.