2016-06-23 03:49:47 +00:00
/ *
* Minecraft Forge
2020-07-02 17:49:11 +00:00
* Copyright ( c ) 2016 - 2020 .
2016-06-23 03:49:47 +00:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2 . 1
* of the License .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
* /
2014-12-28 04:10:54 +00:00
package net.minecraftforge.client.model ;
2018-09-08 20:34:59 +00:00
import com.google.common.collect.ImmutableMap ;
2019-12-11 02:27:07 +00:00
import com.google.common.collect.Lists ;
2018-09-08 20:34:59 +00:00
import com.google.common.collect.Maps ;
import com.google.common.collect.Sets ;
2019-12-11 02:27:07 +00:00
import com.google.gson.* ;
import com.mojang.datafixers.util.Pair ;
2014-12-28 04:10:54 +00:00
import net.minecraft.client.Minecraft ;
2019-12-11 02:27:07 +00:00
import net.minecraft.client.renderer.model.* ;
import net.minecraft.client.renderer.texture.AtlasTexture ;
import net.minecraft.client.renderer.texture.MissingTextureSprite ;
import net.minecraft.client.renderer.texture.TextureAtlasSprite ;
2018-09-08 20:34:59 +00:00
import net.minecraft.resources.IReloadableResourceManager ;
import net.minecraft.resources.IResourceManager ;
2019-12-11 02:27:07 +00:00
import net.minecraft.util.Direction ;
import net.minecraft.util.JSONUtils ;
2014-12-28 04:10:54 +00:00
import net.minecraft.util.ResourceLocation ;
2020-06-19 14:58:45 +00:00
import net.minecraft.util.math.vector.TransformationMatrix ;
2020-08-08 00:59:00 +00:00
import net.minecraftforge.client.event.ModelRegistryEvent ;
2019-12-11 02:27:07 +00:00
import net.minecraftforge.client.model.geometry.IModelGeometry ;
import net.minecraftforge.client.model.geometry.ISimpleModelGeometry ;
2015-07-28 21:23:34 +00:00
import net.minecraftforge.client.model.obj.OBJLoader ;
2019-12-11 02:27:07 +00:00
import net.minecraftforge.common.model.TransformationHelper ;
import javax.annotation.Nullable ;
import java.lang.reflect.Type ;
import java.util.* ;
import java.util.function.Function ;
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
2020-01-23 21:41:32 +00:00
import java.util.stream.Collectors ;
2016-03-13 13:16:25 +00:00
2019-08-29 04:33:49 +00:00
/ * *
2014-12-28 04:10:54 +00:00
* Central hub for custom model loaders .
* /
public class ModelLoaderRegistry
{
2020-01-23 21:41:32 +00:00
public static final String WHITE_TEXTURE = " forge:white " ;
2020-06-27 22:32:50 +00:00
private static final ItemModelGenerator ITEM_MODEL_GENERATOR = new ItemModelGenerator ( ) ;
2019-12-11 02:27:07 +00:00
private static final Map < ResourceLocation , IModelLoader < ? > > loaders = Maps . newHashMap ( ) ;
2020-01-23 21:41:32 +00:00
private static volatile boolean registryFrozen = false ;
2014-12-28 04:10:54 +00:00
2015-06-18 11:14:46 +00:00
// Forge built-in loaders
2019-07-21 01:04:00 +00:00
public static void init ( )
2015-06-18 11:14:46 +00:00
{
2020-01-23 21:41:32 +00:00
registerLoader ( new ResourceLocation ( " minecraft " , " elements " ) , VanillaProxy . Loader . INSTANCE ) ;
registerLoader ( new ResourceLocation ( " forge " , " obj " ) , OBJLoader . INSTANCE ) ;
registerLoader ( new ResourceLocation ( " forge " , " bucket " ) , DynamicBucketModel . Loader . INSTANCE ) ;
registerLoader ( new ResourceLocation ( " forge " , " composite " ) , CompositeModel . Loader . INSTANCE ) ;
registerLoader ( new ResourceLocation ( " forge " , " multi-layer " ) , MultiLayerModel . Loader . INSTANCE ) ;
2020-06-04 14:03:45 +00:00
registerLoader ( new ResourceLocation ( " forge " , " item-layers " ) , ItemLayerModel . Loader . INSTANCE ) ;
2020-06-27 22:32:50 +00:00
registerLoader ( new ResourceLocation ( " forge " , " separate-perspective " ) , SeparatePerspectiveModel . Loader . INSTANCE ) ;
2019-12-11 02:27:07 +00:00
// TODO: Implement as new model loaders
//registerLoader(new ResourceLocation("forge:b3d"), new ModelLoaderAdapter(B3DLoader.INSTANCE));
//registerLoader(new ResourceLocation("forge:fluid"), new ModelLoaderAdapter(ModelFluid.FluidLoader.INSTANCE));
2015-06-18 11:14:46 +00:00
}
2020-08-08 00:59:00 +00:00
/ * *
* INTERNAL METHOD , DO NOT CALL
* /
public static void onModelLoadingStart ( )
2020-01-23 21:41:32 +00:00
{
2020-08-09 20:04:44 +00:00
// Minecraft recreates the ModelBakery on resource reload, but this should only run once during init.
if ( ! registryFrozen )
{
net . minecraftforge . fml . ModLoader . get ( ) . postEvent ( new net . minecraftforge . client . event . ModelRegistryEvent ( ) ) ;
registryFrozen = true ;
}
2020-01-23 21:41:32 +00:00
}
2019-08-29 04:33:49 +00:00
/ * *
2014-12-28 04:10:54 +00:00
* Makes system aware of your loader .
2020-08-08 00:59:00 +00:00
* < b > Must be called from within { @link ModelRegistryEvent } < / b >
2014-12-28 04:10:54 +00:00
* /
2019-12-11 02:27:07 +00:00
public static void registerLoader ( ResourceLocation id , IModelLoader < ? > loader )
2014-12-28 04:10:54 +00:00
{
2020-01-23 21:41:32 +00:00
if ( registryFrozen )
2020-08-08 00:59:00 +00:00
throw new IllegalStateException ( " Can not register model loaders after models have started loading. Please use ModelRegistryEvent to register your loaders. " ) ;
2020-01-23 21:41:32 +00:00
synchronized ( loaders )
{
loaders . put ( id , loader ) ;
( ( IReloadableResourceManager ) Minecraft . getInstance ( ) . getResourceManager ( ) ) . addReloadListener ( loader ) ;
}
2014-12-28 04:10:54 +00:00
}
2019-12-11 02:27:07 +00:00
public static IModelGeometry < ? > getModel ( ResourceLocation loaderId , JsonDeserializationContext deserializationContext , JsonObject data )
2014-12-28 04:10:54 +00:00
{
2019-12-11 02:27:07 +00:00
try
{
if ( ! loaders . containsKey ( loaderId ) )
2020-01-23 21:41:32 +00:00
{
throw new IllegalStateException ( String . format ( " Model loader '%s' not found. Registered loaders: %s " , loaderId ,
loaders . keySet ( ) . stream ( ) . map ( ResourceLocation : : toString ) . collect ( Collectors . joining ( " , " ) ) ) ) ;
}
2019-12-11 02:27:07 +00:00
IModelLoader < ? > loader = loaders . get ( loaderId ) ;
return loader . read ( deserializationContext , data ) ;
}
catch ( Exception e )
{
e . printStackTrace ( ) ;
throw e ;
}
2014-12-28 04:10:54 +00:00
}
2019-12-11 02:27:07 +00:00
@Nullable
public static IModelGeometry < ? > deserializeGeometry ( JsonDeserializationContext deserializationContext , JsonObject object ) {
if ( ! object . has ( " loader " ) ) {
return null ;
}
2014-12-28 04:10:54 +00:00
2019-12-11 02:27:07 +00:00
ResourceLocation loader = new ResourceLocation ( JSONUtils . getString ( object , " loader " ) ) ;
return getModel ( loader , deserializationContext , object ) ;
2014-12-28 04:10:54 +00:00
}
2020-01-23 21:41:32 +00:00
/ * Explanation :
* This takes anything that looks like a valid resourcepack texture location , and tries to extract a resourcelocation out of it .
* 1 . it will ignore anything up to and including an / assets / folder ,
* 2 . it will take the next path component as a namespace ,
* 3 . it will match but skip the / textures / part of the path ,
* 4 . it will take the rest of the path up to but excluding the . png extension as the resource path
* It ' s a best - effort situation , to allow model files exported by modelling software to be used without post - processing .
* Example :
* C : \ Something \ Or Other \ src \ main \ resources \ assets \ mymodid \ textures \ item \ my_thing . png
* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - - - - - - - _______ - - - - - - - - - - _____________ - - - -
* < namespace > < path >
* Result after replacing ' \ ' to '/' : mymodid : item / my_thing
* /
private static final Pattern FILESYSTEM_PATH_TO_RESLOC =
Pattern . compile ( " (?:.*[ \\ \\ /]assets[ \\ \\ /](?<namespace>[a-z_-]+)[ \\ \\ /]textures[ \\ \\ /])?(?<path>[a-z_ \\ \\ /-]+) \\ .png " ) ;
2018-08-16 20:21:21 +00:00
2020-06-19 14:58:45 +00:00
public static RenderMaterial resolveTexture ( @Nullable String tex , IModelConfiguration owner )
2019-12-11 02:27:07 +00:00
{
if ( tex = = null )
2020-01-23 21:41:32 +00:00
return blockMaterial ( WHITE_TEXTURE ) ;
2019-12-11 02:27:07 +00:00
if ( tex . startsWith ( " # " ) )
return owner . resolveTexture ( tex ) ;
2018-08-16 20:21:21 +00:00
2019-12-11 02:27:07 +00:00
// Attempt to convert a common (windows/linux/mac) filesystem path to a ResourceLocation.
// This makes no promises, if it doesn't work, too bad, fix your mtl file.
Matcher match = FILESYSTEM_PATH_TO_RESLOC . matcher ( tex ) ;
if ( match . matches ( ) )
2014-12-28 04:10:54 +00:00
{
2019-12-11 02:27:07 +00:00
String namespace = match . group ( " namespace " ) ;
String path = match . group ( " path " ) . replace ( " \\ " , " / " ) ;
if ( namespace ! = null )
return blockMaterial ( new ResourceLocation ( namespace , path ) ) ;
return blockMaterial ( path ) ;
2014-12-28 04:10:54 +00:00
}
2016-01-06 19:00:43 +00:00
2019-12-11 02:27:07 +00:00
return blockMaterial ( tex ) ;
}
2016-01-06 19:00:43 +00:00
2020-09-10 19:01:34 +00:00
@SuppressWarnings ( " deprecation " )
2020-06-19 14:58:45 +00:00
public static RenderMaterial blockMaterial ( String location )
2019-12-11 02:27:07 +00:00
{
2020-06-19 14:58:45 +00:00
return new RenderMaterial ( AtlasTexture . LOCATION_BLOCKS_TEXTURE , new ResourceLocation ( location ) ) ;
2019-12-11 02:27:07 +00:00
}
2020-09-10 19:01:34 +00:00
@SuppressWarnings ( " deprecation " )
2020-06-19 14:58:45 +00:00
public static RenderMaterial blockMaterial ( ResourceLocation location )
2019-12-11 02:27:07 +00:00
{
2020-06-19 14:58:45 +00:00
return new RenderMaterial ( AtlasTexture . LOCATION_BLOCKS_TEXTURE , location ) ;
2019-12-11 02:27:07 +00:00
}
@Nullable
public static IModelTransform deserializeModelTransforms ( JsonDeserializationContext deserializationContext , JsonObject modelData )
{
if ( ! modelData . has ( " transform " ) )
return null ;
return deserializeTransform ( deserializationContext , modelData . get ( " transform " ) ) . orElse ( null ) ;
}
public static Optional < IModelTransform > deserializeTransform ( JsonDeserializationContext context , JsonElement transformData )
{
if ( ! transformData . isJsonObject ( ) )
{
2016-03-15 22:42:01 +00:00
try
2016-01-06 19:00:43 +00:00
{
2019-12-11 02:27:07 +00:00
TransformationMatrix base = context . deserialize ( transformData , TransformationMatrix . class ) ;
2019-12-17 18:14:52 +00:00
return Optional . of ( new SimpleModelTransform ( ImmutableMap . of ( ) , base . blockCenterToCorner ( ) ) ) ;
2016-03-13 13:16:25 +00:00
}
2019-12-11 02:27:07 +00:00
catch ( JsonParseException e )
2016-03-15 22:42:01 +00:00
{
2019-12-11 02:27:07 +00:00
throw new JsonParseException ( " transform: expected a string, object or valid base transformation, got: " + transformData ) ;
2016-03-15 22:42:01 +00:00
}
2016-03-13 13:16:25 +00:00
}
2019-12-11 02:27:07 +00:00
else
2016-03-13 13:16:25 +00:00
{
2019-12-11 02:27:07 +00:00
JsonObject transform = transformData . getAsJsonObject ( ) ;
EnumMap < ItemCameraTransforms . TransformType , TransformationMatrix > transforms = Maps . newEnumMap ( ItemCameraTransforms . TransformType . class ) ;
deserializeTRSR ( context , transforms , transform , " thirdperson " , ItemCameraTransforms . TransformType . THIRD_PERSON_RIGHT_HAND ) ;
deserializeTRSR ( context , transforms , transform , " thirdperson_righthand " , ItemCameraTransforms . TransformType . THIRD_PERSON_RIGHT_HAND ) ;
deserializeTRSR ( context , transforms , transform , " thirdperson_lefthand " , ItemCameraTransforms . TransformType . THIRD_PERSON_LEFT_HAND ) ;
deserializeTRSR ( context , transforms , transform , " firstperson " , ItemCameraTransforms . TransformType . FIRST_PERSON_RIGHT_HAND ) ;
deserializeTRSR ( context , transforms , transform , " firstperson_righthand " , ItemCameraTransforms . TransformType . FIRST_PERSON_RIGHT_HAND ) ;
deserializeTRSR ( context , transforms , transform , " firstperson_lefthand " , ItemCameraTransforms . TransformType . FIRST_PERSON_LEFT_HAND ) ;
deserializeTRSR ( context , transforms , transform , " head " , ItemCameraTransforms . TransformType . HEAD ) ;
deserializeTRSR ( context , transforms , transform , " gui " , ItemCameraTransforms . TransformType . GUI ) ;
deserializeTRSR ( context , transforms , transform , " ground " , ItemCameraTransforms . TransformType . GROUND ) ;
deserializeTRSR ( context , transforms , transform , " fixed " , ItemCameraTransforms . TransformType . FIXED ) ;
int k = transform . entrySet ( ) . size ( ) ;
if ( transform . has ( " matrix " ) ) k - - ;
if ( transform . has ( " translation " ) ) k - - ;
if ( transform . has ( " rotation " ) ) k - - ;
if ( transform . has ( " scale " ) ) k - - ;
if ( transform . has ( " post-rotation " ) ) k - - ;
2020-05-15 17:10:23 +00:00
if ( transform . has ( " origin " ) ) k - - ;
2019-12-11 02:27:07 +00:00
if ( k > 0 )
2016-03-13 13:16:25 +00:00
{
2020-05-15 17:10:23 +00:00
throw new JsonParseException ( " transform: allowed keys: 'thirdperson', 'firstperson', 'gui', 'head', 'matrix', 'translation', 'rotation', 'scale', 'post-rotation', 'origin' " ) ;
2016-01-06 19:00:43 +00:00
}
2020-02-26 03:45:14 +00:00
TransformationMatrix base = TransformationMatrix . identity ( ) ;
2019-12-11 02:27:07 +00:00
if ( ! transform . entrySet ( ) . isEmpty ( ) )
{
base = context . deserialize ( transform , TransformationMatrix . class ) ;
}
IModelTransform state = new SimpleModelTransform ( Maps . immutableEnumMap ( transforms ) , base ) ;
return Optional . of ( state ) ;
2014-12-28 04:10:54 +00:00
}
}
2019-12-11 02:27:07 +00:00
private static void deserializeTRSR ( JsonDeserializationContext context , EnumMap < ItemCameraTransforms . TransformType , TransformationMatrix > transforms , JsonObject transform , String name , ItemCameraTransforms . TransformType itemCameraTransform )
2016-03-15 22:42:01 +00:00
{
2019-12-11 02:27:07 +00:00
if ( transform . has ( name ) )
2016-03-15 22:42:01 +00:00
{
2019-12-11 02:27:07 +00:00
TransformationMatrix t = context . deserialize ( transform . remove ( name ) , TransformationMatrix . class ) ;
2019-12-17 18:14:52 +00:00
transforms . put ( itemCameraTransform , t . blockCenterToCorner ( ) ) ;
2016-03-15 22:42:01 +00:00
}
}
2020-06-19 14:58:45 +00:00
public static IBakedModel bakeHelper ( BlockModel blockModel , ModelBakery modelBakery , BlockModel otherModel , Function < RenderMaterial , TextureAtlasSprite > spriteGetter , IModelTransform modelTransform , ResourceLocation modelLocation , boolean guiLight3d )
2016-03-15 22:42:01 +00:00
{
2019-12-11 02:27:07 +00:00
IBakedModel model ;
IModelGeometry < ? > customModel = blockModel . customData . getCustomGeometry ( ) ;
IModelTransform customModelState = blockModel . customData . getCustomModelState ( ) ;
if ( customModelState ! = null )
2020-05-15 17:10:23 +00:00
modelTransform = new ModelTransformComposition ( modelTransform , customModelState , modelTransform . isUvLock ( ) ) ;
2020-01-22 21:11:13 +00:00
2019-12-11 02:27:07 +00:00
if ( customModel ! = null )
2019-12-27 21:30:16 +00:00
model = customModel . bake ( blockModel . customData , modelBakery , spriteGetter , modelTransform , blockModel . getOverrides ( modelBakery , otherModel , spriteGetter ) , modelLocation ) ;
2019-12-11 02:27:07 +00:00
else
2020-06-27 22:32:50 +00:00
{
// handle vanilla item models here, since vanilla has a shortcut for them
if ( blockModel . getRootModel ( ) = = ModelBakery . MODEL_GENERATED ) {
model = ITEM_MODEL_GENERATOR . makeItemModel ( spriteGetter , blockModel ) . bakeModel ( modelBakery , blockModel , spriteGetter , modelTransform , modelLocation , guiLight3d ) ;
}
else
{
model = blockModel . bakeVanilla ( modelBakery , otherModel , spriteGetter , modelTransform , modelLocation , guiLight3d ) ;
}
}
2016-03-15 22:42:01 +00:00
2019-12-11 02:27:07 +00:00
if ( customModelState ! = null & & ! model . doesHandlePerspectives ( ) )
model = new PerspectiveMapWrapper ( model , customModelState ) ;
2014-12-28 04:10:54 +00:00
2017-01-19 09:57:37 +00:00
return model ;
}
2019-12-11 02:27:07 +00:00
public static class VanillaProxy implements ISimpleModelGeometry < VanillaProxy >
2014-12-28 04:10:54 +00:00
{
2019-12-11 02:27:07 +00:00
private final List < BlockPart > elements ;
2016-03-13 13:16:25 +00:00
2019-12-11 02:27:07 +00:00
public VanillaProxy ( List < BlockPart > list )
2016-03-15 22:42:01 +00:00
{
2019-12-11 02:27:07 +00:00
this . elements = list ;
2016-03-15 22:42:01 +00:00
}
2019-12-11 02:27:07 +00:00
@Override
2020-06-19 14:58:45 +00:00
public void addQuads ( IModelConfiguration owner , IModelBuilder < ? > modelBuilder , ModelBakery bakery , Function < RenderMaterial , TextureAtlasSprite > spriteGetter , IModelTransform modelTransform , ResourceLocation modelLocation )
2016-03-15 22:42:01 +00:00
{
2019-12-11 02:27:07 +00:00
for ( BlockPart blockpart : elements ) {
for ( Direction direction : blockpart . mapFaces . keySet ( ) ) {
BlockPartFace blockpartface = blockpart . mapFaces . get ( direction ) ;
TextureAtlasSprite textureatlassprite1 = spriteGetter . apply ( owner . resolveTexture ( blockpartface . texture ) ) ;
if ( blockpartface . cullFace = = null ) {
2019-12-27 21:30:16 +00:00
modelBuilder . addGeneralQuad ( BlockModel . makeBakedQuad ( blockpart , blockpartface , textureatlassprite1 , direction , modelTransform , modelLocation ) ) ;
2019-12-11 02:27:07 +00:00
} else {
modelBuilder . addFaceQuad (
2020-02-26 03:45:14 +00:00
modelTransform . getRotation ( ) . rotateTransform ( blockpartface . cullFace ) ,
2019-12-27 21:30:16 +00:00
BlockModel . makeBakedQuad ( blockpart , blockpartface , textureatlassprite1 , direction , modelTransform , modelLocation ) ) ;
2019-12-11 02:27:07 +00:00
}
}
}
2016-03-15 22:42:01 +00:00
}
2019-12-11 02:27:07 +00:00
@Override
2020-06-19 14:58:45 +00:00
public Collection < RenderMaterial > getTextures ( IModelConfiguration owner , Function < ResourceLocation , IUnbakedModel > modelGetter , Set < Pair < String , String > > missingTextureErrors )
2019-12-11 02:27:07 +00:00
{
2020-06-19 14:58:45 +00:00
Set < RenderMaterial > textures = Sets . newHashSet ( ) ;
2019-12-11 02:27:07 +00:00
for ( BlockPart part : elements ) {
for ( BlockPartFace face : part . mapFaces . values ( ) ) {
2020-06-19 14:58:45 +00:00
RenderMaterial texture = owner . resolveTexture ( face . texture ) ;
2019-12-11 02:27:07 +00:00
if ( Objects . equals ( texture , MissingTextureSprite . getLocation ( ) . toString ( ) ) ) {
missingTextureErrors . add ( Pair . of ( face . texture , owner . getModelName ( ) ) ) ;
}
textures . add ( texture ) ;
}
}
return textures ;
}
public static class Loader implements IModelLoader < VanillaProxy >
{
public static final Loader INSTANCE = new Loader ( ) ;
private Loader ( )
{
}
@Override
public void onResourceManagerReload ( IResourceManager resourceManager )
{
}
@Override
public VanillaProxy read ( JsonDeserializationContext deserializationContext , JsonObject modelContents )
{
List < BlockPart > list = this . getModelElements ( deserializationContext , modelContents ) ;
return new VanillaProxy ( list ) ;
}
private List < BlockPart > getModelElements ( JsonDeserializationContext deserializationContext , JsonObject object ) {
List < BlockPart > list = Lists . newArrayList ( ) ;
if ( object . has ( " elements " ) ) {
for ( JsonElement jsonelement : JSONUtils . getJsonArray ( object , " elements " ) ) {
list . add ( deserializationContext . deserialize ( jsonelement , BlockPart . class ) ) ;
}
}
return list ;
}
}
2016-03-15 22:42:01 +00:00
}
2016-03-21 07:01:30 +00:00
2019-12-11 02:27:07 +00:00
public static class ExpandedBlockModelDeserializer extends BlockModel . Deserializer
2016-03-21 07:01:30 +00:00
{
2019-12-11 02:27:07 +00:00
public static final Gson INSTANCE = ( new GsonBuilder ( ) )
. registerTypeAdapter ( BlockModel . class , new ExpandedBlockModelDeserializer ( ) )
. registerTypeAdapter ( BlockPart . class , new BlockPart . Deserializer ( ) )
. registerTypeAdapter ( BlockPartFace . class , new BlockPartFace . Deserializer ( ) )
. registerTypeAdapter ( BlockFaceUV . class , new BlockFaceUV . Deserializer ( ) )
. registerTypeAdapter ( ItemTransformVec3f . class , new ItemTransformVec3f . Deserializer ( ) )
. registerTypeAdapter ( ItemCameraTransforms . class , new ItemCameraTransforms . Deserializer ( ) )
. registerTypeAdapter ( ItemOverride . class , new ItemOverride . Deserializer ( ) )
. registerTypeAdapter ( TransformationMatrix . class , new TransformationHelper . Deserializer ( ) )
. create ( ) ;
public BlockModel deserialize ( JsonElement element , Type targetType , JsonDeserializationContext deserializationContext ) throws JsonParseException {
BlockModel model = super . deserialize ( element , targetType , deserializationContext ) ;
JsonObject jsonobject = element . getAsJsonObject ( ) ;
IModelGeometry < ? > geometry = deserializeGeometry ( deserializationContext , jsonobject ) ;
List < BlockPart > elements = model . getElements ( ) ;
if ( geometry ! = null ) {
elements . clear ( ) ;
model . customData . setCustomGeometry ( geometry ) ;
}
IModelTransform modelState = deserializeModelTransforms ( deserializationContext , jsonobject ) ;
if ( modelState ! = null )
{
model . customData . setCustomModelState ( modelState ) ;
}
if ( jsonobject . has ( " visibility " ) )
{
JsonObject visibility = JSONUtils . getJsonObject ( jsonobject , " visibility " ) ;
for ( Map . Entry < String , JsonElement > part : visibility . entrySet ( ) )
{
model . customData . visibilityData . setVisibilityState ( part . getKey ( ) , part . getValue ( ) . getAsBoolean ( ) ) ;
}
}
return model ;
}
2016-03-21 07:01:30 +00:00
}
2014-12-28 04:10:54 +00:00
}