com.parzivail.util.client.model.DynamicBakedModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pswg Show documentation
Show all versions of pswg Show documentation
Explore the galaxy with Galaxies: Parzi's Star Wars Mod!
/*******************************************************************************
* Copyright 2019 grondag
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.parzivail.util.client.model;
import ;
import com.google.common.collect.ImmutableList;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.class_1058;
import net.minecraft.class_1087;
import net.minecraft.class_1309;
import net.minecraft.class_1799;
import net.minecraft.class_1920;
import net.minecraft.class_1922;
import net.minecraft.class_2338;
import net.minecraft.class_2350;
import net.minecraft.class_2680;
import net.minecraft.class_5819;
import net.minecraft.class_638;
import net.minecraft.class_777;
import net.minecraft.class_806;
import net.minecraft.class_809;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
/**
* Simple baked model supporting the Fabric Render API features.
*/
public abstract class DynamicBakedModel extends AbstractModel
{
public enum CacheMethod
{
SINGLETON,
BLOCKSTATE_KEY,
RENDER_SEED_KEY,
NO_CACHING
}
// These are dirty hacks to at least have some semblance of "working" models when
// a rendering mod replaces Indigo without implementing FRAPI. I hate them, and
// they only work because AbstractBlockState::getModelOffset is called before each
// block is rendered.
// TODO: figure out a better way to do this
private static final ThreadLocal lastQueriedWorld = new ThreadLocal<>();
private static final ThreadLocal lastQueriedPos = new ThreadLocal<>();
protected final ItemProxy itemProxy = new ItemProxy();
protected final HashMap meshes = new HashMap<>();
protected WeakReference[]> quadLists = null;
public DynamicBakedModel(class_1058 sprite, class_809 transformation)
{
super(sprite, transformation);
}
public static void cacheBlockPosQuery(class_1922 world, class_2338 pos)
{
lastQueriedWorld.set(world);
lastQueriedPos.set(pos);
}
@Override
public boolean isVanillaAdapter()
{
return false;
}
protected CacheMethod getDiscriminator()
{
return CacheMethod.SINGLETON;
}
protected abstract Mesh createBlockMesh(class_1920 blockView, class_2680 state, class_2338 pos, Supplier randomSupplier, RenderContext context, Matrix4f transformation);
protected abstract Mesh createItemMesh(class_1799 stack, Supplier randomSupplier, RenderContext context, Matrix4f transformation);
protected Mesh createOrCacheBlockMesh(class_1920 blockView, class_2680 state, class_2338 pos, Supplier randomSupplier, RenderContext context, Matrix4f transformation)
{
var cacheDiscriminator = switch (getDiscriminator())
{
case SINGLETON -> class_2338.field_10980;
case BLOCKSTATE_KEY -> state;
case RENDER_SEED_KEY -> state == null ? 0 : state.method_26190(pos);
default -> null;
};
if (cacheDiscriminator == null)
return createBlockMesh(blockView, state, pos, randomSupplier, context, transformation);
var cacheId = new ModelCacheId(cacheDiscriminator, transformation);
if (meshes.containsKey(cacheId))
return meshes.get(cacheId);
var m = createBlockMesh(blockView, state, pos, randomSupplier, context, transformation);
meshes.put(cacheId, m);
return m;
}
protected Mesh createOrCacheItemMesh(class_1799 stack, Supplier randomSupplier, RenderContext context, Matrix4f transformation)
{
var cacheId = new ModelCacheId(null, transformation);
if (meshes.containsKey(cacheId))
return meshes.get(cacheId);
var m = createItemMesh(stack, randomSupplier, context, transformation);
meshes.put(cacheId, m);
return m;
}
protected abstract Matrix4f createTransformation(class_2680 state);
@Override
public List method_4707(class_2680 state, class_2350 face, class_5819 rand)
{
var lists = quadLists == null ? null : quadLists.get();
if (lists == null)
{
var world = lastQueriedWorld.get() instanceof class_1920 brv ? brv : null;
var pos = lastQueriedPos.get();
if (pos == null)
pos = class_2338.field_10980;
lists = ModelHelper.toQuadLists(createOrCacheBlockMesh(world, state, pos, () -> rand, null, createTransformation(state)));
quadLists = new WeakReference<>(lists);
}
final var result = lists[face == null ? 6 : face.method_10146()];
return result == null ? ImmutableList.of() : result;
}
@Override
public void emitBlockQuads(class_1920 blockView, class_2680 state, class_2338 pos, Supplier randomSupplier, RenderContext context)
{
context.meshConsumer().accept(createOrCacheBlockMesh(blockView, state, pos, randomSupplier, context, createTransformation(state)));
}
@Override
public class_806 method_4710()
{
return itemProxy;
}
@Override
public void emitItemQuads(class_1799 stack, Supplier randomSupplier, RenderContext context)
{
context.meshConsumer().accept(createOrCacheItemMesh(stack, randomSupplier, context, createTransformation(null)));
}
protected class ItemProxy extends class_806
{
public ItemProxy()
{
super(null, null, Collections.emptyList());
}
@Override
public class_1087 method_3495(class_1087 model, class_1799 stack, @Nullable class_638 world, @Nullable class_1309 entity, int seed)
{
return DynamicBakedModel.this;
}
}
private record ModelCacheId(Object discriminator, Matrix4f transformation)
{
@Override
public int hashCode()
{
if (discriminator == null)
return transformation.hashCode() * 31;
return discriminator.hashCode();
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof ModelCacheId cacheId))
return false;
if (this.discriminator == null && cacheId.discriminator == null)
return Objects.equals(transformation, cacheId.transformation);
return Objects.equals(discriminator, cacheId.discriminator);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy