mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-10 12:34:11 +01:00
Everything but models
- Trying to get xplat forge working, fabric can wait until the common project compiles - Move backend manager event handling to separate class - Move commands into forge for now - Make FlwConfig an interface and move concrete impl into forge - Remove event parameters from handlers than don't actually use them - Add platform specific blockstate light emission for uniforms - Remove example effect - Add accessor for LevelRenderer#ticks
This commit is contained in:
parent
ec685ebdc0
commit
ff0a928479
@ -6,6 +6,7 @@ import org.joml.Vector3f;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||
import com.jozufozu.flywheel.backend.mixin.LevelRendererAccessor;
|
||||
import com.jozufozu.flywheel.config.DebugMode;
|
||||
import com.jozufozu.flywheel.lib.math.MatrixMath;
|
||||
|
||||
@ -147,8 +148,7 @@ public final class FrameUniforms extends UniformWriter {
|
||||
}
|
||||
|
||||
private static long writeTime(long ptr, RenderContext context) {
|
||||
int ticks = context.renderer()
|
||||
.getTicks();
|
||||
int ticks = ((LevelRendererAccessor) context.renderer()).flywheel$ticks();
|
||||
float partialTick = context.partialTick();
|
||||
float renderTicks = ticks + partialTick;
|
||||
float renderSeconds = renderTicks / 20f;
|
||||
|
@ -4,6 +4,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.backend.mixin.AbstractClientPlayerAccessor;
|
||||
import com.jozufozu.flywheel.platform.ClientPlatform;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
@ -93,7 +94,8 @@ public final class PlayerUniforms extends UniformWriter {
|
||||
Item handItem = player.getItemInHand(hand).getItem();
|
||||
if (handItem instanceof BlockItem bitem) {
|
||||
Block block = bitem.getBlock();
|
||||
int blockLight = block.defaultBlockState().getLightEmission(player.clientLevel, player.blockPosition());
|
||||
int blockLight = ClientPlatform.getInstance()
|
||||
.getLightEmission(block.defaultBlockState(), player.clientLevel, player.blockPosition());
|
||||
if (heldLight < blockLight) {
|
||||
heldLight = blockLight;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
|
||||
public final class Uniforms {
|
||||
@ -33,7 +32,7 @@ public final class Uniforms {
|
||||
}
|
||||
}
|
||||
|
||||
public static void onReloadLevelRenderer(ReloadLevelRendererEvent event) {
|
||||
public static void onReloadLevelRenderer() {
|
||||
deleteAll();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.jozufozu.flywheel.backend.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
|
||||
@Mixin(LevelRenderer.class)
|
||||
public interface LevelRendererAccessor {
|
||||
@Accessor("ticks")
|
||||
int flywheel$ticks();
|
||||
}
|
@ -1,94 +1,17 @@
|
||||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.jozufozu.flywheel.platform.ClientPlatform;
|
||||
|
||||
import net.minecraft.ResourceLocationException;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
public class FlwConfig {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final FlwConfig INSTANCE = new FlwConfig();
|
||||
|
||||
public final ClientConfig client;
|
||||
private final ForgeConfigSpec clientSpec;
|
||||
|
||||
private FlwConfig() {
|
||||
Pair<ClientConfig, ForgeConfigSpec> clientPair = new ForgeConfigSpec.Builder().configure(ClientConfig::new);
|
||||
this.client = clientPair.getLeft();
|
||||
clientSpec = clientPair.getRight();
|
||||
}
|
||||
|
||||
public static FlwConfig get() {
|
||||
public interface FlwConfig {
|
||||
FlwConfig INSTANCE = ClientPlatform.getInstance().getConfigInstance();
|
||||
static FlwConfig get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public Backend getBackend() {
|
||||
Backend backend = parseBackend(client.backend.get());
|
||||
if (backend == null) {
|
||||
backend = BackendManager.getDefaultBackend();
|
||||
client.backend.set(Backend.REGISTRY.getIdOrThrow(backend).toString());
|
||||
}
|
||||
Backend getBackend();
|
||||
|
||||
return backend;
|
||||
}
|
||||
boolean limitUpdates();
|
||||
|
||||
@Nullable
|
||||
private static Backend parseBackend(String idStr) {
|
||||
ResourceLocation backendId;
|
||||
try {
|
||||
backendId = new ResourceLocation(idStr);
|
||||
} catch (ResourceLocationException e) {
|
||||
LOGGER.warn("Config contains invalid backend ID '" + idStr + "'!");
|
||||
return null;
|
||||
}
|
||||
|
||||
Backend backend = Backend.REGISTRY.get(backendId);
|
||||
if (backend == null) {
|
||||
LOGGER.warn("Config contains non-existent backend with ID '" + backendId + "'!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
public boolean limitUpdates() {
|
||||
return client.limitUpdates.get();
|
||||
}
|
||||
|
||||
public int workerThreads() {
|
||||
return client.workerThreads.get();
|
||||
}
|
||||
|
||||
public void registerSpecs(ModLoadingContext context) {
|
||||
context.registerConfig(ModConfig.Type.CLIENT, clientSpec);
|
||||
}
|
||||
|
||||
public static class ClientConfig {
|
||||
public final ConfigValue<String> backend;
|
||||
public final BooleanValue limitUpdates;
|
||||
public final ForgeConfigSpec.IntValue workerThreads;
|
||||
|
||||
private ClientConfig(ForgeConfigSpec.Builder builder) {
|
||||
backend = builder.comment("Select the backend to use.")
|
||||
.define("backend", Backend.REGISTRY.getIdOrThrow(BackendManager.getDefaultBackend()).toString());
|
||||
|
||||
limitUpdates = builder.comment("Enable or disable instance update limiting with distance.")
|
||||
.define("limitUpdates", true);
|
||||
|
||||
workerThreads = builder.comment("The number of worker threads to use. Set to -1 to let Flywheel decide. Set to 0 to disable parallelism. Requires a game restart to take effect.")
|
||||
.defineInRange("workerThreads", -1, -1, Runtime.getRuntime()
|
||||
.availableProcessors());
|
||||
}
|
||||
}
|
||||
int workerThreads();
|
||||
}
|
||||
|
@ -4,8 +4,6 @@ import org.slf4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.event.EndClientResourceReloadEvent;
|
||||
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
import com.jozufozu.flywheel.backend.Backends;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl;
|
||||
@ -14,7 +12,6 @@ import com.mojang.logging.LogUtils;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.fml.CrashReportCallables;
|
||||
|
||||
public final class BackendManagerImpl {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@ -47,7 +44,7 @@ public final class BackendManagerImpl {
|
||||
return Backends.INDIRECT;
|
||||
}
|
||||
|
||||
private static void chooseBackend() {
|
||||
public static void chooseBackend() {
|
||||
var preferred = FlwConfig.get().getBackend();
|
||||
var actual = preferred.findFallback();
|
||||
|
||||
@ -67,25 +64,5 @@ public final class BackendManagerImpl {
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
CrashReportCallables.registerCrashCallable("Flywheel Backend", BackendManagerImpl::getBackendString);
|
||||
}
|
||||
|
||||
public static void onEndClientResourceReload(EndClientResourceReloadEvent event) {
|
||||
if (event.error()
|
||||
.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
chooseBackend();
|
||||
VisualizationManagerImpl.resetAll();
|
||||
}
|
||||
|
||||
public static void onReloadLevelRenderer(ReloadLevelRendererEvent event) {
|
||||
chooseBackend();
|
||||
|
||||
ClientLevel level = event.level();
|
||||
if (level != null) {
|
||||
VisualizationManagerImpl.reset(level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.EndClientResourceReloadEvent;
|
||||
import com.jozufozu.flywheel.api.model.Model;
|
||||
|
||||
public class ModelCache<T> {
|
||||
@ -31,7 +30,7 @@ public class ModelCache<T> {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void onEndClientResourceReload(EndClientResourceReloadEvent event) {
|
||||
public static void onEndClientResourceReload() {
|
||||
for (ModelCache<?> cache : ALL) {
|
||||
cache.clear();
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import java.util.function.Supplier;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.EndClientResourceReloadEvent;
|
||||
import com.jozufozu.flywheel.api.model.Model;
|
||||
|
||||
public class ModelHolder {
|
||||
@ -51,7 +50,7 @@ public class ModelHolder {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void onEndClientResourceReload(EndClientResourceReloadEvent event) {
|
||||
public static void onEndClientResourceReload() {
|
||||
for (ModelHolder holder : ALL) {
|
||||
holder.clear();
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
|
||||
class MeshEmitter implements VertexConsumer {
|
||||
private final BufferBuilder bufferBuilder;
|
||||
protected final BufferBuilder bufferBuilder;
|
||||
private final RenderType renderType;
|
||||
private boolean lastQuadWasShaded;
|
||||
private boolean seenFirstQuad;
|
||||
@ -51,7 +51,7 @@ class MeshEmitter implements VertexConsumer {
|
||||
}
|
||||
}
|
||||
|
||||
private void observeQuadAndEmitIfNecessary(BakedQuad quad) {
|
||||
protected void observeQuadAndEmitIfNecessary(BakedQuad quad) {
|
||||
if (seenFirstQuad && lastQuadWasShaded != quad.isShade()) {
|
||||
emit();
|
||||
begin();
|
||||
@ -68,13 +68,6 @@ class MeshEmitter implements VertexConsumer {
|
||||
bufferBuilder.putBulkData(poseEntry, quad, colorMuls, red, green, blue, combinedLights, combinedOverlay, mulColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBulkData(PoseStack.Pose matrixEntry, BakedQuad quad, float[] baseBrightness, float red, float green, float blue, float alpha, int[] lightmapCoords, int overlayCoords, boolean readExistingColor) {
|
||||
observeQuadAndEmitIfNecessary(quad);
|
||||
|
||||
bufferBuilder.putBulkData(matrixEntry, quad, baseBrightness, red, green, blue, alpha, lightmapCoords, overlayCoords, readExistingColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer vertex(double x, double y, double z) {
|
||||
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
|
||||
|
@ -14,7 +14,6 @@ import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
|
||||
public final class LevelAttached<T> {
|
||||
private static final ConcurrentLinkedDeque<WeakReference<LevelAttached<?>>> ALL = new ConcurrentLinkedDeque<>();
|
||||
@ -42,11 +41,6 @@ public final class LevelAttached<T> {
|
||||
this(factory, t -> {});
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void onUnloadLevel(LevelEvent.Unload event) {
|
||||
invalidateLevel(event.getLevel());
|
||||
}
|
||||
|
||||
public static void invalidateLevel(LevelAccessor level) {
|
||||
Iterator<WeakReference<LevelAttached<?>>> iterator = ALL.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
|
@ -6,9 +6,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public abstract class ClientPlatform {
|
||||
private static final ClientPlatform INSTANCE;
|
||||
@ -38,4 +41,8 @@ public abstract class ClientPlatform {
|
||||
|
||||
@Nullable
|
||||
public abstract ShadersModHandler.InternalHandler createIrisOculusHandlerIfPresent();
|
||||
|
||||
public abstract int getLightEmission(BlockState state, ClientLevel level, BlockPos pos);
|
||||
|
||||
public abstract FlwConfig getConfigInstance();
|
||||
}
|
||||
|
@ -1,292 +0,0 @@
|
||||
package com.jozufozu.flywheel.vanilla.effect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
import com.jozufozu.flywheel.api.task.Plan;
|
||||
import com.jozufozu.flywheel.api.visual.DynamicVisual;
|
||||
import com.jozufozu.flywheel.api.visual.Effect;
|
||||
import com.jozufozu.flywheel.api.visual.EffectVisual;
|
||||
import com.jozufozu.flywheel.api.visual.TickableVisual;
|
||||
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
|
||||
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||
import com.jozufozu.flywheel.lib.instance.InstanceTypes;
|
||||
import com.jozufozu.flywheel.lib.instance.TransformedInstance;
|
||||
import com.jozufozu.flywheel.lib.model.Models;
|
||||
import com.jozufozu.flywheel.lib.task.ForEachPlan;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
|
||||
// http://www.kfish.org/boids/pseudocode.html
|
||||
public class ExampleEffect implements Effect {
|
||||
private static final List<ExampleEffect> ALL_EFFECTS = new ArrayList<>();
|
||||
|
||||
private static final int VISUAL_COUNT = 500;
|
||||
private static final float SPAWN_RADIUS = 8.0f;
|
||||
private static final float LIMIT_RANGE = 10.0f;
|
||||
private static final float SPEED_LIMIT = 0.1f;
|
||||
private static final float RENDER_SCALE = 2 / 16f;
|
||||
|
||||
private static final float SIGHT_RANGE = 5;
|
||||
|
||||
private static final float COHERENCE = 1f / 60f;
|
||||
private static final float SEPARATION = 0.05f;
|
||||
private static final float ALIGNMENT = 1 / 20f;
|
||||
private static final float TENDENCY = 1 / 1000f;
|
||||
private static final float AVERSION = 1;
|
||||
|
||||
private static final float GNAT_JITTER = 0.05f;
|
||||
|
||||
private final Level level;
|
||||
private final Vector3f targetPoint;
|
||||
|
||||
public ExampleEffect(Level level, Vector3f targetPoint) {
|
||||
this.level = level;
|
||||
this.targetPoint = targetPoint;
|
||||
}
|
||||
|
||||
public static void tick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase != TickEvent.Phase.START || Minecraft.getInstance().isPaused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
trySpawnNewEffect();
|
||||
}
|
||||
|
||||
public static void onReloadLevelRenderer(ReloadLevelRendererEvent event) {
|
||||
ALL_EFFECTS.clear();
|
||||
}
|
||||
|
||||
private static void trySpawnNewEffect() {
|
||||
Level level = Minecraft.getInstance().level;
|
||||
Player player = Minecraft.getInstance().player;
|
||||
|
||||
if (player == null || level == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
VisualizationManager manager = VisualizationManager.get(level);
|
||||
if (manager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ALL_EFFECTS.isEmpty() && level.random.nextFloat() > 0.005f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3 playerPos = player.position();
|
||||
|
||||
var x = (float) (playerPos.x + Mth.nextFloat(level.random, -20, 20));
|
||||
var y = (float) (playerPos.y + Mth.nextFloat(level.random, 0, 5));
|
||||
var z = (float) (playerPos.z + Mth.nextFloat(level.random, -20, 20));
|
||||
|
||||
ExampleEffect effect = new ExampleEffect(level, new Vector3f(x, y, z));
|
||||
ALL_EFFECTS.add(effect);
|
||||
manager.getEffects().queueAdd(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EffectVisual<?> visualize(VisualizationContext ctx) {
|
||||
return new ExampleVisual(ctx);
|
||||
}
|
||||
|
||||
public class ExampleVisual implements EffectVisual<ExampleEffect>, TickableVisual, DynamicVisual {
|
||||
private final List<BoidVisual> effects;
|
||||
private final List<Boid> boids;
|
||||
|
||||
public ExampleVisual(VisualizationContext ctx) {
|
||||
this.effects = new ArrayList<>(VISUAL_COUNT);
|
||||
this.boids = new ArrayList<>(VISUAL_COUNT);
|
||||
|
||||
for (int i = 0; i < VISUAL_COUNT; i++) {
|
||||
var x = targetPoint.x + Mth.nextFloat(level.random, -SPAWN_RADIUS, SPAWN_RADIUS);
|
||||
var y = targetPoint.y + Mth.nextFloat(level.random, -SPAWN_RADIUS, SPAWN_RADIUS);
|
||||
var z = targetPoint.z + Mth.nextFloat(level.random, -SPAWN_RADIUS, SPAWN_RADIUS);
|
||||
|
||||
Boid boid = new Boid(x, y, z);
|
||||
boids.add(boid);
|
||||
effects.add(new BoidVisual(ctx, boid));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan<TickableVisual.Context> planTick() {
|
||||
Plan<TickableVisual.Context> beginTick = ForEachPlan.of(() -> boids, Boid::beginTick);
|
||||
return beginTick.then(ForEachPlan.of(() -> effects, boid -> boid.self.tick(boids)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan<DynamicVisual.Context> planFrame() {
|
||||
return ForEachPlan.of(() -> effects, BoidVisual::beginFrame);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(float partialTick) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float partialTick) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
effects.forEach(BoidVisual::_delete);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Boid {
|
||||
final Vector3f lastPosition;
|
||||
final Vector3f position;
|
||||
final Vector3f lastVelocity = new Vector3f(0);
|
||||
final Vector3f velocity = new Vector3f(0);
|
||||
|
||||
final Vector3f scratch = new Vector3f(0);
|
||||
final Vector3f coherence = new Vector3f(0);
|
||||
final Vector3f alignment = new Vector3f(0);
|
||||
|
||||
public Boid(float x, float y, float z) {
|
||||
lastPosition = new Vector3f(x, y, z);
|
||||
position = new Vector3f(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
private void beginTick() {
|
||||
lastVelocity.set(velocity);
|
||||
lastPosition.set(position);
|
||||
}
|
||||
|
||||
public void tick(List<Boid> swarm) {
|
||||
int seen = 0;
|
||||
coherence.set(0);
|
||||
alignment.set(0);
|
||||
for (Boid boid : swarm) {
|
||||
if (boid == this) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float distance = boid.lastPosition.distance(lastPosition);
|
||||
|
||||
if (distance > SIGHT_RANGE) {
|
||||
continue;
|
||||
}
|
||||
seen++;
|
||||
|
||||
coherence(boid);
|
||||
separation(boid);
|
||||
alignment(boid);
|
||||
}
|
||||
|
||||
if (seen > 0) {
|
||||
coherencePost(seen);
|
||||
alignmentPost(seen);
|
||||
}
|
||||
//tend(ExampleEffect.this.targetPoint);
|
||||
|
||||
avoidPlayer();
|
||||
|
||||
position.add(capSpeed(velocity));
|
||||
}
|
||||
|
||||
private void avoidPlayer() {
|
||||
var player = Minecraft.getInstance().player.position();
|
||||
scratch.set(player.x, player.y, player.z);
|
||||
|
||||
float dsq = lastPosition.distanceSquared(scratch);
|
||||
if (dsq > SIGHT_RANGE * SIGHT_RANGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastPosition.sub(scratch, scratch)
|
||||
.mul(AVERSION / dsq);
|
||||
|
||||
velocity.add(capSpeed(scratch));
|
||||
}
|
||||
|
||||
private void coherence(Boid other) {
|
||||
this.coherence.add(other.lastPosition);
|
||||
}
|
||||
|
||||
private void separation(Boid other) {
|
||||
float dsq = lastPosition.distanceSquared(other.lastPosition);
|
||||
var push = other.lastPosition.sub(lastPosition, this.scratch)
|
||||
.mul(SEPARATION / dsq);
|
||||
|
||||
this.velocity.sub(push);
|
||||
}
|
||||
|
||||
private void alignment(Boid boid) {
|
||||
this.alignment.add(boid.lastVelocity);
|
||||
}
|
||||
|
||||
private void coherencePost(int seen) {
|
||||
this.coherence.div(seen)
|
||||
.sub(lastPosition)
|
||||
.mul(COHERENCE);
|
||||
this.velocity.add(capSpeed(this.coherence));
|
||||
}
|
||||
|
||||
private void alignmentPost(int seen) {
|
||||
this.alignment.div(seen)
|
||||
.sub(lastVelocity)
|
||||
.mul(ALIGNMENT);
|
||||
|
||||
this.velocity.add(this.alignment);
|
||||
}
|
||||
|
||||
private void tend(Vector3f target) {
|
||||
this.scratch.set(target)
|
||||
.sub(lastPosition)
|
||||
.mul(TENDENCY);
|
||||
this.velocity.add(capSpeed(this.scratch));
|
||||
}
|
||||
|
||||
private static Vector3f capSpeed(Vector3f vec) {
|
||||
return vec.normalize(SPEED_LIMIT);
|
||||
}
|
||||
}
|
||||
|
||||
public static class BoidVisual {
|
||||
private final Boid self;
|
||||
private final Vec3i renderOrigin;
|
||||
|
||||
private final TransformedInstance instance;
|
||||
|
||||
public BoidVisual(VisualizationContext ctx, Boid self) {
|
||||
renderOrigin = ctx.renderOrigin();
|
||||
this.self = self;
|
||||
|
||||
instance = ctx.instancerProvider()
|
||||
.instancer(InstanceTypes.TRANSFORMED, Models.block(Blocks.SHROOMLIGHT.defaultBlockState()))
|
||||
.createInstance();
|
||||
|
||||
instance.light(LightTexture.FULL_BRIGHT);
|
||||
}
|
||||
|
||||
public void _delete() {
|
||||
instance.delete();
|
||||
}
|
||||
|
||||
public void beginFrame(DynamicVisual.Context context) {
|
||||
float partialTick = context.partialTick();
|
||||
var x = Mth.lerp(partialTick, self.lastPosition.x, self.position.x);
|
||||
var y = Mth.lerp(partialTick, self.lastPosition.y, self.position.y);
|
||||
var z = Mth.lerp(partialTick, self.lastPosition.z, self.position.z);
|
||||
|
||||
instance.loadIdentity()
|
||||
.translateBack(renderOrigin)
|
||||
.translate(x, y, z)
|
||||
.scale(RENDER_SCALE);
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
"AbstractClientPlayerAccessor",
|
||||
"GameRendererAccessor",
|
||||
"GlStateManagerMixin",
|
||||
"LevelRendererAccessor",
|
||||
"LightTextureAccessor",
|
||||
"OptionsMixin",
|
||||
"OverlayTextureAccessor",
|
||||
|
@ -7,11 +7,14 @@ import com.jozufozu.flywheel.api.event.ReloadLevelRendererCallback;
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.event.RenderStageCallback;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class ClientPlatformImpl extends ClientPlatform {
|
||||
@Override
|
||||
@ -56,4 +59,15 @@ public class ClientPlatformImpl extends ClientPlatform {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightEmission(BlockState state, ClientLevel level, BlockPos pos) {
|
||||
return state.getLightEmission();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlwConfig getConfigInstance() {
|
||||
// TODO: fabric config
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,15 @@ import java.util.ArrayList;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.EndClientResourceReloadEvent;
|
||||
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||
import com.jozufozu.flywheel.backend.compile.FlwPrograms;
|
||||
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||
import com.jozufozu.flywheel.config.BackendArgument;
|
||||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.config.FlwForgeConfig;
|
||||
import com.jozufozu.flywheel.impl.BackendEventHandler;
|
||||
import com.jozufozu.flywheel.impl.BackendManagerImpl;
|
||||
import com.jozufozu.flywheel.impl.visualization.VisualizationEventHandler;
|
||||
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
|
||||
@ -29,6 +32,7 @@ import net.minecraftforge.client.event.RegisterClientReloadListenersEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.CrashReportCallables;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.IExtensionPoint;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
@ -58,7 +62,7 @@ public class FlywheelForge {
|
||||
modEventBus.addListener(FlywheelForge::onCommonSetup);
|
||||
modEventBus.addListener(FlywheelForge::onRegister);
|
||||
|
||||
FlwConfig.get().registerSpecs(modLoadingContext);
|
||||
FlwForgeConfig.INSTANCE.registerSpecs(modLoadingContext);
|
||||
|
||||
modLoadingContext.registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(
|
||||
() -> "any",
|
||||
@ -71,7 +75,7 @@ public class FlywheelForge {
|
||||
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
|
||||
forgeEventBus.addListener(FlywheelForge::addDebugInfo);
|
||||
|
||||
forgeEventBus.addListener(BackendManagerImpl::onReloadLevelRenderer);
|
||||
forgeEventBus.addListener(BackendEventHandler::onReloadLevelRenderer);
|
||||
|
||||
forgeEventBus.addListener(VisualizationEventHandler::onClientTick);
|
||||
forgeEventBus.addListener(VisualizationEventHandler::onBeginFrame);
|
||||
@ -81,26 +85,24 @@ public class FlywheelForge {
|
||||
|
||||
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
||||
|
||||
forgeEventBus.addListener(Uniforms::onReloadLevelRenderer);
|
||||
forgeEventBus.<ReloadLevelRendererEvent>addListener($ -> Uniforms.onReloadLevelRenderer());
|
||||
|
||||
forgeEventBus.addListener((LevelEvent.Unload e) -> LevelAttached.onUnloadLevel(e));
|
||||
|
||||
// forgeEventBus.addListener(ExampleEffect::tick);
|
||||
// forgeEventBus.addListener(ExampleEffect::onReload);
|
||||
forgeEventBus.addListener((LevelEvent.Unload e) -> LevelAttached.invalidateLevel(e.getLevel()));
|
||||
|
||||
modEventBus.addListener(FlywheelForge::registerClientReloadListeners);
|
||||
modEventBus.addListener(FlywheelForge::onClientSetup);
|
||||
modEventBus.addListener(FlywheelForge::onLoadComplete);
|
||||
|
||||
modEventBus.addListener(BackendManagerImpl::onEndClientResourceReload);
|
||||
modEventBus.addListener(BackendEventHandler::onEndClientResourceReload);
|
||||
|
||||
modEventBus.addListener((EndClientResourceReloadEvent e) -> ModelCache.onEndClientResourceReload(e));
|
||||
modEventBus.addListener(ModelHolder::onEndClientResourceReload);
|
||||
modEventBus.<EndClientResourceReloadEvent>addListener($ -> ModelCache.onEndClientResourceReload());
|
||||
modEventBus.<EndClientResourceReloadEvent>addListener($ -> ModelHolder.onEndClientResourceReload());
|
||||
|
||||
modEventBus.addListener(PartialModel::onModelRegistry);
|
||||
modEventBus.addListener(PartialModel::onModelBake);
|
||||
|
||||
Flywheel.earlyInit();
|
||||
CrashReportCallables.registerCrashCallable("Flywheel Backend", BackendManagerImpl::getBackendString);
|
||||
}
|
||||
|
||||
private static void registerClientReloadListeners(RegisterClientReloadListenersEvent event) {
|
||||
|
@ -25,7 +25,7 @@ public final class FlwCommands {
|
||||
}
|
||||
|
||||
public static void registerClientCommands(RegisterClientCommandsEvent event) {
|
||||
FlwConfig config = FlwConfig.get();
|
||||
var config = FlwForgeConfig.INSTANCE;
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> command = Commands.literal("flywheel");
|
||||
|
@ -0,0 +1,88 @@
|
||||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
import net.minecraft.ResourceLocationException;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
public class FlwForgeConfig implements FlwConfig {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final FlwForgeConfig INSTANCE = new FlwForgeConfig();
|
||||
|
||||
public final ClientConfig client;
|
||||
private final ForgeConfigSpec clientSpec;
|
||||
|
||||
private FlwForgeConfig() {
|
||||
Pair<ClientConfig, ForgeConfigSpec> clientPair = new ForgeConfigSpec.Builder().configure(ClientConfig::new);
|
||||
this.client = clientPair.getLeft();
|
||||
clientSpec = clientPair.getRight();
|
||||
}
|
||||
|
||||
public Backend getBackend() {
|
||||
Backend backend = parseBackend(client.backend.get());
|
||||
if (backend == null) {
|
||||
backend = BackendManager.getDefaultBackend();
|
||||
client.backend.set(Backend.REGISTRY.getIdOrThrow(backend).toString());
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Backend parseBackend(String idStr) {
|
||||
ResourceLocation backendId;
|
||||
try {
|
||||
backendId = new ResourceLocation(idStr);
|
||||
} catch (ResourceLocationException e) {
|
||||
LOGGER.warn("Config contains invalid backend ID '" + idStr + "'!");
|
||||
return null;
|
||||
}
|
||||
|
||||
Backend backend = Backend.REGISTRY.get(backendId);
|
||||
if (backend == null) {
|
||||
LOGGER.warn("Config contains non-existent backend with ID '" + backendId + "'!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
public boolean limitUpdates() {
|
||||
return client.limitUpdates.get();
|
||||
}
|
||||
|
||||
public int workerThreads() {
|
||||
return client.workerThreads.get();
|
||||
}
|
||||
|
||||
public void registerSpecs(ModLoadingContext context) {
|
||||
context.registerConfig(ModConfig.Type.CLIENT, clientSpec);
|
||||
}
|
||||
|
||||
public static class ClientConfig {
|
||||
public final ForgeConfigSpec.ConfigValue<String> backend;
|
||||
public final ForgeConfigSpec.BooleanValue limitUpdates;
|
||||
public final ForgeConfigSpec.IntValue workerThreads;
|
||||
|
||||
private ClientConfig(ForgeConfigSpec.Builder builder) {
|
||||
backend = builder.comment("Select the backend to use.")
|
||||
.define("backend", Backend.REGISTRY.getIdOrThrow(BackendManager.getDefaultBackend()).toString());
|
||||
|
||||
limitUpdates = builder.comment("Enable or disable instance update limiting with distance.")
|
||||
.define("limitUpdates", true);
|
||||
|
||||
workerThreads = builder.comment("The number of worker threads to use. Set to -1 to let Flywheel decide. Set to 0 to disable parallelism. Requires a game restart to take effect.")
|
||||
.defineInRange("workerThreads", -1, -1, Runtime.getRuntime()
|
||||
.availableProcessors());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.jozufozu.flywheel.impl;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.EndClientResourceReloadEvent;
|
||||
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
||||
public class BackendEventHandler {
|
||||
public static void onEndClientResourceReload(EndClientResourceReloadEvent event) {
|
||||
if (event.error()
|
||||
.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BackendManagerImpl.chooseBackend();
|
||||
VisualizationManagerImpl.resetAll();
|
||||
}
|
||||
|
||||
public static void onReloadLevelRenderer(ReloadLevelRendererEvent event) {
|
||||
BackendManagerImpl.chooseBackend();
|
||||
|
||||
ClientLevel level = event.level();
|
||||
if (level != null) {
|
||||
VisualizationManagerImpl.reset(level);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.jozufozu.flywheel.lib.model.baked;
|
||||
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
|
||||
class ForgeMeshEmitter extends MeshEmitter {
|
||||
ForgeMeshEmitter(BufferBuilder bufferBuilder, RenderType renderType) {
|
||||
super(bufferBuilder, renderType);
|
||||
}
|
||||
|
||||
// Forge has another putBulkData that we need to override
|
||||
@Override
|
||||
public void putBulkData(PoseStack.Pose matrixEntry, BakedQuad quad, float[] baseBrightness, float red, float green, float blue, float alpha, int[] lightmapCoords, int overlayCoords, boolean readExistingColor) {
|
||||
observeQuadAndEmitIfNecessary(quad);
|
||||
|
||||
bufferBuilder.putBulkData(matrixEntry, quad, baseBrightness, red, green, blue, alpha, lightmapCoords, overlayCoords, readExistingColor);
|
||||
}
|
||||
}
|
@ -7,10 +7,14 @@ import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.event.RenderStageEvent;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.config.FlwForgeConfig;
|
||||
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
||||
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
|
||||
@ -57,4 +61,14 @@ public class ClientPlatformImpl extends ClientPlatform {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightEmission(BlockState state, ClientLevel level, BlockPos pos) {
|
||||
return state.getLightEmission(level, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlwConfig getConfigInstance() {
|
||||
return FlwForgeConfig.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user