This commit is contained in:
ZtereoHYPE 2022-07-17 19:20:28 +02:00
parent e2246761dd
commit 7d37cc3c87
18 changed files with 783 additions and 1 deletions

View file

@ -0,0 +1,21 @@
package codes.ztereohype.example;
import net.fabricmc.api.ModInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ExampleMod implements ModInitializer {
// This logger is used to write text to the console and the log file.
// It is considered best practice to use your mod id as the logger's name.
// That way, it's clear which mod wrote info, warnings, and errors.
public static final Logger LOGGER = LoggerFactory.getLogger("modid");
@Override
public void onInitialize() {
// This code runs as soon as Minecraft is in a mod-load-ready state.
// However, some things (like resources) may still be uninitialized.
// Proceed with mild caution.
LOGGER.info("Hello Fabric world!");
}
}

View file

@ -0,0 +1,80 @@
package codes.ztereohype.example;
import net.minecraft.util.Mth;
import java.util.ArrayList;
import java.util.List;
public class Star {
private final double xCoord;
private final double yCoord;
private final double zCoord;
private final double sinPolarAngle;
private final double cosPolarAngle;
private final double projSin;
private final double projCos;
private final double twinkleSpeed;
private final double initialRadius;
private double currentAngle;
private double currentRadius;
public Star(double randX, double randY, double randZ, double initialRadius, double twinkleSpeed) {
double invsqrtDistance = Mth.fastInvSqrt(randX * randX + randY * randY + randZ * randZ);
this.xCoord = randX * invsqrtDistance * 100.0;
this.yCoord = randY * invsqrtDistance * 100.0;
this.zCoord = randZ * invsqrtDistance * 100.0;
double polarAngle = Math.atan2(randX, randZ);
this.sinPolarAngle = Math.sin(polarAngle);
this.cosPolarAngle = Math.cos(polarAngle);
// magic projection fuckery??
double proj = Math.atan2(Math.sqrt(randX * randX + randZ * randZ), randY);
this.projSin = Math.sin(proj);
this.projCos = Math.cos(proj);
this.twinkleSpeed = twinkleSpeed;
this.initialRadius = initialRadius;
this.currentRadius = initialRadius;
this.currentAngle = twinkleSpeed; //just so they dont all start straight
}
public void tick(int ticks) {
currentAngle += 0.007d * twinkleSpeed;
currentRadius = Mth.lerp(Math.sin(ticks * twinkleSpeed / 10f) * 0.5f + 0.5f, initialRadius - 0.15f, initialRadius + 0.15f) ;
}
//return 4*3 coords for 4 vertices
public double[] getVertices() {
double[] vertices = new double[12];
double cosRot = Math.cos(currentAngle);
double sinRot = Math.sin(currentAngle);
for(int v = 0; v < 4; ++v) {
// shift the vector to the 4 corners:
// vec 0, 1 --> -rad; vec 2, 3 --> +rad
double xShift = (double)((v & 2) - 1) * currentRadius;
// vec 1, 2 --> +rad; vec 3, 0 --> -rad
double yShift = (double)(((v + 1) & 2) - 1) * currentRadius;
// magic projection fuckery to turn the shift into an offset applying rotation and polar bs
double aa = xShift * cosRot - yShift * sinRot;
double ab = yShift * cosRot + xShift * sinRot;
double ae = - aa * projCos;
double yOffset = aa * projSin;
double xOffset = ae * sinPolarAngle - ab * cosPolarAngle;
double zOffset = ab * sinPolarAngle + ae * cosPolarAngle;
vertices[v * 3 ] = xCoord + xOffset;
vertices[v * 3 + 1] = yCoord + yOffset;
vertices[v * 3 + 2] = zCoord + zOffset;
}
return vertices;
}
}

View file

@ -0,0 +1,128 @@
package codes.ztereohype.example;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import java.util.ArrayList;
import java.util.List;
public class StarManager {
// public static VertexBuffer starBuffer = new VertexBuffer();
public static ArrayList<Star> starList = new ArrayList<>();
public static BufferBuilder.RenderedBuffer generateStars(BufferBuilder bufferBuilder, long seed) {
RandomSource randomSource = RandomSource.create(seed);
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
for(int i = 0; i < 1500; ++i) {
// -1..1
double randX = randomSource.nextFloat() * 2.0F - 1.0F;
double randY = randomSource.nextFloat() * 2.0F - 1.0F;
double randZ = randomSource.nextFloat() * 2.0F - 1.0F;
// 0.15..0.25 ???
double starRadius = 0.15F + randomSource.nextFloat() * 0.5F;
double squaredDistance = randX * randX + randY * randY + randZ * randZ;
if (squaredDistance < 1.0 && squaredDistance > 0.01) {
double invsqrtDistance = Mth.fastInvSqrt(squaredDistance);
// star center coords
double xCoord = randX * invsqrtDistance * 100.0;
double yCoord = randY * invsqrtDistance * 100.0;
double zCoord = randZ * invsqrtDistance * 100.0;
// rad angle of polar coords
double polarAngle = Math.atan2(randX, randZ);
double sinPolarAngle = Math.sin(polarAngle);
double cosPolarAngle = Math.cos(polarAngle);
// magic projection fuckery??
double p = Math.atan2(Math.sqrt(randX * randX + randZ * randZ), randY);
double q = Math.sin(p);
double r = Math.cos(p);
// random rotation in rad
double rot = randomSource.nextDouble() * Math.PI * 2.0;
double sinRot = Math.sin(rot);
double cosRot = Math.cos(rot);
for(int v = 0; v < 4; ++v) {
// x:
// 0 0 0 0 & 0 0 1 0 --> 0 --> -.20
// 0 0 0 1 & 0 0 1 0 --> 0 --> -.20
// 0 0 1 0 & 0 0 1 0 --> 2 --> +.20
// 0 0 1 1 & 0 0 1 0 --> 2 --> +.20
// y:
// 0 0 0 1 & 0 0 1 0 --> 0 --> -.20
// 0 0 1 0 & 0 0 1 0 --> 2 --> +.20
// 0 0 1 1 & 0 0 1 0 --> 2 --> +.20
// 0 1 0 0 & 0 0 1 0 --> 0 --> -.20
// shift the vector to the 4 corners:
// vec 0, 1 --> -rad; vec 2, 3 --> +rad
double xShift = (double)((v & 2) - 1) * starRadius;
// vec 1, 2 --> +rad; vec 3, 0 --> -rad
double yShift = (double)(((v + 1) & 2) - 1) * starRadius;
// magic projection fuckery to turn the shift into an offset applying rotation and polar bs
double aa = xShift * cosRot - yShift * sinRot;
double ab = yShift * cosRot + xShift * sinRot;
double ae = 0.0 * q - aa * r;
double yOffset = aa * q + 0.0 * r;
double xOffset = ae * sinPolarAngle - ab * cosPolarAngle;
double zOffset = ab * sinPolarAngle + ae * cosPolarAngle;
bufferBuilder.vertex(xCoord + xOffset, yCoord + yOffset, zCoord + zOffset).endVertex();
System.out.println("x: " + (xCoord + xOffset) + ", y: " + (yCoord + yOffset) + ", z: " + (zCoord + zOffset));
}
}
}
return bufferBuilder.end();
}
public static void generateStarList() {
RandomSource randomSource = RandomSource.create(123L);
for(int i = 0; i < 65000; ++i) {
// -1..1
double randX = randomSource.nextFloat() * 2.0F - 1.0F;
double randY = randomSource.nextFloat() * 2.0F - 1.0F;
double randZ = randomSource.nextFloat() * 2.0F - 1.0F;
// 0.15..0.25 ???
double starRadius = 0.15F + randomSource.nextFloat() * 0.1F;
double squaredDistance = randX * randX + randY * randY + randZ * randZ;
if (squaredDistance < 1.0 && squaredDistance > 0.01) {
starList.add(new Star(randX, randY, randZ, starRadius, 0.3 + randomSource.nextDouble() * 0.4));
}
}
}
public static void updateStars(int ticks, VertexBuffer starBuffer) {
Tesselator tesselator = Tesselator.getInstance();
BufferBuilder bufferBuilder = tesselator.getBuilder();
RenderSystem.setShader(GameRenderer::getPositionShader);
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
for (Star star : starList) {
star.tick(ticks);
double[] vertexList = star.getVertices();
for (int i = 0; i < 12; i += 3) {
bufferBuilder.vertex(vertexList[i], vertexList[i + 1], vertexList[i + 2]).endVertex();
}
}
starBuffer.bind();
starBuffer.upload(bufferBuilder.end());
VertexBuffer.unbind();
}
}

View file

@ -0,0 +1,46 @@
package codes.ztereohype.example.mixin;
import codes.ztereohype.example.ExampleMod;
import codes.ztereohype.example.StarManager;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Camera;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.util.RandomSource;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(LevelRenderer.class)
public class ExampleMixin {
@Shadow private VertexBuffer starBuffer;
@Shadow private int ticks;
@Inject(at = @At("HEAD"), method = "createStars", cancellable = true)
private void generateStars(CallbackInfo ci) {
StarManager.generateStarList();
starBuffer = new VertexBuffer();
StarManager.updateStars(0, starBuffer);
ci.cancel();
}
@Inject(at = @At("HEAD"), method = "tick")
private void tickStars(CallbackInfo ci) {
StarManager.updateStars(ticks, starBuffer);
}
// @Inject(at = @At(value="INVOKE", shift = At.Shift.AFTER, target = "Lcom/mojang/blaze3d/vertex/VertexBuffer;bind()V", ordinal = 1), method = "renderSky")
// private void pushPoseStack(PoseStack poseStack, Matrix4f projectionMatrix, float partialTick, Camera camera, boolean bl, Runnable skyFogSetup, CallbackInfo ci) {
// poseStack.pushPose();
// poseStack.scale(40,1,1);
// }
// @Inject(at = @At(value="INVOKE", shift = At.Shift.AFTER, target = "Lcom/mojang/blaze3d/vertex/VertexBuffer;drawWithShader(Lcom/mojang/math/Matrix4f;Lcom/mojang/math/Matrix4f;Lnet/minecraft/client/renderer/ShaderInstance;)V", ordinal = 1), method = "renderSky")
// private void popPoseStack(PoseStack poseStack, Matrix4f projectionMatrix, float partialTick, Camera camera, boolean bl, Runnable skyFogSetup, CallbackInfo ci) {
// poseStack.popPose();
// }
}