-
-
Notifications
You must be signed in to change notification settings - Fork 61
Configuration Files
This xml file defines all of the blocks that jmc2obj can export and what models they will use.
By default jmc2obj ships with the one blocks.conf
file but it will search for and load any blocks-*.conf
files in the conf directory. This allows you to create a separate conf file per mod to define just the blocks in that mod for example.
Each block is defined within a <block>
element which has an id
and name
attribue along with a number of sub elements. id
is the minecraft block id that this definition will apply to and name
is the human readable name of the block.
For example the stone definition starts with <block id="minecraft:stone" name="Stone">
The elements that can be defined in the <block>
element can depend on the model that is used, the ones that are always valid are:
-
<model>
- This is the name of the java class that will handle exporting this model, if absent, it defaults toRegistry
which will load the model from the chosen resource packs. The full list of models can be found here, most are no longer used in the default blocks.conf since transitioning to using resource pack models. -
<occlusion>
- This defines how the block is seen by other blocks in terms of how solid it is, used in determining if other blocks should export faces on sides facing this block. Also determines if the map view will show the block.- full - adj. faces are never drawn (default)
- none - adj. faces are always drawn
- transparent - adj. faces are not drawn if they have the same block id
- bottom - the top face of the block below is not drawn
- custom - use special occlusion rules in model
- volume - occlusion for a transparent volume; similar to transparent, but also adds faces on boundaries with other block types
-
<materials>
- A comma separated list of textures for the model to use to use. For most models the textures given are used for certain sides of a block with the following patters:all_sides
ortop_and_bottom, sides
ortop, sides, bottom
ortop, front, back, left, right, bottom
(top, north, south, west, east, bottom
) -
<waterlogged>
-true
orfalse
, defaultfalse
. Some blocks are 'waterlogged' in game but do not save this in their blockstate, set waterlogged to true to make the block act waterlogged when this tag is missing. -
<ore>
- Specifies a block ID that this block will be changed into if the convert ores option is enabled.
The Mesh
model is one of the most customisable models, it allows loading in a custom obj file to use as the model but there are many options that you can apply to modify which obj is chosen and how it is transformed. This is achieved by nesting various <mesh>
elements in the block definition.
The simplest case is just a single obj file: <mesh>models/bell.obj</mesh>
which will just place the first object in the obj model where the block is.
If the obj file conains multiple separate objects, you should specify a which object to use by giving the name after a #. For example, the chest.obj has 3 objects in it: chest, chest_left and chest_right. The right half of the chest can be used with <mesh>models/chest.obj#chest_right</mesh>
<mesh>
elements can be added inside other <mesh>
elements to create a tree structure of elements that will be added. A simple tree that will add both the base(pot) and the cactus objects from flowerpot.obj would look like this:
<mesh>
<mesh>models/flowerpot.obj#base</mesh>
<mesh>models/flowerpot.obj#cactus</mesh>
</mesh>
There are several special attributes you can put onto a mesh element to change how it will act.
-
jmc_material
- When this is set to a texture, all models within this element will have their textures overriden with this. -
jmc_optimize
- If set totrue
, allows the models within this element to be optimized. -
jmc_random
- Iftrue
randomly picks from sub elements rather than using them all. More details
There are 3 other types of element you can have inside a mesh tree: <translate>
, <rotate>
& <scale>
. These can apply a transformation to any models that are inside them, further down the tree. The attribues that control these are the same for all:
-
const
- The axis to constrain the transform to,x
y
orz
. -
value
- Which value to use for the transform.
This example will export the chest model but rotated 90 degrees about the Y axis:
<mesh>
<rotate const="y" value="90">
<mesh>models/chest.obj#chest</mesh>
</rotate>
</mesh>
These simple parts becomes powerful when used with the fact that mesh elements in the tree can be filtered by the different states of a block. In a mesh element, you can add any number of arbritrary state values as an attribute. These will then be used to only apply that mesh element, and any elements within it, only if the current block matches the specified state.
For example, the ender_chest
block has a state called facing
that can be one of the four cardinal directions. We can use this with a rotation element to take a single chest model and rotate it depending on what facing
value each block has:
<mesh>
<mesh facing="north">
<rotate const="y" value="180">
<mesh>models/chest.obj#chest</mesh>
</rotate>
</mesh>
<mesh facing="east">
<rotate const="y" value="270">
<mesh>models/chest.obj#chest</mesh>
</rotate>
</mesh>
<mesh facing="south">
<rotate const="y" value="0">
<mesh>models/chest.obj#chest</mesh>
</rotate>
</mesh>
<mesh facing="west">
<rotate const="y" value="90">
<mesh>models/chest.obj#chest</mesh>
</rotate>
</mesh>
</mesh>
Another example with the end_portal_frame
, which has both facing
and eye
states. The models are rotated depending on the facing state and then the base object is always added but the eye object is only added when eye
is true
:
<mesh>
<mesh facing="north">
<rotate const="y" value="0">
<mesh>models/endportal_frame.obj#base</mesh>
<mesh eye="true">models/endportal_frame.obj#eye</mesh>
</rotate>
</mesh>
<mesh facing="south">
<rotate const="y" value="180">
<mesh>models/endportal_frame.obj#base</mesh>
<mesh eye="true">models/endportal_frame.obj#eye</mesh>
</rotate>
</mesh>
<mesh facing="west">
<rotate const="y" value="90">
<mesh>models/endportal_frame.obj#base</mesh>
<mesh eye="true">models/endportal_frame.obj#eye</mesh>
</rotate>
</mesh>
<mesh facing="east">
<rotate const="y" value="-90">
<mesh>models/endportal_frame.obj#base</mesh>
<mesh eye="true">models/endportal_frame.obj#eye</mesh>
</rotate>
</mesh>
</mesh>
If a mesh element has the jmc_random
attribute set to true
, rather than applying every mesh element within, it will randomly pick one of them instead. The elements within may also have a jmc_weight
attribute set on them which will be used to determine how likely that element will be picked. By default all elements have a weight of 1 and so are equally likely.
For example, this will randomly pick different chest model rotations with a preference for no rotation:
<mesh jmc_random="true">
<mesh>
<rotate const="y" value="180">
<mesh>models/chest.obj#chest</mesh>
</rotate>
</mesh>
<mesh>
<rotate const="y" value="270">
<mesh>models/chest.obj#chest</mesh>
</rotate>
</mesh>
<mesh jmc_weight="2">
<rotate const="y" value="0">
<mesh>models/chest.obj#chest</mesh>
</rotate>
</mesh>
<mesh>
<rotate const="y" value="90">
<mesh>models/chest.obj#chest</mesh>
</rotate>
</mesh>
</mesh>
TBD
TBD