Jump to content

Recommended Posts

Posted (edited)

Hi everyone,

I want to create block that can hold different kind of items, and to render these items on it (similar to toolrack).

I've seen multiple ways of doing this in the survival mod and I'm still a bit lost. Please correct me if any of the info I'm providing is wrong.

The Forge has it's own content renderer and uses already existing shapes (ForgeContentsRenderer -> RegenMesh).
The Toolrack implements the ITexPositionSource for locating texture atlas position for tools (with some dictionary magic for getting ToolTextureSubIds ), but it seems limited to only tools.
The GroundStorage seems closest to what I need, it uses also it's own renderer, but is also most complex one. Going through where do we get meshes I finally land in getOrCreateMesh within BEContainerDisplay.

There is this code pattern I keep seeing in different places:

IContainedMeshSource meshSource = stack.Collectible?.GetCollectibleInterface<IContainedMeshSource>();
if (meshSource != null)
{
  toolMeshes[i] = meshSource.GenMesh(stack, capi.BlockTextureAtlas, Pos);
}
else
{
  if (stack.Class == EnumItemClass.Item)
  {
    capi.Tesselator.TesselateItem(stack.Item, out toolMeshes[i], this);
  }
  else
  {
    capi.Tesselator.TesselateBlock(stack.Block, out toolMeshes[i]);
  }
}

Just to compare with what's in BEContainerDisplay:
 


IContainedMeshSource meshSource = stack.Collectible?.GetCollectibleInterface<IContainedMeshSource>();
if (meshSource != null)
{
  mesh = meshSource.GenMesh(stack, capi.BlockTextureAtlas, Pos);
}
if (mesh == null)
{
  ICoreClientAPI capi = Api as ICoreClientAPI;
  if (stack.Class == EnumItemClass.Block)
  {
    mesh = capi.TesselatorManager.GetDefaultBlockMesh(stack.Block).Clone();
  }
  else
  {
    nowTesselatingObj = stack.Collectible;
    nowTesselatingShape = null;
    if (stack.Item.Shape?.Base != null)
    {
      nowTesselatingShape = capi.TesselatorManager.GetCachedShape(stack.Item.Shape.Base);
    }
    capi.Tesselator.TesselateItem(stack.Item, out mesh, this);
    mesh.RenderPassesAndExtraBits.Fill((short)EnumChunkRenderPass.BlendNoCull);
    }
  }

Basically I see that it follows pattern of:
Take "contained mesh source" if possible first. If that fails, in no particular order handle Blocks/Items meshes.

- What is the use case of handling these "contained mesh sources" first? What types of items/blocks have this and when I can rely on it?

- Should block that stores & displays contained items inherit the BEContainerDisplays and play around with rotation/scale and col/sel boxes? Why the toolrack/forge are not using this? 

Cheers

EDIT:
Writing the question was an excellent rubber duck. I achieved what I wanted by inheriting my BE from BlockEntityDisplay and setting up offsets for inventory elements within the genTransformationMatrices override. If someone is familiar with the topic, I'd still love to know the answers to the questions above - and if this solution actually sounds ok (maybe it's highly bad for performance or multiplayer? No idea as for now.) 

Edited by Orjanek
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.