Jump to content

Best option for rendering a modular block?


AnZaNaMa

Recommended Posts

Alright, so I have a block with a TileEntity that is basically a frame that will hold different "parts". I'm trying to determine whether I should use a JSON model (or OBJ) or a TESR. In the end, there will be quite a few unique parts that all will need to render differently and one of my blocks will need to be able to hold multiple different parts. I feel like if I tried to do this using JSON models, it would be way too complex. Also, I have experience using OpenGL apart from Minecraft so I'd probably be able use a TESR pretty well. I don't know if they will cause too much lag, though. Are they a lot more expensive than JSON models? I need the player to be able to use quite a few of these before they lag too badly.

 

Sorry if this question seems unclear. I find it difficult to put what I'm thinking into words. Is there some other option I'm missing or a better way to dynamically render a TileEntity?

- Just because things are the way they are doesn't mean they can't be the way you want them to be. Unless they're aspen trees. You can tell they're aspens 'cause the way they are.

Link to comment
Share on other sites

TESR should only really be used if the model animates.

 

I can't really advise on how best to proceed trying to do this with JSON models, but if you do go TESR, go FastTESR.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Well, the model probably will be changing a lot. I'm not sure if I'll be animating yet. I'll look into FastTESR

- Just because things are the way they are doesn't mean they can't be the way you want them to be. Unless they're aspen trees. You can tell they're aspens 'cause the way they are.

Link to comment
Share on other sites

If you won't be animating, use custom IBakedModel. If you do want to animate, as Draco said, use Fast TESR.

 

By creating custom implementation of IBakedModel, you can override getQuads. In order to provide tile's data to get quads, pass unlisted properties from your block to model (override unlisted prop methods in your block class). getQuads is called each time model is drawn (item / in-world render update). So, in there, get baked models for all your parts, stream all the quads transforming accordingly, collect into a list and that list (considering your frame is rather a non-full block, you should do it only when side arg is null - side arg is for adjacency culling - ).

 

Example (might be too many files to all link here) : IBaked, Helper, Uses client baked lib and client baked pipeline (and here), Model reg manager for using loaded & mapped json/obj/baked models for custom stuff, and a lot more...

Edited by Elix_x
Example & Links 2
Link to comment
Share on other sites

Oh boy, what have I gotten myself into... I'm already half-way through creating a FastTESR, so I'm going to see how well that does. I'll probably end up coming back to this, though.

- Just because things are the way they are doesn't mean they can't be the way you want them to be. Unless they're aspen trees. You can tell they're aspens 'cause the way they are.

Link to comment
Share on other sites

Honestly, I was pretty overwhelmed reading through that the first time. However, on closer inspection this doesn't seem all that complicated. I'm just wondering - if getBakedQuads is called every frame, how is it more efficient than a TESR or FastTESR? I mean, obviously it may be because with a TESR, I'd be pushing and popping matrices, and drawing point-by-point and whatnot, but doesn't that eventually have to be done anyway, whether I give Minecraft a BakedModel, or I just render it myself?

- Just because things are the way they are doesn't mean they can't be the way you want them to be. Unless they're aspen trees. You can tell they're aspens 'cause the way they are.

Link to comment
Share on other sites

19 minutes ago, AnZaNaMa said:

getBakedQuads is called every frame

It isn't. Its only called when the chunk is re-rendered, which is only whenever a block in that chunk changes state.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Oh, okay. So @Elix_x I don't really understand how you're passing the TileEntity to the getQuads(). I know you're using some sort of workaround with the UnlistedPropertyGeneric, but I don't see what's going on. Is there any chance you could give an example of passing the TileEntity to getQuads() without the Optionals and lambda functions? I'm not well versed in Java 8, so it's extremely confusing to me.

- Just because things are the way they are doesn't mean they can't be the way you want them to be. Unless they're aspen trees. You can tell they're aspens 'cause the way they are.

Link to comment
Share on other sites

Actually, I think I may have managed to figure it out. Here's what I'm doing in getQuads() to access the TileEntity:

@Override
    public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
        if(side != null) {
            return Collections.EMPTY_LIST;
        }
        IExtendedBlockState extState = (IExtendedBlockState)state; 
        TileEntityBase  tile = (TileEntityBase)extState.getValue(UnlistedProperty.BLOCK_ACCESS).getTileEntity(extState.getValue(UnlistedProperty.POS));
    }

 

Are you using the UnlistedPropertyGeneric.WORLD and UnlistedPropertyGeneric.TILE elsewhere, or am I missing something? Do I need to map these properties to the block somewhere else so that I can actually access them without error here?

- Just because things are the way they are doesn't mean they can't be the way you want them to be. Unless they're aspen trees. You can tell they're aspens 'cause the way they are.

Link to comment
Share on other sites

Yep, you have to declare them in block class to make MC know about them, and actually provide/update them.

FYI: This is similar for saved, actual and extended props. The declaration of all 3 is in createBlockState, saved props are handled by meta<->state methods, actuals by getActualState and extended - by getExtendedState. The difference between actual and extended, is that actual is used on server and client, has a limited number of serializeable values it can take and can be used in state mapping (~json model). Extended state is used only on client, can take any values of any type, and cannot be used for state mapping - aka only custom IBaked models.

 

FYI 2: Actually, if you can create a single unlisted property for tile entity and pass it directly, instead of world and position. I'm just using 2 separate props, because i'm using them for other blocks too, which don't always have a tile entity, or i simply don't need it.

Link to comment
Share on other sites

Thanks for your help! I was doing some more research and found another topic here where you linked a topic related to IBakedModels, but it seems the link doesn't work anymore. Don't suppose you know how I can find it?

- Just because things are the way they are doesn't mean they can't be the way you want them to be. Unless they're aspen trees. You can tell they're aspens 'cause the way they are.

Link to comment
Share on other sites

19 hours ago, Elix_x said:

Yep, you have to declare them in block class to make MC know about them, and actually provide/update them.

I am sorry, but this is precisely what not to do. Blockstate properties (unlisted or not) may be passed off to a rendering thread, which must not interact with the main game objects like the world. This is precisely why block states work the way they work. If you must pass custom data through unlisted properties, you must grab it all in getExtendedState and then pass it into the block state as an immutable (or immutable-like, i.e. not changing anymore) object. An IBlockState object should never suddenly change it's contents, which yours does, since the World can and will change.

Link to comment
Share on other sites

1 hour ago, diesieben07 said:

I am sorry, but this is precisely what not to do. Blockstate properties (unlisted or not) may be passed off to a rendering thread, which must not interact with the main game objects like the world. This is precisely why block states work the way they work. If you must pass custom data through unlisted properties, you must grab it all in getExtendedState and then pass it into the block state as an immutable (or immutable-like, i.e. not changing anymore) object. An IBlockState object should never suddenly change it's contents, which yours does, since the World can and will change.

I understand that concurrency is an issue that can occur at any time. But what's the other way of passing required information to the model? You could compile everything you need into immutable objects to be passed, and that work on that in tessellation, but that creates compilation (+decompilation) overhead.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • every time I try to load forge version 1. 12. 2 with the blockbuster mod the mclib and the metamorphs mod The game crashed and this is the crash m whilst there was a severe problem during mod loading that has caused the game to fail Error: net.minecraftforge.fml.common.LoaderExceptionModCrash: Caught exception from Blockbuster (blockbuster)
    • Join the Ultimate EarthSMP - [RiftMC SMP] play.riftmc.net https://riftmc.net/ Join Our Discord     Are you ready to embark on a Minecraft adventure like no other? Look no further than RiftMC! With our server, you'll be transported to a world of endless possibilities, where your imagination can run wild.   Have you ever dreamed of building your own kingdom, or exploring vast landscapes with your friends? At RiftMC, you can do just that and more. With multiple gameplay options, including survival, earthsmp, and PvP gameplay, you'll never run out of things to do.   Are you looking for a challenge? Our survival mode will test your skills as you brave the dangers of the wilderness. Or, if you're feeling creative, our custom world is the perfect canvas for you to unleash your imagination and build whatever your heart desires.   Do you thrive on competition? Our PvP arenas are the perfect place for you to battle it out with other players for supremacy. Or, if you prefer a more cooperative experience, join up with other players to form communities and build sprawling cities.   But that's not all - we also have a thriving economic system, where you can buy and sell goods with other players and even start your own businesses. And with our friendly and dedicated staff, you can rest assured that you'll always have the help and support you need.   So, what are you waiting for? Are you ready to experience the adventure of a lifetime? Join the thousands of players who have already discovered the magic of RiftMC! Simply connect to play.riftmc.net and let the journey begin. Are you ready to dive in?  
    • I want a sword that will kill all hostile mobs with one hit, so is there any way to do that?
    • I have that error when i started my forge server, can anyone help me? C:\Users\orden\Desktop\Servidor MC>REM Forge requires a configured set of both JVM and program arguments. C:\Users\orden\Desktop\Servidor MC>REM Add custom JVM arguments to the user_jvm_args.txt C:\Users\orden\Desktop\Servidor MC>REM Add custom program arguments {such as nogui} to this file in the next line before the  or C:\Users\orden\Desktop\Servidor MC>REM  pass them to this script directly C:\Users\orden\Desktop\Servidor MC>java @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.18.2-40.1.57/win_args.txt 2023-04-01 21:15:43,376 main WARN Advanced terminal features are not available in this environment [21:15:43] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher running: args [--launchTarget, forgeserver, --fml.forgeVersion, 40.1.57, --fml.mcVersion, 1.18.2, --fml.forgeGroup, net.minecraftforge, --fml.mcpVersion, 20220404.173914, -nogui] [21:15:43] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher 9.1.3+9.1.3+main.9b69c82a starting: java version 20 by Oracle Corporation [21:15:43] [main/INFO] [op.OptiFineTransformationService/]: OptiFineTransformationService.onLoad [21:15:43] [main/INFO] [op.OptiFineTransformationService/]: OptiFine ZIP file URL: union:/C:/Users/orden/Desktop/Servidor%20MC/mods/OptiFine-1.18.2_HD_U_H7.jar%2338!/ [21:15:43] [main/INFO] [op.OptiFineTransformationService/]: OptiFine ZIP file: C:\Users\orden\Desktop\Servidor MC\mods\OptiFine-1.18.2_HD_U_H7.jar [21:15:43] [main/INFO] [op.OptiFineTransformer/]: Target.PRE_CLASS is available [21:15:43] [main/INFO] [mixin/]: SpongePowered MIXIN Subsystem Version=0.8.5 Source=union:/C:/Users/orden/Desktop/Servidor%20MC/libraries/org/spongepowered/mixin/0.8.5/mixin-0.8.5.jar%2314!/ Service=ModLauncher Env=SERVER [21:15:43] [main/INFO] [op.OptiFineTransformationService/]: OptiFineTransformationService.initialize [21:15:45] [main/INFO] [op.OptiFineTransformationService/]: OptiFineTransformationService.transformers [21:15:45] [main/INFO] [op.OptiFineTransformer/]: Targets: 350 [21:15:45] [main/INFO] [op.OptiFineTransformationService/]: additionalClassesLocator: [optifine., net.optifine.] [21:15:47] [main/INFO] [mixin/]: Compatibility level set to JAVA_17 [21:15:47] [main/INFO] [mixin/]: Successfully loaded Mixin Connector [de.maxhenkel.camera.MixinConnector] [21:15:47] [main/INFO] [mixin/]: Successfully loaded Mixin Connector [tictim.paraglider.MixinConnector] [21:15:47] [main/INFO] [cp.mo.mo.LaunchServiceHandler/MODLAUNCHER]: Launching target 'forgeserver' with arguments [-nogui] [21:15:47] [main/WARN] [mixin/]: Error loading class: net/minecraft/server/level/ChunkMap (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: @Mixin target net.minecraft.server.level.ChunkMap was not found securitycraft.mixins.json:camera.ChunkMapMixin [21:15:47] [main/WARN] [mixin/]: Error loading class: de/maxhenkel/gravestone/events/DeathEvents (java.lang.ClassNotFoundException: de.maxhenkel.gravestone.events.DeathEvents) [21:15:47] [main/WARN] [mixin/]: Error loading class: net/minecraft/world/item/ItemStack (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: @Mixin target net.minecraft.world.item.ItemStack was not found tombstone.mixins.json:ItemStackMixin [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/lang/invoke/MethodHandles$Lookup (java.lang.IllegalArgumentException: Unsupported class file major version 64) [21:15:47] [main/WARN] [mixin/]: Error loading class: java/util/concurrent/CompletableFuture (java.lang.IllegalArgumentException: Unsupported class file major version 64) Exception in thread "main" org.spongepowered.asm.mixin.transformer.throwables.MixinTransformerError: An unexpected critical error was encountered         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.MixinProcessor.applyMixins(MixinProcessor.java:392)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.MixinTransformer.transformClass(MixinTransformer.java:250)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.service.modlauncher.MixinTransformationHandler.processClass(MixinTransformationHandler.java:131)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.launch.MixinLaunchPluginLegacy.processClass(MixinLaunchPluginLegacy.java:131)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.serviceapi.ILaunchPluginService.processClassWithFlags(ILaunchPluginService.java:156)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.LaunchPluginHandler.offerClassNodeToPlugins(LaunchPluginHandler.java:88)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.ClassTransformer.transform(ClassTransformer.java:120)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.TransformingClassLoader.maybeTransformClassBytes(TransformingClassLoader.java:50)         at cpw.mods.securejarhandler@1.0.3/cpw.mods.cl.ModuleClassLoader.readerToClass(ModuleClassLoader.java:110)         at cpw.mods.securejarhandler@1.0.3/cpw.mods.cl.ModuleClassLoader.lambda$findClass$16(ModuleClassLoader.java:216)         at cpw.mods.securejarhandler@1.0.3/cpw.mods.cl.ModuleClassLoader.loadFromModule(ModuleClassLoader.java:226)         at cpw.mods.securejarhandler@1.0.3/cpw.mods.cl.ModuleClassLoader.findClass(ModuleClassLoader.java:216)         at cpw.mods.securejarhandler@1.0.3/cpw.mods.cl.ModuleClassLoader.loadClass(ModuleClassLoader.java:132)         at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)         at java.base/java.lang.Class.getDeclaredMethods0(Native Method)         at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3502)         at java.base/java.lang.Class.getMethodsRecursive(Class.java:3643)         at java.base/java.lang.Class.getMethod0(Class.java:3629)         at java.base/java.lang.Class.getMethod(Class.java:2319)         at MC-BOOTSTRAP/fmlloader@1.18.2-40.1.57/net.minecraftforge.fml.loading.targets.CommonServerLaunchHandler.lambda$launchService$0(CommonServerLaunchHandler.java:32)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:53)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:71)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.Launcher.run(Launcher.java:106)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.Launcher.main(Launcher.java:77)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:26)         at MC-BOOTSTRAP/cpw.mods.modlauncher@9.1.3/cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:23)         at cpw.mods.bootstraplauncher@1.0.0/cpw.mods.bootstraplauncher.BootstrapLauncher.main(BootstrapLauncher.java:149) Caused by: org.spongepowered.asm.mixin.throwables.ClassMetadataNotFoundException: java.util.concurrent.CompletableFuture         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.MixinPreProcessorStandard.transformMethod(MixinPreProcessorStandard.java:754)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.MixinPreProcessorStandard.transform(MixinPreProcessorStandard.java:739)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.MixinPreProcessorStandard.attach(MixinPreProcessorStandard.java:310)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.MixinPreProcessorStandard.createContextFor(MixinPreProcessorStandard.java:280)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.MixinInfo.createContextFor(MixinInfo.java:1288)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.MixinApplicatorStandard.apply(MixinApplicatorStandard.java:292)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.TargetClassContext.apply(TargetClassContext.java:383)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.TargetClassContext.applyMixins(TargetClassContext.java:365)         at MC-BOOTSTRAP/org.spongepowered.mixin/org.spongepowered.asm.mixin.transformer.MixinProcessor.applyMixins(MixinProcessor.java:363)         ... 27 more C:\Users\orden\Desktop\Servidor MC>pause Presione una tecla para continuar . . .
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.