mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-10 12:15:03 +01:00
Switch to instancing controllers
- Combine InstanceFactories and FlywheelRendered into InstancingControllers - Store these controllers directly in the BlockEntity/Entity type instead of a map for efficiency - Redo InstancedRenderRegistry to fit these changes - Rename all tile to block entity - Remove all interface I prefixes - Organize imports - Bump version to 0.5.1
This commit is contained in:
parent
4c0df23702
commit
eb8dc6bc07
71 changed files with 515 additions and 370 deletions
|
@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G
|
||||||
org.gradle.daemon = false
|
org.gradle.daemon = false
|
||||||
|
|
||||||
# mod version info
|
# mod version info
|
||||||
mod_version = 0.5.0a
|
mod_version = 0.5.1
|
||||||
mc_update_version = 1.18
|
mc_update_version = 1.18
|
||||||
minecraft_version = 1.18.1
|
minecraft_version = 1.18.1
|
||||||
forge_version = 39.0.8
|
forge_version = 39.0.8
|
||||||
|
|
|
@ -15,7 +15,6 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
public class FlywheelClient {
|
public class FlywheelClient {
|
||||||
|
|
||||||
public static void clientInit() {
|
public static void clientInit() {
|
||||||
|
|
||||||
CrashReportCallables.registerCrashCallable("Flywheel Backend", () ->
|
CrashReportCallables.registerCrashCallable("Flywheel Backend", () ->
|
||||||
Backend.getInstance().getBackendDescriptor());
|
Backend.getInstance().getBackendDescriptor());
|
||||||
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
package com.jozufozu.flywheel.api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Something (a BlockEntity or Entity) that can be rendered using the instancing API.
|
|
||||||
*/
|
|
||||||
public interface FlywheelRendered {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if there are parts of the renderer that cannot be implemented with Flywheel.
|
|
||||||
*/
|
|
||||||
default boolean shouldRenderNormally() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,8 @@ package com.jozufozu.flywheel.api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A marker interface custom worlds can override to indicate
|
* A marker interface custom worlds can override to indicate
|
||||||
* that tiles inside the world should render with Flywheel.
|
* that block entities and entities inside the world should
|
||||||
|
* render with Flywheel.
|
||||||
*
|
*
|
||||||
* {@link net.minecraft.client.Minecraft#level Minecraft#level} is special cased and will support Flywheel by default.
|
* {@link net.minecraft.client.Minecraft#level Minecraft#level} is special cased and will support Flywheel by default.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,18 +2,18 @@ package com.jozufozu.flywheel.api.instance;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
import com.jozufozu.flywheel.api.Instancer;
|
import com.jozufozu.flywheel.api.Instancer;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface giving {@link TileEntityInstance}s a hook to have a function called at
|
* An interface giving {@link BlockEntityInstance}s a hook to have a function called at
|
||||||
* the start of a frame. By implementing {@link IDynamicInstance}, a {@link TileEntityInstance}
|
* the start of a frame. By implementing {@link DynamicInstance}, a {@link BlockEntityInstance}
|
||||||
* can animate its models in ways that could not be easily achieved by shader attribute
|
* can animate its models in ways that could not be easily achieved by shader attribute
|
||||||
* parameterization.
|
* parameterization.
|
||||||
*
|
*
|
||||||
* <br><br> If your goal is offloading work to shaders, but you're unsure exactly how you need
|
* <br><br> If your goal is offloading work to shaders, but you're unsure exactly how you need
|
||||||
* to parameterize the instances, you're encouraged to implement this for prototyping.
|
* to parameterize the instances, you're encouraged to implement this for prototyping.
|
||||||
*/
|
*/
|
||||||
public interface IDynamicInstance extends IInstance {
|
public interface DynamicInstance extends Instance {
|
||||||
/**
|
/**
|
||||||
* Called every frame, and after initialization.
|
* Called every frame, and after initialization.
|
||||||
* <br>
|
* <br>
|
|
@ -2,6 +2,6 @@ package com.jozufozu.flywheel.api.instance;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
public interface IInstance {
|
public interface Instance {
|
||||||
BlockPos getWorldPosition();
|
BlockPos getWorldPosition();
|
||||||
}
|
}
|
|
@ -2,13 +2,13 @@ package com.jozufozu.flywheel.api.instance;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
import com.jozufozu.flywheel.api.Instancer;
|
import com.jozufozu.flywheel.api.Instancer;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface giving {@link TileEntityInstance}s a hook to have a function called at
|
* An interface giving {@link BlockEntityInstance}s a hook to have a function called at
|
||||||
* the end of every tick. By implementing {@link ITickableInstance}, a {@link TileEntityInstance}
|
* the end of every tick. By implementing {@link TickableInstance}, a {@link BlockEntityInstance}
|
||||||
* can update frequently, but not every frame.
|
* can update frequently, but not every frame.
|
||||||
* <br> There are a few cases in which this should be considered over {@link IDynamicInstance}:
|
* <br> There are a few cases in which this should be considered over {@link DynamicInstance}:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>
|
* <li>
|
||||||
* You'd like to change something about the instance every now and then.
|
* You'd like to change something about the instance every now and then.
|
||||||
|
@ -20,7 +20,7 @@ import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public interface ITickableInstance extends IInstance {
|
public interface TickableInstance extends Instance {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called every tick, and after initialization.
|
* Called every tick, and after initialization.
|
|
@ -3,20 +3,20 @@ package com.jozufozu.flywheel.backend;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.shader.gamestate.IGameStateProvider;
|
import com.jozufozu.flywheel.core.shader.gamestate.GameStateProvider;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class GameStateRegistry {
|
public class GameStateRegistry {
|
||||||
|
|
||||||
private static final Map<ResourceLocation, IGameStateProvider> registeredStateProviders = new HashMap<>();
|
private static final Map<ResourceLocation, GameStateProvider> registeredStateProviders = new HashMap<>();
|
||||||
|
|
||||||
static void clear() {
|
static void clear() {
|
||||||
registeredStateProviders.clear();
|
registeredStateProviders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IGameStateProvider getStateProvider(ResourceLocation location) {
|
public static GameStateProvider getStateProvider(ResourceLocation location) {
|
||||||
IGameStateProvider out = registeredStateProviders.get(location);
|
GameStateProvider out = registeredStateProviders.get(location);
|
||||||
|
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
throw new IllegalArgumentException("State provider '" + location + "' does not exist.");
|
throw new IllegalArgumentException("State provider '" + location + "' does not exist.");
|
||||||
|
@ -25,7 +25,7 @@ public class GameStateRegistry {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void register(IGameStateProvider context) {
|
public static void register(GameStateProvider context) {
|
||||||
if (registeredStateProviders.containsKey(context.getID())) {
|
if (registeredStateProviders.containsKey(context.getID())) {
|
||||||
throw new IllegalStateException("Duplicate game state provider: " + context.getID());
|
throw new IllegalStateException("Duplicate game state provider: " + context.getID());
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,15 @@ import java.util.Arrays;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.IDynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.IInstance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.ITickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.core.materials.FlatLit;
|
import com.jozufozu.flywheel.core.materials.FlatLit;
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
|
||||||
import com.jozufozu.flywheel.light.LightListener;
|
import com.jozufozu.flywheel.light.LightListener;
|
||||||
import com.jozufozu.flywheel.light.LightProvider;
|
import com.jozufozu.flywheel.light.LightProvider;
|
||||||
import com.jozufozu.flywheel.light.ListenerStatus;
|
import com.jozufozu.flywheel.light.ListenerStatus;
|
||||||
|
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
@ -20,9 +20,9 @@ import net.minecraft.world.level.LightLayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A general interface providing information about any type of thing that could use Flywheel's instanced rendering.
|
* A general interface providing information about any type of thing that could use Flywheel's instanced rendering.
|
||||||
* Right now, that's only {@link TileInstanceManager}, but there could be an entity equivalent in the future.
|
* Right now, that's only {@link BlockEntityInstanceManager}, but there could be an entity equivalent in the future.
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractInstance implements IInstance, LightListener {
|
public abstract class AbstractInstance implements Instance, LightListener {
|
||||||
|
|
||||||
protected final MaterialManager materialManager;
|
protected final MaterialManager materialManager;
|
||||||
public final Level world;
|
public final Level world;
|
||||||
|
@ -48,7 +48,7 @@ public abstract class AbstractInstance implements IInstance, LightListener {
|
||||||
* Update instance data here. Good for when data doesn't change very often and when animations are GPU based.
|
* Update instance data here. Good for when data doesn't change very often and when animations are GPU based.
|
||||||
* Don't query lighting data here, that's handled separately in {@link #updateLight()}.
|
* Don't query lighting data here, that's handled separately in {@link #updateLight()}.
|
||||||
*
|
*
|
||||||
* <br><br> If your animations are complex or more CPU driven, see {@link IDynamicInstance} or {@link ITickableInstance}.
|
* <br><br> If your animations are complex or more CPU driven, see {@link DynamicInstance} or {@link TickableInstance}.
|
||||||
*/
|
*/
|
||||||
public void update() {
|
public void update() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
import com.jozufozu.flywheel.api.Instancer;
|
import com.jozufozu.flywheel.api.Instancer;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
|
|
||||||
public abstract class AbstractInstancer<D extends InstanceData> implements Instancer<D> {
|
public abstract class AbstractInstancer<D extends InstanceData> implements Instancer<D> {
|
||||||
|
|
|
@ -10,8 +10,8 @@ import java.util.Set;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.IDynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.ITickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.light.LightUpdater;
|
||||||
|
@ -30,8 +30,8 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
private final Set<T> queuedUpdates;
|
private final Set<T> queuedUpdates;
|
||||||
|
|
||||||
protected final Map<T, AbstractInstance> instances;
|
protected final Map<T, AbstractInstance> instances;
|
||||||
protected final Object2ObjectOpenHashMap<T, ITickableInstance> tickableInstances;
|
protected final Object2ObjectOpenHashMap<T, TickableInstance> tickableInstances;
|
||||||
protected final Object2ObjectOpenHashMap<T, IDynamicInstance> dynamicInstances;
|
protected final Object2ObjectOpenHashMap<T, DynamicInstance> dynamicInstances;
|
||||||
|
|
||||||
protected int frame;
|
protected int frame;
|
||||||
protected int tick;
|
protected int tick;
|
||||||
|
@ -71,7 +71,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
* Ticks the InstanceManager.
|
* Ticks the InstanceManager.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* {@link ITickableInstance}s get ticked.
|
* {@link TickableInstance}s get ticked.
|
||||||
* <br>
|
* <br>
|
||||||
* Queued updates are processed.
|
* Queued updates are processed.
|
||||||
* </p>
|
* </p>
|
||||||
|
@ -85,16 +85,16 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
int cY = (int) cameraY;
|
int cY = (int) cameraY;
|
||||||
int cZ = (int) cameraZ;
|
int cZ = (int) cameraZ;
|
||||||
|
|
||||||
ArrayList<ITickableInstance> instances = new ArrayList<>(tickableInstances.values());
|
ArrayList<TickableInstance> instances = new ArrayList<>(tickableInstances.values());
|
||||||
int incr = 500;
|
int incr = 500;
|
||||||
int size = instances.size();
|
int size = instances.size();
|
||||||
int start = 0;
|
int start = 0;
|
||||||
while (start < size) {
|
while (start < size) {
|
||||||
int end = Math.min(start + incr, size);
|
int end = Math.min(start + incr, size);
|
||||||
|
|
||||||
List<ITickableInstance> sub = instances.subList(start, end);
|
List<TickableInstance> sub = instances.subList(start, end);
|
||||||
taskEngine.submit(() -> {
|
taskEngine.submit(() -> {
|
||||||
for (ITickableInstance instance : sub) {
|
for (TickableInstance instance : sub) {
|
||||||
tickInstance(cX, cY, cZ, instance);
|
tickInstance(cX, cY, cZ, instance);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -103,7 +103,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickInstance(int cX, int cY, int cZ, ITickableInstance instance) {
|
private void tickInstance(int cX, int cY, int cZ, TickableInstance instance) {
|
||||||
if (!instance.decreaseTickRateWithDistance()) {
|
if (!instance.decreaseTickRateWithDistance()) {
|
||||||
instance.tick();
|
instance.tick();
|
||||||
return;
|
return;
|
||||||
|
@ -132,16 +132,16 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
int cY = (int) info.getPosition().y;
|
int cY = (int) info.getPosition().y;
|
||||||
int cZ = (int) info.getPosition().z;
|
int cZ = (int) info.getPosition().z;
|
||||||
|
|
||||||
ArrayList<IDynamicInstance> instances = new ArrayList<>(dynamicInstances.values());
|
ArrayList<DynamicInstance> instances = new ArrayList<>(dynamicInstances.values());
|
||||||
int incr = 500;
|
int incr = 500;
|
||||||
int size = instances.size();
|
int size = instances.size();
|
||||||
int start = 0;
|
int start = 0;
|
||||||
while (start < size) {
|
while (start < size) {
|
||||||
int end = Math.min(start + incr, size);
|
int end = Math.min(start + incr, size);
|
||||||
|
|
||||||
List<IDynamicInstance> sub = instances.subList(start, end);
|
List<DynamicInstance> sub = instances.subList(start, end);
|
||||||
taskEngine.submit(() -> {
|
taskEngine.submit(() -> {
|
||||||
for (IDynamicInstance dyn : sub) {
|
for (DynamicInstance dyn : sub) {
|
||||||
if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
|
if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
|
||||||
dyn.beginFrame();
|
dyn.beginFrame();
|
||||||
}
|
}
|
||||||
|
@ -179,8 +179,8 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* By default this is the only hook an IInstance has to change its internal state. This is the lowest frequency
|
* By default this is the only hook an IInstance has to change its internal state. This is the lowest frequency
|
||||||
* update hook IInstance gets. For more frequent updates, see {@link ITickableInstance} and
|
* update hook IInstance gets. For more frequent updates, see {@link TickableInstance} and
|
||||||
* {@link IDynamicInstance}.
|
* {@link DynamicInstance}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param obj the object to update.
|
* @param obj the object to update.
|
||||||
|
@ -312,12 +312,12 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
.addListener(renderer);
|
.addListener(renderer);
|
||||||
instances.put(obj, renderer);
|
instances.put(obj, renderer);
|
||||||
|
|
||||||
if (renderer instanceof ITickableInstance r) {
|
if (renderer instanceof TickableInstance r) {
|
||||||
tickableInstances.put(obj, r);
|
tickableInstances.put(obj, r);
|
||||||
r.tick();
|
r.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderer instanceof IDynamicInstance r) {
|
if (renderer instanceof DynamicInstance r) {
|
||||||
dynamicInstances.put(obj, r);
|
dynamicInstances.put(obj, r);
|
||||||
r.beginFrame();
|
r.beginFrame();
|
||||||
}
|
}
|
||||||
|
@ -328,9 +328,9 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOriginShift() {
|
public void onOriginShift() {
|
||||||
ArrayList<T> instancedTiles = new ArrayList<>(instances.keySet());
|
ArrayList<T> instanced = new ArrayList<>(instances.keySet());
|
||||||
invalidate();
|
invalidate();
|
||||||
instancedTiles.forEach(this::add);
|
instanced.forEach(this::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void detachLightListeners() {
|
public void detachLightListeners() {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instance.IDynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.ITickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.batching.BatchingEngine;
|
import com.jozufozu.flywheel.backend.instancing.batching.BatchingEngine;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
|
||||||
import com.jozufozu.flywheel.config.FlwEngine;
|
import com.jozufozu.flywheel.config.FlwEngine;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
|
@ -29,7 +29,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
public class InstanceWorld {
|
public class InstanceWorld {
|
||||||
protected final Engine engine;
|
protected final Engine engine;
|
||||||
protected final InstanceManager<Entity> entityInstanceManager;
|
protected final InstanceManager<Entity> entityInstanceManager;
|
||||||
protected final InstanceManager<BlockEntity> tileEntityInstanceManager;
|
protected final InstanceManager<BlockEntity> blockEntityInstanceManager;
|
||||||
|
|
||||||
protected final ParallelTaskEngine taskEngine;
|
protected final ParallelTaskEngine taskEngine;
|
||||||
|
|
||||||
|
@ -48,16 +48,16 @@ public class InstanceWorld {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
entityInstanceManager = new EntityInstanceManager(manager);
|
entityInstanceManager = new EntityInstanceManager(manager);
|
||||||
tileEntityInstanceManager = new TileInstanceManager(manager);
|
blockEntityInstanceManager = new BlockEntityInstanceManager(manager);
|
||||||
|
|
||||||
manager.addListener(entityInstanceManager);
|
manager.addListener(entityInstanceManager);
|
||||||
manager.addListener(tileEntityInstanceManager);
|
manager.addListener(blockEntityInstanceManager);
|
||||||
this.engine = manager;
|
this.engine = manager;
|
||||||
}
|
}
|
||||||
case BATCHING -> {
|
case BATCHING -> {
|
||||||
this.engine = new BatchingEngine();
|
this.engine = new BatchingEngine();
|
||||||
entityInstanceManager = new EntityInstanceManager(this.engine);
|
entityInstanceManager = new EntityInstanceManager(this.engine);
|
||||||
tileEntityInstanceManager = new TileInstanceManager(this.engine);
|
blockEntityInstanceManager = new BlockEntityInstanceManager(this.engine);
|
||||||
}
|
}
|
||||||
default -> throw new IllegalArgumentException("Unknown engine type");
|
default -> throw new IllegalArgumentException("Unknown engine type");
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ public class InstanceWorld {
|
||||||
return entityInstanceManager;
|
return entityInstanceManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceManager<BlockEntity> getTileEntityInstanceManager() {
|
public InstanceManager<BlockEntity> getBlockEntityInstanceManager() {
|
||||||
return tileEntityInstanceManager;
|
return blockEntityInstanceManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,7 +78,7 @@ public class InstanceWorld {
|
||||||
this.taskEngine.stopWorkers();
|
this.taskEngine.stopWorkers();
|
||||||
engine.delete();
|
engine.delete();
|
||||||
entityInstanceManager.detachLightListeners();
|
entityInstanceManager.detachLightListeners();
|
||||||
tileEntityInstanceManager.detachLightListeners();
|
blockEntityInstanceManager.detachLightListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,7 +86,7 @@ public class InstanceWorld {
|
||||||
* <p>
|
* <p>
|
||||||
* Check and shift the origin coordinate.
|
* Check and shift the origin coordinate.
|
||||||
* <br>
|
* <br>
|
||||||
* Call {@link IDynamicInstance#beginFrame()} on all instances in this world.
|
* Call {@link DynamicInstance#beginFrame()} on all instances in this world.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public void beginFrame(BeginFrameEvent event) {
|
public void beginFrame(BeginFrameEvent event) {
|
||||||
|
@ -94,14 +94,14 @@ public class InstanceWorld {
|
||||||
|
|
||||||
taskEngine.syncPoint();
|
taskEngine.syncPoint();
|
||||||
|
|
||||||
tileEntityInstanceManager.beginFrame(taskEngine, event.getInfo());
|
blockEntityInstanceManager.beginFrame(taskEngine, event.getInfo());
|
||||||
entityInstanceManager.beginFrame(taskEngine, event.getInfo());
|
entityInstanceManager.beginFrame(taskEngine, event.getInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tick the renderers after the game has ticked:
|
* Tick the renderers after the game has ticked:
|
||||||
* <p>
|
* <p>
|
||||||
* Call {@link ITickableInstance#tick()} on all instances in this world.
|
* Call {@link TickableInstance#tick()} on all instances in this world.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public void tick() {
|
public void tick() {
|
||||||
|
@ -110,7 +110,7 @@ public class InstanceWorld {
|
||||||
|
|
||||||
if (renderViewEntity == null) return;
|
if (renderViewEntity == null) return;
|
||||||
|
|
||||||
tileEntityInstanceManager.tick(taskEngine, renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ());
|
blockEntityInstanceManager.tick(taskEngine, renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ());
|
||||||
entityInstanceManager.tick(taskEngine, renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ());
|
entityInstanceManager.tick(taskEngine, renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,13 @@ public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this when you want to manually run {@link AbstractInstance#update()}.
|
* Call this when you want to manually run {@link AbstractInstance#update()}.
|
||||||
* @param te The tile whose instance you want to update.
|
* @param blockEntity The block entity whose instance you want to update.
|
||||||
*/
|
*/
|
||||||
public static void enqueueUpdate(BlockEntity te) {
|
public static void enqueueUpdate(BlockEntity blockEntity) {
|
||||||
if (Backend.isOn() && te.hasLevel() && te.getLevel() instanceof ClientLevel) {
|
if (Backend.isOn() && blockEntity.hasLevel() && blockEntity.getLevel() instanceof ClientLevel) {
|
||||||
instanceWorlds.get(te.getLevel())
|
instanceWorlds.get(blockEntity.getLevel())
|
||||||
.getTileEntityInstanceManager()
|
.getBlockEntityInstanceManager()
|
||||||
.queueUpdate(te);
|
.queueUpdate(blockEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +48,10 @@ public class InstancedRenderDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InstanceManager<BlockEntity> getTiles(LevelAccessor world) {
|
public static InstanceManager<BlockEntity> getBlockEntities(LevelAccessor world) {
|
||||||
if (Backend.isOn()) {
|
if (Backend.isOn()) {
|
||||||
return instanceWorlds.get(world)
|
return instanceWorlds.get(world)
|
||||||
.getTileEntityInstanceManager();
|
.getBlockEntityInstanceManager();
|
||||||
} else {
|
} else {
|
||||||
throw new NullPointerException("Backend is off, cannot retrieve instance world.");
|
throw new NullPointerException("Backend is off, cannot retrieve instance world.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,134 +1,176 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Objects;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.jozufozu.flywheel.api.FlywheelRendered;
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityTypeExtension;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.blockentity.SimpleBlockEntityInstancingController;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.IEntityInstanceFactory;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.ITileInstanceFactory;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityTypeExtension;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.entity.SimpleEntityInstancingController;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2BooleanLinkedOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
|
||||||
public class InstancedRenderRegistry {
|
public class InstancedRenderRegistry {
|
||||||
private static final InstancedRenderRegistry INSTANCE = new InstancedRenderRegistry();
|
public static <T extends BlockEntity> boolean canInstance(BlockEntityType<? extends T> type) {
|
||||||
|
return getBlockEntityController(type) != null;
|
||||||
public static InstancedRenderRegistry getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Object2BooleanMap<Object> skipRender = new Object2BooleanLinkedOpenHashMap<>();
|
public static <T extends Entity> boolean canInstance(EntityType<? extends T> type) {
|
||||||
private final Map<BlockEntityType<?>, ITileInstanceFactory<?>> tiles = Maps.newHashMap();
|
return getEntityController(type) != null;
|
||||||
private final Map<EntityType<?>, IEntityInstanceFactory<?>> entities = Maps.newHashMap();
|
|
||||||
|
|
||||||
protected InstancedRenderRegistry() {
|
|
||||||
skipRender.defaultReturnValue(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends BlockEntity> boolean shouldSkipRender(T type) {
|
@Nullable
|
||||||
return _skipRender(type.getType()) || ((type instanceof FlywheelRendered) && !((FlywheelRendered) type).shouldRenderNormally());
|
public static <T extends BlockEntity> BlockEntityInstance<? super T> createInstance(MaterialManager materialManager, T blockEntity) {
|
||||||
|
BlockEntityInstancingController<? super T> controller = getBlockEntityController(getType(blockEntity));
|
||||||
|
if (controller == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return controller.createInstance(materialManager, blockEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Entity> boolean shouldSkipRender(T type) {
|
@Nullable
|
||||||
return _skipRender(type.getType()) || ((type instanceof FlywheelRendered) && !((FlywheelRendered) type).shouldRenderNormally());
|
public static <T extends Entity> EntityInstance<? super T> createInstance(MaterialManager materialManager, T entity) {
|
||||||
|
EntityInstancingController<? super T> controller = getEntityController(getType(entity));
|
||||||
|
if (controller == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return controller.createInstance(materialManager, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends BlockEntity> boolean canInstance(BlockEntityType<? extends T> type) {
|
public static <T extends BlockEntity> boolean shouldSkipRender(T blockEntity) {
|
||||||
return tiles.containsKey(type);
|
BlockEntityInstancingController<? super T> controller = getBlockEntityController(getType(blockEntity));
|
||||||
|
if (controller == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return controller.shouldSkipRender(blockEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Entity> boolean canInstance(EntityType<? extends T> type) {
|
public static <T extends Entity> boolean shouldSkipRender(T entity) {
|
||||||
return entities.containsKey(type);
|
EntityInstancingController<? super T> controller = getEntityController(getType(entity));
|
||||||
|
if (controller == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return controller.shouldSkipRender(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends BlockEntity> TileConfig<? extends T> tile(BlockEntityType<? extends T> type) {
|
public static <T extends BlockEntity> BlockEntityConfig<T> configure(BlockEntityType<T> type) {
|
||||||
return new TileConfig<>(type);
|
return new BlockEntityConfig<>(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Entity> EntityConfig<? extends T> entity(EntityType<? extends T> type) {
|
public static <T extends Entity> EntityConfig<T> configure(EntityType<T> type) {
|
||||||
return new EntityConfig<>(type);
|
return new EntityConfig<>(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
public <T extends BlockEntity> TileEntityInstance<? super T> create(MaterialManager manager, T tile) {
|
public static <T extends BlockEntity> BlockEntityInstancingController<? super T> getBlockEntityController(BlockEntityType<T> type) {
|
||||||
BlockEntityType<?> type = tile.getType();
|
return ((BlockEntityTypeExtension<T>) type).flywheel$getInstancingController();
|
||||||
ITileInstanceFactory<? super T> factory = (ITileInstanceFactory<? super T>) this.tiles.get(type);
|
|
||||||
|
|
||||||
if (factory == null) return null;
|
|
||||||
else return factory.create(manager, tile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends BlockEntity> void setBlockEntityController(BlockEntityType<T> type, BlockEntityInstancingController<? super T> instancingController) {
|
||||||
|
((BlockEntityTypeExtension<T>) type).flywheel$setInstancingController(instancingController);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
public <T extends Entity> EntityInstance<? super T> create(MaterialManager manager, T tile) {
|
public static <T extends Entity> EntityInstancingController<? super T> getEntityController(EntityType<T> type) {
|
||||||
EntityType<?> type = tile.getType();
|
return ((EntityTypeExtension<T>) type).flywheel$getInstancingController();
|
||||||
IEntityInstanceFactory<? super T> factory = (IEntityInstanceFactory<? super T>) this.entities.get(type);
|
|
||||||
|
|
||||||
if (factory == null) return null;
|
|
||||||
else return factory.create(manager, tile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean _skipRender(Object o) {
|
@SuppressWarnings("unchecked")
|
||||||
return skipRender.getBoolean(o);
|
public static <T extends Entity> void setEntityController(EntityType<T> type, EntityInstancingController<? super T> instancingController) {
|
||||||
|
((EntityTypeExtension<T>) type).flywheel$setInstancingController(instancingController);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Config<CONFIG extends Config<CONFIG, FACTORY>, FACTORY> {
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends BlockEntity> BlockEntityType<? super T> getType(T blockEntity) {
|
||||||
CONFIG factory(FACTORY rendererFactory);
|
return (BlockEntityType<? super T>) blockEntity.getType();
|
||||||
|
|
||||||
CONFIG setSkipRender(boolean skipRender);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TileConfig<T extends BlockEntity> implements Config<TileConfig<T>, ITileInstanceFactory<? super T>> {
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends Entity> EntityType<? super T> getType(T entity) {
|
||||||
|
return (EntityType<? super T>) entity.getType();
|
||||||
|
}
|
||||||
|
|
||||||
private final BlockEntityType<T> type;
|
public static class BlockEntityConfig<T extends BlockEntity> {
|
||||||
|
protected BlockEntityType<T> type;
|
||||||
|
protected BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||||
|
protected Predicate<T> skipRender;
|
||||||
|
|
||||||
public TileConfig(BlockEntityType<T> type) {
|
public BlockEntityConfig(BlockEntityType<T> type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileConfig<T> factory(ITileInstanceFactory<? super T> rendererFactory) {
|
public BlockEntityConfig<T> factory(BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> instanceFactory) {
|
||||||
tiles.put(type, rendererFactory);
|
this.instanceFactory = instanceFactory;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileConfig<T> setSkipRender(boolean skipRender) {
|
public BlockEntityConfig<T> skipRender(Predicate<T> skipRender) {
|
||||||
InstancedRenderRegistry.this.skipRender.put(type, skipRender);
|
this.skipRender = skipRender;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockEntityConfig<T> alwaysSkipRender() {
|
||||||
|
this.skipRender = be -> true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleBlockEntityInstancingController<T> apply() {
|
||||||
|
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
|
||||||
|
if (skipRender == null) {
|
||||||
|
skipRender = be -> false;
|
||||||
|
}
|
||||||
|
SimpleBlockEntityInstancingController<T> controller = new SimpleBlockEntityInstancingController<>(instanceFactory, skipRender);
|
||||||
|
setBlockEntityController(type, controller);
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EntityConfig<T extends Entity> implements Config<EntityConfig<T>, IEntityInstanceFactory<? super T>> {
|
public static class EntityConfig<T extends Entity> {
|
||||||
|
protected EntityType<T> type;
|
||||||
private final EntityType<T> type;
|
protected BiFunction<MaterialManager, T, EntityInstance<? super T>> instanceFactory;
|
||||||
|
protected Predicate<T> skipRender;
|
||||||
|
|
||||||
public EntityConfig(EntityType<T> type) {
|
public EntityConfig(EntityType<T> type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityConfig<T> factory(IEntityInstanceFactory<? super T> rendererFactory) {
|
public EntityConfig<T> factory(BiFunction<MaterialManager, T, EntityInstance<? super T>> instanceFactory) {
|
||||||
entities.put(type, rendererFactory);
|
this.instanceFactory = instanceFactory;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityConfig<T> setSkipRender(boolean skipRender) {
|
public EntityConfig<T> skipRender(Predicate<T> skipRender) {
|
||||||
InstancedRenderRegistry.this.skipRender.put(type, skipRender);
|
this.skipRender = skipRender;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityConfig<T> alwaysSkipRender() {
|
||||||
|
this.skipRender = entity -> true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleEntityInstancingController<T> apply() {
|
||||||
|
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
|
||||||
|
if (skipRender == null) {
|
||||||
|
skipRender = entity -> false;
|
||||||
|
}
|
||||||
|
SimpleEntityInstancingController<T> controller = new SimpleEntityInstancingController<>(instanceFactory, skipRender);
|
||||||
|
setEntityController(type, controller);
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,18 +6,14 @@ import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialGroup;
|
import com.jozufozu.flywheel.api.MaterialGroup;
|
||||||
import com.jozufozu.flywheel.backend.RenderLayer;
|
import com.jozufozu.flywheel.backend.RenderLayer;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.SuperBufferSource;
|
import com.jozufozu.flywheel.backend.instancing.SuperBufferSource;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.Engine;
|
|
||||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||||
import com.mojang.blaze3d.platform.Lighting;
|
import com.mojang.blaze3d.platform.Lighting;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.tile;
|
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.Material;
|
import com.jozufozu.flywheel.api.Material;
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.IDynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.ITickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||||
|
@ -22,28 +22,28 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
*
|
*
|
||||||
* <br><br> There are a few additional features that overriding classes can opt in to:
|
* <br><br> There are a few additional features that overriding classes can opt in to:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link IDynamicInstance}</li>
|
* <li>{@link DynamicInstance}</li>
|
||||||
* <li>{@link ITickableInstance}</li>
|
* <li>{@link TickableInstance}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* See the interfaces' documentation for more information about each one.
|
* See the interfaces' documentation for more information about each one.
|
||||||
*
|
*
|
||||||
* <br> Implementing one or more of these will give a {@link TileEntityInstance} access
|
* <br> Implementing one or more of these will give a {@link BlockEntityInstance} access
|
||||||
* to more interesting and regular points within a tick or a frame.
|
* to more interesting and regular points within a tick or a frame.
|
||||||
*
|
*
|
||||||
* @param <T> The type of {@link BlockEntity} your class is an instance of.
|
* @param <T> The type of {@link BlockEntity} your class is an instance of.
|
||||||
*/
|
*/
|
||||||
public abstract class TileEntityInstance<T extends BlockEntity> extends AbstractInstance {
|
public abstract class BlockEntityInstance<T extends BlockEntity> extends AbstractInstance {
|
||||||
|
|
||||||
protected final T tile;
|
protected final T blockEntity;
|
||||||
protected final BlockPos pos;
|
protected final BlockPos pos;
|
||||||
protected final BlockPos instancePos;
|
protected final BlockPos instancePos;
|
||||||
protected final BlockState blockState;
|
protected final BlockState blockState;
|
||||||
|
|
||||||
public TileEntityInstance(MaterialManager materialManager, T tile) {
|
public BlockEntityInstance(MaterialManager materialManager, T blockEntity) {
|
||||||
super(materialManager, tile.getLevel());
|
super(materialManager, blockEntity.getLevel());
|
||||||
this.tile = tile;
|
this.blockEntity = blockEntity;
|
||||||
this.pos = tile.getBlockPos();
|
this.pos = blockEntity.getBlockPos();
|
||||||
this.blockState = tile.getBlockState();
|
this.blockState = blockEntity.getBlockState();
|
||||||
this.instancePos = pos.subtract(materialManager.getOriginCoordinate());
|
this.instancePos = pos.subtract(materialManager.getOriginCoordinate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,12 +56,12 @@ public abstract class TileEntityInstance<T extends BlockEntity> extends Abstract
|
||||||
* @return <code>true</code> if this instance should be discarded and refreshed.
|
* @return <code>true</code> if this instance should be discarded and refreshed.
|
||||||
*/
|
*/
|
||||||
public boolean shouldReset() {
|
public boolean shouldReset() {
|
||||||
return tile.getBlockState() != blockState;
|
return blockEntity.getBlockState() != blockState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In order to accommodate for floating point precision errors at high coordinates,
|
* In order to accommodate for floating point precision errors at high coordinates,
|
||||||
* {@link TileInstanceManager}s are allowed to arbitrarily adjust the origin, and
|
* {@link BlockEntityInstanceManager}s are allowed to arbitrarily adjust the origin, and
|
||||||
* shift the world matrix provided as a shader uniform accordingly.
|
* shift the world matrix provided as a shader uniform accordingly.
|
||||||
*
|
*
|
||||||
* @return The {@link BlockPos position} of the {@link BlockEntity} this instance
|
* @return The {@link BlockPos position} of the {@link BlockEntity} this instance
|
|
@ -1,46 +1,44 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.tile;
|
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
public class TileInstanceManager extends InstanceManager<BlockEntity> {
|
public class BlockEntityInstanceManager extends InstanceManager<BlockEntity> {
|
||||||
|
|
||||||
public TileInstanceManager(MaterialManager materialManager) {
|
public BlockEntityInstanceManager(MaterialManager materialManager) {
|
||||||
super(materialManager);
|
super(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canInstance(BlockEntity obj) {
|
protected boolean canInstance(BlockEntity obj) {
|
||||||
return obj != null && InstancedRenderRegistry.getInstance().canInstance(obj.getType());
|
return obj != null && InstancedRenderRegistry.canInstance(obj.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractInstance createRaw(BlockEntity obj) {
|
protected AbstractInstance createRaw(BlockEntity obj) {
|
||||||
return InstancedRenderRegistry.getInstance()
|
return InstancedRenderRegistry.createInstance(materialManager, obj);
|
||||||
.create(materialManager, obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canCreateInstance(BlockEntity tile) {
|
protected boolean canCreateInstance(BlockEntity blockEntity) {
|
||||||
if (tile.isRemoved()) return false;
|
if (blockEntity.isRemoved()) return false;
|
||||||
|
|
||||||
Level world = tile.getLevel();
|
Level world = blockEntity.getLevel();
|
||||||
|
|
||||||
if (world == null) return false;
|
if (world == null) return false;
|
||||||
|
|
||||||
if (world.isEmptyBlock(tile.getBlockPos())) return false;
|
if (world.isEmptyBlock(blockEntity.getBlockPos())) return false;
|
||||||
|
|
||||||
if (Backend.isFlywheelWorld(world)) {
|
if (Backend.isFlywheelWorld(world)) {
|
||||||
BlockPos pos = tile.getBlockPos();
|
BlockPos pos = blockEntity.getBlockPos();
|
||||||
|
|
||||||
BlockGetter existingChunk = world.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4);
|
BlockGetter existingChunk = world.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4);
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
|
public interface BlockEntityInstancingController<T extends BlockEntity> {
|
||||||
|
BlockEntityInstance<? super T> createInstance(MaterialManager materialManager, T blockEntity);
|
||||||
|
|
||||||
|
boolean shouldSkipRender(T blockEntity);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
|
public interface BlockEntityTypeExtension<T extends BlockEntity> {
|
||||||
|
BlockEntityInstancingController<? super T> flywheel$getInstancingController();
|
||||||
|
|
||||||
|
void flywheel$setInstancingController(BlockEntityInstancingController<? super T> instancingController);
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
|
public class SimpleBlockEntityInstancingController<T extends BlockEntity> implements BlockEntityInstancingController<T> {
|
||||||
|
protected BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||||
|
protected Predicate<T> skipRender;
|
||||||
|
|
||||||
|
public SimpleBlockEntityInstancingController(BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
||||||
|
this.instanceFactory = instanceFactory;
|
||||||
|
this.skipRender = skipRender;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntityInstance<? super T> createInstance(MaterialManager materialManager, T blockEntity) {
|
||||||
|
return instanceFactory.apply(materialManager, blockEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldSkipRender(T blockEntity) {
|
||||||
|
return skipRender.test(blockEntity);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||||
package com.jozufozu.flywheel.backend.instancing.tile;
|
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.entity;
|
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.IDynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.ITickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
|
||||||
import com.jozufozu.flywheel.light.LightListener;
|
import com.jozufozu.flywheel.light.LightListener;
|
||||||
import com.jozufozu.flywheel.light.LightProvider;
|
import com.jozufozu.flywheel.light.LightProvider;
|
||||||
import com.jozufozu.flywheel.light.MovingListener;
|
import com.jozufozu.flywheel.light.MovingListener;
|
||||||
|
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -24,8 +24,8 @@ import net.minecraft.world.phys.Vec3;
|
||||||
* *
|
* *
|
||||||
* <br><br> There are a few additional features that overriding classes can opt in to:
|
* <br><br> There are a few additional features that overriding classes can opt in to:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link IDynamicInstance}</li>
|
* <li>{@link DynamicInstance}</li>
|
||||||
* <li>{@link ITickableInstance}</li>
|
* <li>{@link TickableInstance}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* See the interfaces' documentation for more information about each one.
|
* See the interfaces' documentation for more information about each one.
|
||||||
*
|
*
|
||||||
|
@ -65,7 +65,7 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In order to accommodate for floating point precision errors at high coordinates,
|
* In order to accommodate for floating point precision errors at high coordinates,
|
||||||
* {@link TileInstanceManager}s are allowed to arbitrarily adjust the origin, and
|
* {@link BlockEntityInstanceManager}s are allowed to arbitrarily adjust the origin, and
|
||||||
* shift the world matrix provided as a shader uniform accordingly.
|
* shift the world matrix provided as a shader uniform accordingly.
|
||||||
*
|
*
|
||||||
* @return The position this instance should be rendered at to appear in the correct location.
|
* @return The position this instance should be rendered at to appear in the correct location.
|
||||||
|
@ -78,7 +78,7 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In order to accommodate for floating point precision errors at high coordinates,
|
* In order to accommodate for floating point precision errors at high coordinates,
|
||||||
* {@link TileInstanceManager}s are allowed to arbitrarily adjust the origin, and
|
* {@link BlockEntityInstanceManager}s are allowed to arbitrarily adjust the origin, and
|
||||||
* shift the world matrix provided as a shader uniform accordingly.
|
* shift the world matrix provided as a shader uniform accordingly.
|
||||||
*
|
*
|
||||||
* @return The position this instance should be rendered at to appear in the correct location.
|
* @return The position this instance should be rendered at to appear in the correct location.
|
||||||
|
|
|
@ -5,7 +5,6 @@ import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
@ -20,13 +19,12 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canInstance(Entity obj) {
|
protected boolean canInstance(Entity obj) {
|
||||||
return obj != null && InstancedRenderRegistry.getInstance().canInstance(obj.getType());
|
return obj != null && InstancedRenderRegistry.canInstance(obj.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractInstance createRaw(Entity obj) {
|
protected AbstractInstance createRaw(Entity obj) {
|
||||||
return InstancedRenderRegistry.getInstance()
|
return InstancedRenderRegistry.createInstance(materialManager, obj);
|
||||||
.create(materialManager, obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
|
public interface EntityInstancingController<T extends Entity> {
|
||||||
|
EntityInstance<? super T> createInstance(MaterialManager materialManager, T entity);
|
||||||
|
|
||||||
|
boolean shouldSkipRender(T entity);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
|
public interface EntityTypeExtension<T extends Entity> {
|
||||||
|
EntityInstancingController<? super T> flywheel$getInstancingController();
|
||||||
|
|
||||||
|
void flywheel$setInstancingController(EntityInstancingController<? super T> instancingController);
|
||||||
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.entity;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
|
||||||
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface IEntityInstanceFactory<E extends Entity> {
|
|
||||||
EntityInstance<? super E> create(MaterialManager manager, E te);
|
|
||||||
}
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
|
public class SimpleEntityInstancingController<T extends Entity> implements EntityInstancingController<T> {
|
||||||
|
protected BiFunction<MaterialManager, T, EntityInstance<? super T>> instanceFactory;
|
||||||
|
protected Predicate<T> skipRender;
|
||||||
|
|
||||||
|
public SimpleEntityInstancingController(BiFunction<MaterialManager, T, EntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
||||||
|
this.instanceFactory = instanceFactory;
|
||||||
|
this.skipRender = skipRender;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityInstance<? super T> createInstance(MaterialManager materialManager, T entity) {
|
||||||
|
return instanceFactory.apply(materialManager, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldSkipRender(T entity) {
|
||||||
|
return skipRender.test(entity);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,11 +9,11 @@ import java.util.stream.Stream;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialGroup;
|
import com.jozufozu.flywheel.api.MaterialGroup;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
|
||||||
import com.jozufozu.flywheel.backend.RenderLayer;
|
import com.jozufozu.flywheel.backend.RenderLayer;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||||
import com.jozufozu.flywheel.backend.instancing.Engine;
|
import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||||
import com.jozufozu.flywheel.core.WorldContext;
|
import com.jozufozu.flywheel.core.WorldContext;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.tile;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
|
||||||
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ITileInstanceFactory<T extends BlockEntity> {
|
|
||||||
TileEntityInstance<? super T> create(MaterialManager manager, T te);
|
|
||||||
}
|
|
|
@ -62,7 +62,7 @@ public class FileResolution {
|
||||||
* Called after all files are loaded. If we can't find the file here, it doesn't exist.
|
* Called after all files are loaded. If we can't find the file here, it doesn't exist.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
void resolve(ISourceHolder sources) {
|
void resolve(SourceHolder sources) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
file = sources.findSource(fileLoc);
|
file = sources.findSource(fileLoc);
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class Resolver {
|
||||||
/**
|
/**
|
||||||
* Try and resolve all referenced source files, printing errors if any aren't found.
|
* Try and resolve all referenced source files, printing errors if any aren't found.
|
||||||
*/
|
*/
|
||||||
public void resolve(ISourceHolder sources) {
|
public void resolve(SourceHolder sources) {
|
||||||
for (FileResolution resolution : resolutions.values()) {
|
for (FileResolution resolution : resolutions.values()) {
|
||||||
resolution.resolve(sources);
|
resolution.resolve(sources);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
/**
|
/**
|
||||||
* The main object for loading and parsing source files.
|
* The main object for loading and parsing source files.
|
||||||
*/
|
*/
|
||||||
public class ShaderSources implements ISourceHolder {
|
public class ShaderSources implements SourceHolder {
|
||||||
public static final String SHADER_DIR = "flywheel/shaders/";
|
public static final String SHADER_DIR = "flywheel/shaders/";
|
||||||
public static final ArrayList<String> EXTENSIONS = Lists.newArrayList(".vert", ".vsh", ".frag", ".fsh", ".glsl");
|
public static final ArrayList<String> EXTENSIONS = Lists.newArrayList(".vert", ".vsh", ".frag", ".fsh", ".glsl");
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.resources.ResourceLocation;
|
||||||
* A minimal source file lookup function.
|
* A minimal source file lookup function.
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ISourceHolder {
|
public interface SourceHolder {
|
||||||
|
|
||||||
SourceFile findSource(ResourceLocation name);
|
SourceFile findSource(ResourceLocation name);
|
||||||
}
|
}
|
|
@ -3,9 +3,6 @@ package com.jozufozu.flywheel.config;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
|
||||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
|
||||||
|
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package com.jozufozu.flywheel.core.crumbling;
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
public class CrumblingInstanceManager extends TileInstanceManager {
|
public class CrumblingInstanceManager extends BlockEntityInstanceManager {
|
||||||
|
|
||||||
public CrumblingInstanceManager(MaterialManager materialManager) {
|
public CrumblingInstanceManager(MaterialManager materialManager) {
|
||||||
super(materialManager);
|
super(materialManager);
|
||||||
|
|
|
@ -6,8 +6,8 @@ import java.util.SortedSet;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
|
@ -36,7 +36,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for rendering the block breaking overlay for instanced tiles.
|
* Responsible for rendering the block breaking overlay for instanced block entities.
|
||||||
*/
|
*/
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
@Mod.EventBusSubscriber(Dist.CLIENT)
|
@Mod.EventBusSubscriber(Dist.CLIENT)
|
||||||
|
@ -57,7 +57,7 @@ public class CrumblingRenderer {
|
||||||
public static void renderBreaking(RenderLayerEvent event) {
|
public static void renderBreaking(RenderLayerEvent event) {
|
||||||
if (!Backend.canUseInstancing(event.getWorld())) return;
|
if (!Backend.canUseInstancing(event.getWorld())) return;
|
||||||
|
|
||||||
Int2ObjectMap<List<BlockEntity>> activeStages = getActiveStageTiles(event.getWorld());
|
Int2ObjectMap<List<BlockEntity>> activeStages = getActiveStageBlockEntities(event.getWorld());
|
||||||
|
|
||||||
if (activeStages.isEmpty()) return;
|
if (activeStages.isEmpty()) return;
|
||||||
|
|
||||||
|
@ -90,9 +90,9 @@ public class CrumblingRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Associate each breaking stage with a list of all tile entities at that stage.
|
* Associate each breaking stage with a list of all block entities at that stage.
|
||||||
*/
|
*/
|
||||||
private static Int2ObjectMap<List<BlockEntity>> getActiveStageTiles(ClientLevel world) {
|
private static Int2ObjectMap<List<BlockEntity>> getActiveStageBlockEntities(ClientLevel world) {
|
||||||
|
|
||||||
Int2ObjectMap<List<BlockEntity>> breakingEntities = new Int2ObjectArrayMap<>();
|
Int2ObjectMap<List<BlockEntity>> breakingEntities = new Int2ObjectArrayMap<>();
|
||||||
|
|
||||||
|
@ -105,11 +105,11 @@ public class CrumblingRenderer {
|
||||||
int blockDamage = progresses.last()
|
int blockDamage = progresses.last()
|
||||||
.getProgress();
|
.getProgress();
|
||||||
|
|
||||||
BlockEntity tileEntity = world.getBlockEntity(breakingPos);
|
BlockEntity blockEntity = world.getBlockEntity(breakingPos);
|
||||||
|
|
||||||
if (tileEntity != null) {
|
if (blockEntity != null) {
|
||||||
List<BlockEntity> tileEntities = breakingEntities.computeIfAbsent(blockDamage, $ -> new ArrayList<>());
|
List<BlockEntity> blockEntities = breakingEntities.computeIfAbsent(blockDamage, $ -> new ArrayList<>());
|
||||||
tileEntities.add(tileEntity);
|
blockEntities.add(blockEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ package com.jozufozu.flywheel.core.hardcoded;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.core.Formats;
|
import com.jozufozu.flywheel.core.Formats;
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
|
||||||
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
|
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
|
||||||
import com.mojang.blaze3d.platform.MemoryTracker;
|
import com.mojang.blaze3d.platform.MemoryTracker;
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,11 @@ package com.jozufozu.flywheel.core.materials.model;
|
||||||
import com.jozufozu.flywheel.api.struct.Batched;
|
import com.jozufozu.flywheel.api.struct.Batched;
|
||||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
|
||||||
import com.jozufozu.flywheel.core.layout.MatrixItems;
|
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.Programs;
|
import com.jozufozu.flywheel.core.Programs;
|
||||||
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
|
import com.jozufozu.flywheel.core.layout.MatrixItems;
|
||||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.jozufozu.flywheel.core.materials.model;
|
package com.jozufozu.flywheel.core.materials.model;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe;
|
import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe;
|
||||||
import com.jozufozu.flywheel.util.MatrixWrite;
|
import com.jozufozu.flywheel.util.MatrixWrite;
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ package com.jozufozu.flywheel.core.materials.oriented;
|
||||||
import com.jozufozu.flywheel.api.struct.Batched;
|
import com.jozufozu.flywheel.api.struct.Batched;
|
||||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.Programs;
|
import com.jozufozu.flywheel.core.Programs;
|
||||||
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ package com.jozufozu.flywheel.core.materials.oriented;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe;
|
import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe;
|
||||||
|
|
||||||
public class OrientedWriterUnsafe extends BasicWriterUnsafe<OrientedData> {
|
public class OrientedWriterUnsafe extends BasicWriterUnsafe<OrientedData> {
|
||||||
|
|
|
@ -7,13 +7,13 @@ import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.ShaderContext;
|
import com.jozufozu.flywheel.backend.ShaderContext;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.core.shader.extension.IExtensionInstance;
|
import com.jozufozu.flywheel.core.shader.extension.ExtensionInstance;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A shader program that be arbitrarily "extended". This class can take in any number of program extensions, and
|
* A shader program that be arbitrarily "extended". This class can take in any number of program extensions, and
|
||||||
* will initialize them and then call their {@link IExtensionInstance#bind() bind} function every subsequent time this
|
* will initialize them and then call their {@link ExtensionInstance#bind() bind} function every subsequent time this
|
||||||
* program is bound. An "extension" is something that interacts with the shader program in a way that is invisible to
|
* program is bound. An "extension" is something that interacts with the shader program in a way that is invisible to
|
||||||
* the caller using the program. This is used by some programs to implement the different fog modes. Other uses might
|
* the caller using the program. This is used by some programs to implement the different fog modes. Other uses might
|
||||||
* include binding extra textures to allow for blocks to have normal maps, for example. As the extensions are
|
* include binding extra textures to allow for blocks to have normal maps, for example. As the extensions are
|
||||||
|
@ -22,7 +22,7 @@ import net.minecraft.resources.ResourceLocation;
|
||||||
*/
|
*/
|
||||||
public class ExtensibleGlProgram extends GlProgram {
|
public class ExtensibleGlProgram extends GlProgram {
|
||||||
|
|
||||||
protected final List<IExtensionInstance> extensions = new ArrayList<>();
|
protected final List<ExtensionInstance> extensions = new ArrayList<>();
|
||||||
|
|
||||||
public ExtensibleGlProgram(ResourceLocation name, int handle) {
|
public ExtensibleGlProgram(ResourceLocation name, int handle) {
|
||||||
super(name, handle);
|
super(name, handle);
|
||||||
|
@ -32,7 +32,7 @@ public class ExtensibleGlProgram extends GlProgram {
|
||||||
public void bind() {
|
public void bind() {
|
||||||
super.bind();
|
super.bind();
|
||||||
|
|
||||||
extensions.forEach(IExtensionInstance::bind);
|
extensions.forEach(ExtensionInstance::bind);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,7 +42,7 @@ public class ExtensibleGlProgram extends GlProgram {
|
||||||
.append(name)
|
.append(name)
|
||||||
.append('[');
|
.append('[');
|
||||||
|
|
||||||
for (IExtensionInstance extension : extensions) {
|
for (ExtensionInstance extension : extensions) {
|
||||||
builder.append(extension)
|
builder.append(extension)
|
||||||
.append('+');
|
.append('+');
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,22 +5,22 @@ import java.util.List;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.core.shader.spec.IGameStateCondition;
|
import com.jozufozu.flywheel.core.shader.spec.GameStateCondition;
|
||||||
import com.jozufozu.flywheel.util.Pair;
|
import com.jozufozu.flywheel.util.Pair;
|
||||||
|
|
||||||
public class GameStateProgram<P extends GlProgram> implements ContextAwareProgram<P> {
|
public class GameStateProgram<P extends GlProgram> implements ContextAwareProgram<P> {
|
||||||
|
|
||||||
private final List<Pair<IGameStateCondition, P>> variants;
|
private final List<Pair<GameStateCondition, P>> variants;
|
||||||
private final P fallback;
|
private final P fallback;
|
||||||
|
|
||||||
protected GameStateProgram(List<Pair<IGameStateCondition, P>> variants, P fallback) {
|
protected GameStateProgram(List<Pair<GameStateCondition, P>> variants, P fallback) {
|
||||||
this.variants = variants;
|
this.variants = variants;
|
||||||
this.fallback = fallback;
|
this.fallback = fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public P get() {
|
public P get() {
|
||||||
for (Pair<IGameStateCondition, P> variant : variants) {
|
for (Pair<GameStateCondition, P> variant : variants) {
|
||||||
if (variant.first()
|
if (variant.first()
|
||||||
.isMet()) return variant.second();
|
.isMet()) return variant.second();
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ public class GameStateProgram<P extends GlProgram> implements ContextAwareProgra
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
for (Pair<IGameStateCondition, P> variant : variants) {
|
for (Pair<GameStateCondition, P> variant : variants) {
|
||||||
variant.second()
|
variant.second()
|
||||||
.delete();
|
.delete();
|
||||||
}
|
}
|
||||||
|
@ -44,13 +44,13 @@ public class GameStateProgram<P extends GlProgram> implements ContextAwareProgra
|
||||||
|
|
||||||
public static class Builder<P extends GlProgram> {
|
public static class Builder<P extends GlProgram> {
|
||||||
private final P fallback;
|
private final P fallback;
|
||||||
private final List<Pair<IGameStateCondition, P>> variants = new ArrayList<>();
|
private final List<Pair<GameStateCondition, P>> variants = new ArrayList<>();
|
||||||
|
|
||||||
public Builder(P fallback) {
|
public Builder(P fallback) {
|
||||||
this.fallback = fallback;
|
this.fallback = fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder<P> withVariant(IGameStateCondition condition, P program) {
|
public Builder<P> withVariant(GameStateCondition condition, P program) {
|
||||||
variants.add(Pair.of(condition, program));
|
variants.add(Pair.of(condition, program));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.core.shader.extension;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public interface IExtensionInstance {
|
public interface ExtensionInstance {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind the extra program state. It is recommended to grab the state information from global variables.
|
* Bind the extra program state. It is recommended to grab the state information from global variables.
|
|
@ -5,7 +5,7 @@ import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class UnitExtensionInstance implements IExtensionInstance {
|
public class UnitExtensionInstance implements ExtensionInstance {
|
||||||
|
|
||||||
public static final ResourceLocation NAME = Flywheel.rl("unit");
|
public static final ResourceLocation NAME = Flywheel.rl("unit");
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class WorldFog implements IExtensionInstance {
|
public class WorldFog implements ExtensionInstance {
|
||||||
|
|
||||||
public static final ResourceLocation NAME = Flywheel.rl("fog");
|
public static final ResourceLocation NAME = Flywheel.rl("fog");
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ import com.mojang.serialization.Codec;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public interface IGameStateProvider {
|
public interface GameStateProvider {
|
||||||
|
|
||||||
Codec<IGameStateProvider> CODEC = ResourceLocation.CODEC.xmap(GameStateRegistry::getStateProvider, IGameStateProvider::getID);
|
Codec<GameStateProvider> CODEC = ResourceLocation.CODEC.xmap(GameStateRegistry::getStateProvider, GameStateProvider::getID);
|
||||||
|
|
||||||
ResourceLocation getID();
|
ResourceLocation getID();
|
||||||
|
|
|
@ -2,11 +2,11 @@ package com.jozufozu.flywheel.core.shader.gamestate;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.core.shader.spec.IBooleanStateProvider;
|
import com.jozufozu.flywheel.core.shader.spec.BooleanStateProvider;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class NormalDebugStateProvider implements IBooleanStateProvider {
|
public class NormalDebugStateProvider implements BooleanStateProvider {
|
||||||
|
|
||||||
public static final NormalDebugStateProvider INSTANCE = new NormalDebugStateProvider();
|
public static final NormalDebugStateProvider INSTANCE = new NormalDebugStateProvider();
|
||||||
public static final ResourceLocation NAME = Flywheel.rl("normal_debug");
|
public static final ResourceLocation NAME = Flywheel.rl("normal_debug");
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
package com.jozufozu.flywheel.core.shader.spec;
|
package com.jozufozu.flywheel.core.shader.spec;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.shader.gamestate.IGameStateProvider;
|
import com.jozufozu.flywheel.core.shader.gamestate.GameStateProvider;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class BooleanGameStateCondition implements IGameStateCondition {
|
public class BooleanGameStateCondition implements GameStateCondition {
|
||||||
|
|
||||||
public static final Codec<BooleanGameStateCondition> BOOLEAN_SUGAR = IGameStateProvider.CODEC.xmap(gameContext -> {
|
public static final Codec<BooleanGameStateCondition> BOOLEAN_SUGAR = GameStateProvider.CODEC.xmap(gameContext -> {
|
||||||
if (gameContext instanceof IBooleanStateProvider) {
|
if (gameContext instanceof BooleanStateProvider) {
|
||||||
return new BooleanGameStateCondition(((IBooleanStateProvider) gameContext));
|
return new BooleanGameStateCondition(((BooleanStateProvider) gameContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}, IGameStateCondition::getStateProvider);
|
}, GameStateCondition::getStateProvider);
|
||||||
protected final IBooleanStateProvider context;
|
protected final BooleanStateProvider context;
|
||||||
|
|
||||||
public BooleanGameStateCondition(IBooleanStateProvider context) {
|
public BooleanGameStateCondition(BooleanStateProvider context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public class BooleanGameStateCondition implements IGameStateCondition {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IGameStateProvider getStateProvider() {
|
public GameStateProvider getStateProvider() {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.jozufozu.flywheel.core.shader.spec;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.core.shader.gamestate.GameStateProvider;
|
||||||
|
|
||||||
|
public interface BooleanStateProvider extends GameStateProvider {
|
||||||
|
|
||||||
|
boolean isTrue();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Boolean getValue() {
|
||||||
|
return isTrue();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
package com.jozufozu.flywheel.core.shader.spec;
|
package com.jozufozu.flywheel.core.shader.spec;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.shader.gamestate.IGameStateProvider;
|
import com.jozufozu.flywheel.core.shader.gamestate.GameStateProvider;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public interface IGameStateCondition {
|
public interface GameStateCondition {
|
||||||
|
|
||||||
ResourceLocation getID();
|
ResourceLocation getID();
|
||||||
|
|
||||||
IGameStateProvider getStateProvider();
|
GameStateProvider getStateProvider();
|
||||||
|
|
||||||
boolean isMet();
|
boolean isMet();
|
||||||
}
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.shader.spec;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.shader.gamestate.IGameStateProvider;
|
|
||||||
|
|
||||||
public interface IBooleanStateProvider extends IGameStateProvider {
|
|
||||||
|
|
||||||
boolean isTrue();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default Boolean getValue() {
|
|
||||||
return isTrue();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,10 +9,10 @@ import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.DataResult;
|
import com.mojang.serialization.DataResult;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
public record ProgramState(IGameStateCondition context, List<String> defines) {
|
public record ProgramState(GameStateCondition context, List<String> defines) {
|
||||||
|
|
||||||
// TODO: Use Codec.dispatch
|
// TODO: Use Codec.dispatch
|
||||||
private static final Codec<IGameStateCondition> WHEN = Codec.either(BooleanGameStateCondition.BOOLEAN_SUGAR, SpecificValueCondition.CODEC)
|
private static final Codec<GameStateCondition> WHEN = Codec.either(BooleanGameStateCondition.BOOLEAN_SUGAR, SpecificValueCondition.CODEC)
|
||||||
.flatXmap(either -> either.map(DataResult::success, DataResult::success), any -> {
|
.flatXmap(either -> either.map(DataResult::success, DataResult::success), any -> {
|
||||||
if (any instanceof BooleanGameStateCondition) {
|
if (any instanceof BooleanGameStateCondition) {
|
||||||
return DataResult.success(Either.left((BooleanGameStateCondition) any));
|
return DataResult.success(Either.left((BooleanGameStateCondition) any));
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
package com.jozufozu.flywheel.core.shader.spec;
|
package com.jozufozu.flywheel.core.shader.spec;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.shader.gamestate.IGameStateProvider;
|
import com.jozufozu.flywheel.core.shader.gamestate.GameStateProvider;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class SpecificValueCondition implements IGameStateCondition {
|
public class SpecificValueCondition implements GameStateCondition {
|
||||||
|
|
||||||
public static final Codec<SpecificValueCondition> CODEC = RecordCodecBuilder.create(condition -> condition.group(IGameStateProvider.CODEC.fieldOf("provider")
|
public static final Codec<SpecificValueCondition> CODEC = RecordCodecBuilder.create(condition -> condition.group(GameStateProvider.CODEC.fieldOf("provider")
|
||||||
.forGetter(SpecificValueCondition::getStateProvider), Codec.STRING.fieldOf("value")
|
.forGetter(SpecificValueCondition::getStateProvider), Codec.STRING.fieldOf("value")
|
||||||
.forGetter(SpecificValueCondition::getValue))
|
.forGetter(SpecificValueCondition::getValue))
|
||||||
.apply(condition, SpecificValueCondition::new));
|
.apply(condition, SpecificValueCondition::new));
|
||||||
|
|
||||||
private final String required;
|
private final String required;
|
||||||
private final IGameStateProvider context;
|
private final GameStateProvider context;
|
||||||
|
|
||||||
public SpecificValueCondition(IGameStateProvider context, String required) {
|
public SpecificValueCondition(GameStateProvider context, String required) {
|
||||||
this.required = required;
|
this.required = required;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ public class SpecificValueCondition implements IGameStateCondition {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IGameStateProvider getStateProvider() {
|
public GameStateProvider getStateProvider() {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
|
|
@ -3,8 +3,8 @@ package com.jozufozu.flywheel.core.vertex;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
|
|
||||||
public class PosTexNormalVertex implements VertexType {
|
public class PosTexNormalVertex implements VertexType {
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ import net.minecraft.world.ticks.LevelTickAccess;
|
||||||
|
|
||||||
public class VirtualRenderWorld extends Level implements FlywheelWorld {
|
public class VirtualRenderWorld extends Level implements FlywheelWorld {
|
||||||
public final Map<BlockPos, BlockState> blocksAdded = new HashMap<>();
|
public final Map<BlockPos, BlockState> blocksAdded = new HashMap<>();
|
||||||
public final Map<BlockPos, BlockEntity> tesAdded = new HashMap<>();
|
public final Map<BlockPos, BlockEntity> besAdded = new HashMap<>();
|
||||||
public final Set<SectionPos> spannedSections = new HashSet<>();
|
public final Set<SectionPos> spannedSections = new HashSet<>();
|
||||||
private final BlockPos.MutableBlockPos scratch = new BlockPos.MutableBlockPos();
|
private final BlockPos.MutableBlockPos scratch = new BlockPos.MutableBlockPos();
|
||||||
|
|
||||||
|
@ -85,9 +85,9 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld {
|
||||||
lighter.runUpdates(Integer.MAX_VALUE, false, false);
|
lighter.runUpdates(Integer.MAX_VALUE, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTileEntities(Collection<BlockEntity> tileEntities) {
|
public void setBlockEntities(Collection<BlockEntity> blockEntities) {
|
||||||
tesAdded.clear();
|
besAdded.clear();
|
||||||
tileEntities.forEach(te -> tesAdded.put(te.getBlockPos(), te));
|
blockEntities.forEach(be -> besAdded.put(be.getBlockPos(), be));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
|
@ -153,7 +153,7 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld {
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public BlockEntity getBlockEntity(BlockPos pos) {
|
public BlockEntity getBlockEntity(BlockPos pos) {
|
||||||
return tesAdded.get(pos);
|
return besAdded.get(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.jozufozu.flywheel.mixin;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityTypeExtension;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
|
||||||
|
@Mixin(BlockEntityType.class)
|
||||||
|
public class BlockEntityTypeMixin<T extends BlockEntity> implements BlockEntityTypeExtension<T> {
|
||||||
|
@Unique
|
||||||
|
private BlockEntityInstancingController<? super T> flywheel$instancingController;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntityInstancingController<? super T> flywheel$getInstancingController() {
|
||||||
|
return flywheel$instancingController;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flywheel$setInstancingController(BlockEntityInstancingController<? super T> instancingController) {
|
||||||
|
this.flywheel$instancingController = instancingController;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,8 +9,6 @@ import org.lwjgl.system.MemoryUtil;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.SuperBufferSource;
|
|
||||||
import com.jozufozu.flywheel.backend.model.DirectVertexConsumer;
|
|
||||||
import com.jozufozu.flywheel.backend.model.BufferBuilderHack;
|
import com.jozufozu.flywheel.backend.model.BufferBuilderHack;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
|
|
|
@ -24,11 +24,9 @@ public class CancelEntityRenderMixin {
|
||||||
private Iterable<Entity> filterEntities(ClientLevel world) {
|
private Iterable<Entity> filterEntities(ClientLevel world) {
|
||||||
Iterable<Entity> entities = world.entitiesForRendering();
|
Iterable<Entity> entities = world.entitiesForRendering();
|
||||||
if (Backend.isOn()) {
|
if (Backend.isOn()) {
|
||||||
|
|
||||||
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
||||||
|
|
||||||
InstancedRenderRegistry r = InstancedRenderRegistry.getInstance();
|
filtered.removeIf(InstancedRenderRegistry::shouldSkipRender);
|
||||||
filtered.removeIf(r::shouldSkipRender);
|
|
||||||
|
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,11 @@ public class ChunkRebuildHooksMixin {
|
||||||
|
|
||||||
@Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
|
||||||
private <E extends BlockEntity> void addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set<BlockEntity> set, E be, CallbackInfo ci) {
|
private <E extends BlockEntity> void addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set<BlockEntity> set, E be, CallbackInfo ci) {
|
||||||
|
|
||||||
if (Backend.canUseInstancing(be.getLevel())) {
|
if (Backend.canUseInstancing(be.getLevel())) {
|
||||||
|
if (InstancedRenderRegistry.canInstance(be.getType()))
|
||||||
|
InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be);
|
||||||
|
|
||||||
InstancedRenderRegistry registry = InstancedRenderRegistry.getInstance();
|
if (InstancedRenderRegistry.shouldSkipRender(be))
|
||||||
if (registry.canInstance(be.getType()))
|
|
||||||
InstancedRenderDispatcher.getTiles(be.getLevel()).queueAdd(be);
|
|
||||||
|
|
||||||
if (registry.shouldSkipRender(be))
|
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.jozufozu.flywheel.mixin;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityTypeExtension;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
|
||||||
|
@Mixin(EntityType.class)
|
||||||
|
public class EntityTypeMixin<T extends Entity> implements EntityTypeExtension<T> {
|
||||||
|
@Unique
|
||||||
|
private EntityInstancingController<? super T> flywheel$instancingController;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityInstancingController<? super T> flywheel$getInstancingController() {
|
||||||
|
return flywheel$instancingController;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flywheel$setInstancingController(EntityInstancingController<? super T> instancingController) {
|
||||||
|
this.flywheel$instancingController = instancingController;
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,9 +26,9 @@ public class InstanceAddMixin {
|
||||||
|
|
||||||
@Inject(method = "setBlockEntity",
|
@Inject(method = "setBlockEntity",
|
||||||
at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))
|
at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))
|
||||||
private void tileAdded(BlockEntity be, CallbackInfo ci) {
|
private void blockEntityAdded(BlockEntity be, CallbackInfo ci) {
|
||||||
if (level.isClientSide && Backend.isOn()) {
|
if (level.isClientSide && Backend.isOn()) {
|
||||||
InstancedRenderDispatcher.getTiles(this.level)
|
InstancedRenderDispatcher.getBlockEntities(this.level)
|
||||||
.add(be);
|
.add(be);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,18 +25,18 @@ public class InstanceRemoveMixin {
|
||||||
@Inject(at = @At("TAIL"), method = "setRemoved")
|
@Inject(at = @At("TAIL"), method = "setRemoved")
|
||||||
private void removeInstance(CallbackInfo ci) {
|
private void removeInstance(CallbackInfo ci) {
|
||||||
if (level instanceof ClientLevel && Backend.isOn()) {
|
if (level instanceof ClientLevel && Backend.isOn()) {
|
||||||
InstancedRenderDispatcher.getTiles(this.level)
|
InstancedRenderDispatcher.getBlockEntities(this.level)
|
||||||
.remove((BlockEntity) (Object) this);
|
.remove((BlockEntity) (Object) this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Don't do this.
|
// * Don't do this.
|
||||||
// * It can cause infinite loops if an instance class tries to access another tile entity in its constructor.
|
// * It can cause infinite loops if an instance class tries to access another block entity in its constructor.
|
||||||
// */
|
// */
|
||||||
// @Inject(at = @At("TAIL"), method = "clearRemoved")
|
// @Inject(at = @At("TAIL"), method = "clearRemoved")
|
||||||
// private void addInstance(CallbackInfo ci) {
|
// private void addInstance(CallbackInfo ci) {
|
||||||
// if (level.isClientSide) InstancedRenderDispatcher.getTiles(this.level)
|
// if (level.isClientSide) InstancedRenderDispatcher.getBlockEntities(this.level)
|
||||||
// .add((BlockEntity) (Object) this);
|
// .add((BlockEntity) (Object) this);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class RenderHooksMixin {
|
||||||
@Inject(at = @At("TAIL"), method = "setBlockDirty(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;)V")
|
@Inject(at = @At("TAIL"), method = "setBlockDirty(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;)V")
|
||||||
private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
|
private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
|
||||||
if (Backend.isOn()) {
|
if (Backend.isOn()) {
|
||||||
InstancedRenderDispatcher.getTiles(level)
|
InstancedRenderDispatcher.getBlockEntities(level)
|
||||||
.update(level.getBlockEntity(pos));
|
.update(level.getBlockEntity(pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package com.jozufozu.flywheel.vanilla;
|
package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.IDynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
|
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
@ -14,14 +14,14 @@ import net.minecraft.client.renderer.blockentity.BellRenderer;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.level.block.entity.BellBlockEntity;
|
import net.minecraft.world.level.block.entity.BellBlockEntity;
|
||||||
|
|
||||||
public class BellInstance extends TileEntityInstance<BellBlockEntity> implements IDynamicInstance {
|
public class BellInstance extends BlockEntityInstance<BellBlockEntity> implements DynamicInstance {
|
||||||
|
|
||||||
private final OrientedData bell;
|
private final OrientedData bell;
|
||||||
|
|
||||||
private float lastRingTime = Float.NaN;
|
private float lastRingTime = Float.NaN;
|
||||||
|
|
||||||
public BellInstance(MaterialManager materialManager, BellBlockEntity tile) {
|
public BellInstance(MaterialManager materialManager, BellBlockEntity blockEntity) {
|
||||||
super(materialManager, tile);
|
super(materialManager, blockEntity);
|
||||||
|
|
||||||
bell = createBellInstance()
|
bell = createBellInstance()
|
||||||
.setPivot(0.5f, 0.75f, 0.5f)
|
.setPivot(0.5f, 0.75f, 0.5f)
|
||||||
|
@ -30,15 +30,15 @@ public class BellInstance extends TileEntityInstance<BellBlockEntity> implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginFrame() {
|
public void beginFrame() {
|
||||||
float ringTime = (float)tile.ticks + AnimationTickHolder.getPartialTicks();
|
float ringTime = (float)blockEntity.ticks + AnimationTickHolder.getPartialTicks();
|
||||||
|
|
||||||
if (ringTime == lastRingTime) return;
|
if (ringTime == lastRingTime) return;
|
||||||
lastRingTime = ringTime;
|
lastRingTime = ringTime;
|
||||||
|
|
||||||
if (tile.shaking) {
|
if (blockEntity.shaking) {
|
||||||
float angle = Mth.sin(ringTime / (float) Math.PI) / (4.0F + ringTime / 3.0F);
|
float angle = Mth.sin(ringTime / (float) Math.PI) / (4.0F + ringTime / 3.0F);
|
||||||
|
|
||||||
Vector3f ringAxis = tile.clickDirection.getCounterClockWise().step();
|
Vector3f ringAxis = blockEntity.clickDirection.getCounterClockWise().step();
|
||||||
|
|
||||||
bell.setRotation(ringAxis.rotation(angle));
|
bell.setRotation(ringAxis.rotation(angle));
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,7 +59,7 @@ public class BellInstance extends TileEntityInstance<BellBlockEntity> implements
|
||||||
private OrientedData createBellInstance() {
|
private OrientedData createBellInstance() {
|
||||||
return materialManager.defaultCutout()
|
return materialManager.defaultCutout()
|
||||||
.material(Materials.ORIENTED)
|
.material(Materials.ORIENTED)
|
||||||
.model(tile.getType(), BellInstance::createBellModel)
|
.model(blockEntity.getType(), BellInstance::createBellModel)
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,12 @@ import java.util.Calendar;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.IDynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
@ -28,7 +28,7 @@ import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.LidBlockEntity;
|
import net.minecraft.world.level.block.entity.LidBlockEntity;
|
||||||
import net.minecraft.world.level.block.state.properties.ChestType;
|
import net.minecraft.world.level.block.state.properties.ChestType;
|
||||||
|
|
||||||
public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileEntityInstance<T> implements IDynamicInstance {
|
public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends BlockEntityInstance<T> implements DynamicInstance {
|
||||||
|
|
||||||
private final OrientedData body;
|
private final OrientedData body;
|
||||||
private final ModelData lid;
|
private final ModelData lid;
|
||||||
|
@ -41,13 +41,13 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileE
|
||||||
|
|
||||||
private float lastProgress = Float.NaN;
|
private float lastProgress = Float.NaN;
|
||||||
|
|
||||||
public ChestInstance(MaterialManager materialManager, T tile) {
|
public ChestInstance(MaterialManager materialManager, T blockEntity) {
|
||||||
super(materialManager, tile);
|
super(materialManager, blockEntity);
|
||||||
|
|
||||||
Block block = blockState.getBlock();
|
Block block = blockState.getBlock();
|
||||||
|
|
||||||
chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE;
|
chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE;
|
||||||
renderMaterial = Sheets.chooseMaterial(tile, chestType, isChristmas());
|
renderMaterial = Sheets.chooseMaterial(blockEntity, chestType, isChristmas());
|
||||||
|
|
||||||
body = baseInstance()
|
body = baseInstance()
|
||||||
.setPosition(getInstancePosition());
|
.setPosition(getInstancePosition());
|
||||||
|
@ -63,7 +63,7 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileE
|
||||||
|
|
||||||
DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> wrapper = chestBlock.combine(blockState, world, getWorldPosition(), true);
|
DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> wrapper = chestBlock.combine(blockState, world, getWorldPosition(), true);
|
||||||
|
|
||||||
this.lidProgress = wrapper.apply(ChestBlock.opennessCombiner(tile));
|
this.lidProgress = wrapper.apply(ChestBlock.opennessCombiner(blockEntity));
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package com.jozufozu.flywheel.vanilla;
|
package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.IDynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.ITickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
|
import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
@ -21,7 +21,7 @@ import net.minecraft.world.level.block.RenderShape;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance<T> implements IDynamicInstance, ITickableInstance {
|
public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance<T> implements DynamicInstance, TickableInstance {
|
||||||
|
|
||||||
private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png");
|
private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png");
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package com.jozufozu.flywheel.vanilla;
|
package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.IDynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
|
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
|
import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
|
@ -19,7 +19,7 @@ import net.minecraft.world.item.DyeColor;
|
||||||
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
||||||
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
||||||
|
|
||||||
public class ShulkerBoxInstance extends TileEntityInstance<ShulkerBoxBlockEntity> implements IDynamicInstance {
|
public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntity> implements DynamicInstance {
|
||||||
|
|
||||||
private final TextureAtlasSprite texture;
|
private final TextureAtlasSprite texture;
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ public class ShulkerBoxInstance extends TileEntityInstance<ShulkerBoxBlockEntity
|
||||||
|
|
||||||
private float lastProgress = Float.NaN;
|
private float lastProgress = Float.NaN;
|
||||||
|
|
||||||
public ShulkerBoxInstance(MaterialManager materialManager, ShulkerBoxBlockEntity tile) {
|
public ShulkerBoxInstance(MaterialManager materialManager, ShulkerBoxBlockEntity blockEntity) {
|
||||||
super(materialManager, tile);
|
super(materialManager, blockEntity);
|
||||||
|
|
||||||
DyeColor color = tile.getColor();
|
DyeColor color = blockEntity.getColor();
|
||||||
if (color == null) {
|
if (color == null) {
|
||||||
texture = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION.sprite();
|
texture = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION.sprite();
|
||||||
} else {
|
} else {
|
||||||
|
@ -56,7 +56,7 @@ public class ShulkerBoxInstance extends TileEntityInstance<ShulkerBoxBlockEntity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginFrame() {
|
public void beginFrame() {
|
||||||
float progress = tile.getProgress(AnimationTickHolder.getPartialTicks());
|
float progress = blockEntity.getProgress(AnimationTickHolder.getPartialTicks());
|
||||||
|
|
||||||
if (progress == lastProgress) return;
|
if (progress == lastProgress) return;
|
||||||
lastProgress = progress;
|
lastProgress = progress;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.vanilla;
|
package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
import static com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry.configure;
|
||||||
|
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
@ -28,34 +28,40 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
public class VanillaInstances {
|
public class VanillaInstances {
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
InstancedRenderRegistry r = InstancedRenderRegistry.getInstance();
|
configure(BlockEntityType.CHEST)
|
||||||
|
.alwaysSkipRender()
|
||||||
|
.factory(ChestInstance::new)
|
||||||
|
.apply();
|
||||||
|
configure(BlockEntityType.ENDER_CHEST)
|
||||||
|
.alwaysSkipRender()
|
||||||
|
.factory(ChestInstance::new)
|
||||||
|
.apply();
|
||||||
|
configure(BlockEntityType.TRAPPED_CHEST)
|
||||||
|
.alwaysSkipRender()
|
||||||
|
.factory(ChestInstance::new)
|
||||||
|
.apply();
|
||||||
|
|
||||||
r.tile(BlockEntityType.CHEST)
|
configure(BlockEntityType.BELL)
|
||||||
.setSkipRender(true)
|
.alwaysSkipRender()
|
||||||
.factory(ChestInstance::new);
|
.factory(BellInstance::new)
|
||||||
r.tile(BlockEntityType.ENDER_CHEST)
|
.apply();
|
||||||
.setSkipRender(true)
|
|
||||||
.factory(ChestInstance::new);
|
|
||||||
r.tile(BlockEntityType.TRAPPED_CHEST)
|
|
||||||
.setSkipRender(true)
|
|
||||||
.factory(ChestInstance::new);
|
|
||||||
|
|
||||||
r.tile(BlockEntityType.BELL)
|
configure(BlockEntityType.SHULKER_BOX)
|
||||||
.setSkipRender(true)
|
.alwaysSkipRender()
|
||||||
.factory(BellInstance::new);
|
.factory(ShulkerBoxInstance::new)
|
||||||
|
.apply();
|
||||||
|
|
||||||
r.tile(BlockEntityType.SHULKER_BOX)
|
configure(EntityType.MINECART)
|
||||||
.setSkipRender(true)
|
.alwaysSkipRender()
|
||||||
.factory(ShulkerBoxInstance::new);
|
.factory(MinecartInstance::new)
|
||||||
|
.apply();
|
||||||
r.entity(EntityType.MINECART)
|
configure(EntityType.HOPPER_MINECART)
|
||||||
.setSkipRender(true)
|
.alwaysSkipRender()
|
||||||
.factory(MinecartInstance::new);
|
.factory(MinecartInstance::new)
|
||||||
r.entity(EntityType.HOPPER_MINECART)
|
.apply();
|
||||||
.setSkipRender(true)
|
configure(EntityType.FURNACE_MINECART)
|
||||||
.factory(MinecartInstance::new);
|
.alwaysSkipRender()
|
||||||
r.entity(EntityType.FURNACE_MINECART)
|
.factory(MinecartInstance::new)
|
||||||
.setSkipRender(true)
|
.apply();
|
||||||
.factory(MinecartInstance::new);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"refmap": "flywheel.refmap.json",
|
"refmap": "flywheel.refmap.json",
|
||||||
"client": [
|
"client": [
|
||||||
|
"BlockEntityTypeMixin",
|
||||||
"BufferBuilderMixin",
|
"BufferBuilderMixin",
|
||||||
"BufferUploaderAccessor",
|
"BufferUploaderAccessor",
|
||||||
"CancelEntityRenderMixin",
|
"CancelEntityRenderMixin",
|
||||||
"ChunkRebuildHooksMixin",
|
"ChunkRebuildHooksMixin",
|
||||||
|
"EntityTypeMixin",
|
||||||
"FixFabulousDepthMixin",
|
"FixFabulousDepthMixin",
|
||||||
"InstanceAddMixin",
|
"InstanceAddMixin",
|
||||||
"InstanceRemoveMixin",
|
"InstanceRemoveMixin",
|
||||||
|
|
Loading…
Reference in a new issue