Files
MinecraftForge/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java
T
RainWarrior 6eba0ebb93 Added model loader registry
Entry point: ModelLoaderRegistry
loader interface: ICustomModelLoader
custom model: IModel

ModelLoader is responsible for splicing into vanilla model system.
(you probably don't need to use it directly)

Interop with vanilla models isn't great yet
(vanilla models can't refer to custom ones as parents), will improve in
the future.

Includes loader for B3D models, with animation support
(net.minecraftforge.client.model.b3d).
Blender export plugin with compatible coordinate system:
https://github.com/RainWarrior/B3DExport

OBJ loader is being written, will be included at some point in the
future. For now you can convert OBJ to B3D via blender, or wait.
2015-01-29 11:33:52 +03:00

221 lines
8.6 KiB
Java

package net.minecraftforge.debug;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.client.resources.model.ModelRotation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.client.model.Attributes;
import net.minecraftforge.client.model.ICustomModelLoader;
import net.minecraftforge.client.model.IFlexibleBakedModel;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.IModelState;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.b3d.B3DLoader;
import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.registry.GameRegistry;
import com.google.common.base.Function;
import com.google.common.primitives.Ints;
@Mod(modid = ModelLoaderRegistryDebug.MODID, version = ModelLoaderRegistryDebug.VERSION)
public class ModelLoaderRegistryDebug
{
public static final String MODID = "ForgeDebugModelLoaderRegistry";
public static final String VERSION = "1.0";
@EventHandler
public void preInit(FMLPreInitializationEvent event)
{
//ModelLoaderRegistry.registerLoader(DummyModelLoader.instance);
B3DLoader.instance.addDomain(MODID.toLowerCase());
GameRegistry.registerBlock(CustomModelBlock.instance, CustomModelBlock.name);
//ModelBakery.addVariantName(Item.getItemFromBlock(CustomModelBlock.instance), "forgedebug:dummymodel");
ModelBakery.addVariantName(Item.getItemFromBlock(CustomModelBlock.instance), MODID.toLowerCase() + ":untitled2.b3d");
}
@EventHandler
public void init(FMLInitializationEvent event)
{
Item item = Item.getItemFromBlock(CustomModelBlock.instance);
//Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation("forgedebug:dummymodel", "inventory"));
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation(MODID.toLowerCase() + ":untitled2.b3d", "inventory"));
}
public static class CustomModelBlock extends Block
{
public static final CustomModelBlock instance = new CustomModelBlock();
public static final String name = "CustomModelBlock";
private int counter = 1;
private ExtendedBlockState state = new ExtendedBlockState(this, new IProperty[0], new IUnlistedProperty[]{ B3DLoader.B3DFrameProperty.instance });
private CustomModelBlock()
{
super(Material.iron);
setCreativeTab(CreativeTabs.tabBlock);
setUnlocalizedName(MODID + ":" + name);
}
@Override
public boolean isOpaqueCube() { return false; }
@Override
public boolean isFullCube() { return false; }
@Override
public boolean isVisuallyOpaque() { return false; }
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos)
{
IModel model = ModelLoaderRegistry.getModel(new ResourceLocation(MODID.toLowerCase(),"block/untitled2.b3d"));
B3DLoader.B3DState defaultState = ((B3DLoader.Wrapper)model).getDefaultState();
B3DLoader.B3DState newState = new B3DLoader.B3DState(defaultState.getAnimation(), counter);
return ((IExtendedBlockState)this.state.getBaseState()).withProperty(B3DLoader.B3DFrameProperty.instance, newState);
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ)
{
if(world.isRemote)
{
System.out.println("click " + counter);
if(player.isSneaking()) counter--;
else counter++;
//if(counter >= model.getNode().getKeys().size()) counter = 0;
world.markBlockRangeForRenderUpdate(pos, pos);
}
return false;
}
}
public static class DummyModelLoader implements ICustomModelLoader
{
public static final DummyModelLoader instance = new DummyModelLoader();
public static final ResourceLocation dummyTexture = new ResourceLocation("minecraft:blocks/dirt");
public boolean accepts(ResourceLocation modelLocation)
{
return modelLocation.getResourceDomain().equals("forgedebug") && modelLocation.getResourcePath().contains("dummymodel");
}
public IModel loadModel(ResourceLocation model)
{
return DummyModel.instance;
}
public static enum DummyModel implements IModel
{
instance;
public Collection<ResourceLocation> getDependencies()
{
return Collections.emptyList();
}
public Collection<ResourceLocation> getTextures()
{
return Collections.singletonList(dummyTexture);
}
public IFlexibleBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> textures)
{
return new DummyBakedModel(textures.apply(dummyTexture));
}
public IModelState getDefaultState()
{
return ModelRotation.X0_Y0;
}
}
public static class DummyBakedModel implements IFlexibleBakedModel
{
private final TextureAtlasSprite texture;
public DummyBakedModel(TextureAtlasSprite texture)
{
this.texture = texture;
}
public List<BakedQuad> getFaceQuads(EnumFacing side)
{
return Collections.emptyList();
}
private int[] vertexToInts(float x, float y, float z, int color, float u, float v)
{
return new int[] {
Float.floatToRawIntBits(x),
Float.floatToRawIntBits(y),
Float.floatToRawIntBits(z),
color,
Float.floatToRawIntBits(texture.getInterpolatedU(u)),
Float.floatToRawIntBits(texture.getInterpolatedV(v)),
0
};
}
public List<BakedQuad> getGeneralQuads()
{
List<BakedQuad> ret = new ArrayList<BakedQuad>();
// 1 half-way rotated quad looking UP
ret.add(new BakedQuad(Ints.concat(
vertexToInts(0, .5f, .5f, -1, 0, 0),
vertexToInts(.5f, .5f, 1, -1, 0, 16),
vertexToInts(1, .5f, .5f, -1, 16, 16),
vertexToInts(.5f, .5f, 0, -1, 16, 0)
), -1, EnumFacing.UP));
return ret;
}
public boolean isGui3d() { return true; }
public boolean isAmbientOcclusion() { return true; }
public boolean isBuiltInRenderer() { return false; }
public TextureAtlasSprite getTexture() { return this.texture; }
public ItemCameraTransforms getItemCameraTransforms()
{
return ItemCameraTransforms.DEFAULT;
}
public VertexFormat getFormat()
{
return Attributes.DEFAULT_BAKED_FORMAT;
}
}
public void onResourceManagerReload(IResourceManager resourceManager) {}
}
}