mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 14:33:57 +01:00
Always the first thing to fall apart
- Fix crumbling on indirect
This commit is contained in:
parent
eae1d0ef94
commit
68453d8349
@ -8,6 +8,8 @@ import java.util.Queue;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.RenderContext;
|
import dev.engine_room.flywheel.api.RenderContext;
|
||||||
@ -106,7 +108,13 @@ public abstract class DrawManager<N extends AbstractInstancer<?>> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static <I extends AbstractInstancer<?>> Map<GroupKey<?>, Int2ObjectMap<List<Pair<I, InstanceHandleImpl<?>>>>> doCrumblingSort(Class<I> clazz, List<Engine.CrumblingBlock> crumblingBlocks) {
|
@FunctionalInterface
|
||||||
|
protected interface State2Instancer<I extends AbstractInstancer<?>> {
|
||||||
|
// I tried using a plain Function<State<?>, I> here, but it exploded with type errors.
|
||||||
|
@Nullable I apply(InstanceHandleImpl.State<?> state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static <I extends AbstractInstancer<?>> Map<GroupKey<?>, Int2ObjectMap<List<Pair<I, InstanceHandleImpl<?>>>>> doCrumblingSort(List<Engine.CrumblingBlock> crumblingBlocks, State2Instancer<I> cast) {
|
||||||
Map<GroupKey<?>, Int2ObjectMap<List<Pair<I, InstanceHandleImpl<?>>>>> byType = new HashMap<>();
|
Map<GroupKey<?>, Int2ObjectMap<List<Pair<I, InstanceHandleImpl<?>>>>> byType = new HashMap<>();
|
||||||
for (Engine.CrumblingBlock block : crumblingBlocks) {
|
for (Engine.CrumblingBlock block : crumblingBlocks) {
|
||||||
int progress = block.progress();
|
int progress = block.progress();
|
||||||
@ -123,16 +131,12 @@ public abstract class DrawManager<N extends AbstractInstancer<?>> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceHandleImpl.State<?> abstractInstancer = impl.state;
|
var instancer = cast.apply(impl.state);
|
||||||
// AbstractInstancer directly implement HandleState, so this check is valid.
|
|
||||||
if (!clazz.isInstance(abstractInstancer)) {
|
if (instancer == null) {
|
||||||
// This rejects instances that were created by a different engine,
|
|
||||||
// and also instances that are hidden or deleted.
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var instancer = clazz.cast(abstractInstancer);
|
|
||||||
|
|
||||||
byType.computeIfAbsent(new GroupKey<>(instancer.type, instancer.environment), $ -> new Int2ObjectArrayMap<>())
|
byType.computeIfAbsent(new GroupKey<>(instancer.type, instancer.environment), $ -> new Int2ObjectArrayMap<>())
|
||||||
.computeIfAbsent(progress, $ -> new ArrayList<>())
|
.computeIfAbsent(progress, $ -> new ArrayList<>())
|
||||||
.add(Pair.of(instancer, impl));
|
.add(Pair.of(instancer, impl));
|
||||||
|
@ -189,7 +189,7 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void renderCrumbling(List<Engine.CrumblingBlock> crumblingBlocks) {
|
public void renderCrumbling(List<Engine.CrumblingBlock> crumblingBlocks) {
|
||||||
var byType = doCrumblingSort(IndirectInstancer.class, crumblingBlocks);
|
var byType = doCrumblingSort(crumblingBlocks, IndirectInstancer::fromState);
|
||||||
|
|
||||||
if (byType.isEmpty()) {
|
if (byType.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -74,6 +74,14 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
|||||||
return new InstanceHandleImpl[ObjectStorage.PAGE_SIZE];
|
return new InstanceHandleImpl[ObjectStorage.PAGE_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static IndirectInstancer<?> fromState(InstanceHandleImpl.State<?> handle) {
|
||||||
|
if (handle instanceof InstancePage<?> instancer) {
|
||||||
|
return instancer.parent;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static final class InstancePage<I extends Instance> implements InstanceHandleImpl.State<I> {
|
private static final class InstancePage<I extends Instance> implements InstanceHandleImpl.State<I> {
|
||||||
private final IndirectInstancer<I> parent;
|
private final IndirectInstancer<I> parent;
|
||||||
private final int pageNo;
|
private final int pageNo;
|
||||||
|
@ -147,7 +147,15 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
|
|||||||
@Override
|
@Override
|
||||||
public void renderCrumbling(List<Engine.CrumblingBlock> crumblingBlocks) {
|
public void renderCrumbling(List<Engine.CrumblingBlock> crumblingBlocks) {
|
||||||
// Sort draw calls into buckets, so we don't have to do as many shader binds.
|
// Sort draw calls into buckets, so we don't have to do as many shader binds.
|
||||||
var byType = doCrumblingSort(InstancedInstancer.class, crumblingBlocks);
|
var byType = doCrumblingSort(crumblingBlocks, handle -> {
|
||||||
|
// AbstractInstancer directly implement HandleState, so this check is valid.
|
||||||
|
if (handle instanceof InstancedInstancer<?> instancer) {
|
||||||
|
return instancer;
|
||||||
|
}
|
||||||
|
// This rejects instances that were created by a different engine,
|
||||||
|
// and also instances that are hidden or deleted.
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
if (byType.isEmpty()) {
|
if (byType.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user