jmc2obj / j-mc-2-obj

Java-based Minecraft-to-OBJ exporter.
http://www.jmc2obj.net
331 stars 57 forks source link

CommonMCOBJ Feedback #243

Closed StandingPadAnimations closed 1 month ago

StandingPadAnimations commented 3 months ago

Hey there, Mahid from the MCprep team here. I want to propose and discuss a draft specification that we at the MCprep team have been working on for the past week or so: CommonMCOBJ

CommonMCOBJ aims to establish a common standard for extra metadata in OBJ exports, such as texture export information, information about the selection that the OBJ is derived from, etc. In addition, we also want to create a unified way to export biome information, to improve animator workflows in the 3D software side of things.

Even though it's a draft, we want to gather feedback for CommonMCOBJ from OBJ developers to make sure the spec works for OBJ exporters (after all, it's so far made from the perspective of us MCprep developers), and improve it before finalizing V1 and requesting support.

Hope to hear back!

mmdanggg2 commented 3 months ago

Yea, I like it, think it makes sense to be able to pass some kind of standard metadata around. My only comment would be that the selection centre would be redundant if you already have the bounds.

StandingPadAnimations commented 3 months ago

Makes sense. Regarding selections, is getting in-game coordinates possible for the the bounds of a selection, or would that be more complicated on the exporter side of things?

mmdanggg2 commented 3 months ago

Yes - I had assumed that the bounds were in world space and that should be easy to do given that the selection is already made and used with world coordinates. Another suggestion, perhaps a scale field would make sense too, to say how big 1 block is in obj units.

mmdanggg2 commented 3 months ago

Just thinking a little more, is there a reason why the selection is only for the XY and not Z and then on top of that, why would it be supplied in Z up coordinate mode when minecraft is Y up by default. I think the way I would do it is to have the selection fields replaced with an export_bounds_min/max that have the XYZ coordinates of the min and max block in minecraft world coordinates that are included in the export. Then if Z up is true it just means that Y and Z have been swapped in the obj coordinates, the bounds would remain in the Y up minecraft world space.

StandingPadAnimations commented 3 months ago

To clarify, z_up refers to the orientation of the outputed OBJ; some 3D programs set the Z axis as up while others set the Y axis as up. This wouldn't impact actual selction coordinates. Maybe we could rename the variable to something like up_axis and have it set to either Y or Z.

Having a Z coordinate for selections might be a bit weird as selections tend to be interpreted as 2D, but I think including it would be fine, perhaps with a seprate height range variable that could be something like (max depth, max height)

mmdanggg2 commented 3 months ago

Z up is fine as it is. My point was that the spec says selection_vertex_top: (X, Y) coordinates of the top vertice which if you're talking about a selection made from the perspective of looking down on the world like a map, then in fact you mean that the selection in minecraft coordinates would be (X, Z).

As for including the vertical coordinate in the data, It's just a much more complete description of what is actually included in the obj. If this is supposed to describe what part of a minecraft world has been exported into the obj file then it's pretty important to include that I would have thought. jmc lets you select the exported region in all 3 dimensions and so an export from a world may only be from Y60-128 for example. That should be represented in this metadata. As I said, I think it makes more sense for it to be an exported bounding box which covers all these cases. If an exporter doesn't let the user select the Y range of the export then it would just set the bounds to the min and max world height.

StandingPadAnimations commented 3 months ago

Thanks for clarifying, a bounding box would certainly be a more flexible option. If I'm understanding correctly, instead of using selection vertices, there would be min-max ranges for the X, Y, and Z components, similar to the following? (just as an example):

# x_range: (min x, max x) 
# y_range: (min y, max y) 
# z_range: (min z, max z) 
mmdanggg2 commented 3 months ago

Yea, that could certainly work too. I think it's just more concise and specific to have something like

# exported_bounds_min: (min X, min Y, min Z)
# exported_bounds_max: (max X, max Y, max Z)

Where the XYZ is (inclusive) the minecraft coordinates of the exported blocks

mmdanggg2 commented 3 months ago

I've done a basic implementation here if you wanna try it: jMc2Obj-123_CommonMCOBJ.zip

StandingPadAnimations commented 3 months ago

Sounds good to me, thanks for the feedback. I'll open a PR once we've finalized version one of CommonMCOBJ

TheDuckCow commented 3 months ago

Just wanted to say thanks @mmdanggg2 for being quick to respond and support the idea, very excited for moving this forward!

mmdanggg2 commented 3 months ago

Just had a read through the updated definition and It's not very clear and sounds like we're not totally on the same page. Here's a full example just so there's no ambiguity about what I mean. In the game I found an area I want to export and made a note of the coordinates: One corner at X: 304, Y: -53, Z: 100 Screenshot 2024-03-22 013513 The other at X: 343, Y: 125, Z: 130 Screenshot 2024-03-22 013749

I select this region in jmc and export (in jmc, the max coordinate is not inclusive so those values are all +1): image

The selection is exported with these blocks at the min and max corners: image

And the obj file contains these values in the header, describing the region of the minecraft world that is in the obj file:

# exported_bounds_min: 304, -53, 100
# exported_bounds_max: 343, 125, 130
StandingPadAnimations commented 3 months ago

Thanks for the clarification, I'll update the spec accordingly

StandingPadAnimations commented 3 months ago

Alright, I've updated the selections section to be more in line with your proposal: https://github.com/CommonMCOBJ/CommonMCOBJ#selections

StandingPadAnimations commented 3 months ago

I've opened #245 to add CommonMCOBJ version 1 support. Although version 1 isn't technically finalized, it's more or less in a complete state.

mmdanggg2 commented 3 months ago

Yea - nice. A few more thoughts I had, mentioned it earlier but a scale value I think would be good, eg a scale of 1.5 means in the obj units one block is 1.5 units big. And then I feel like centred and split blocks are a bit ambiguous. For centered, jmc's centred mode is a little weird in that it places the centre of the bounds at 0,0 on the X Z axis but it places the min Y at 0 rather than the centre of Y at 0. Perhaps instead, an offset XYZ value to say how it has been moved from the original coordinates? Split blocks I think is going to be quite hard to nail down, jmc has a few different ways to split the blocks and they interact differently depending on which options you've picked and I doubt other apps, such as mineways, would have equivalents.

StandingPadAnimations commented 3 months ago

A scale parameter is a good idea, I'll add it. As for centered, I think we could define it as the center of the bounding box itself (which would presumably be the center of the OBJ), or perhaps we could just forego is_centered for now and add it back when it's better defined.

Split blocks would be equivalent to object per block, where each block type is split as its own separate object.

mmdanggg2 commented 3 months ago

I don't wanna sound too pushy with my suggestions but to me an offset xyz would still provide the information that is_centered would give at the same time as removing any ambiguity with what exactly that means and then additionally provides information about any other kind of translation that could have been applied. It would mean that jmc's weird centered mode is handled but also any arbitrary offset that could be made, something else that jmc allows.

Ok, the current split block description sounds much more like jmc's split materials option so that should be clarified.

TheDuckCow commented 3 months ago

Regarding is_centered, I also agree that bounding box min/max conveys the same information and is a bit more obvious to understand. I'd just leave it out.

Something separate that would be interesting to know is a block offset. From the MCprep standpoint, this is one of those things that we hard code : if jmc2obj do an extra vec3(0.5m) offset, but don't do for Mineways (or vice versa, don't remember offhand).

block_offset could be succinctly defined as the absolute world location of the center of any 1x1x1 block whose origin is defined as (0,0,0).

And this would just be hard coded in jmc2obj as (0,0,0) or (0.5, 0.5, 0.5) and would be the opposite in Mineways (again, I don't remember which one is using which). Or maybe we define it as an absolute position of the lowest value vertex, in which case it'd be either (0,0,0) meaning the cube position ranges from xyz 0->1, or (-0.5, -0.5, -0.5) meaning the cube is centered on the orgin itself.

mmdanggg2 commented 3 months ago

Yea, that's a good point about if the coordinate is at the centre of the block or in the lower corner. Something like you say perhaps block_centre_offset: 0, 0, 0

I think my point about a general offset value is important to include. Without it it would be impossible to accurately piece together multiple separate exports into the same coordinate space.

TheDuckCow commented 3 months ago

Yeah I'm fine with that definition.

Right, I also agree about having an absolute offset shift as indeed, where this common header will shine the most is in letting users re-export the same section or adjacent sections with ease.

StandingPadAnimations commented 3 months ago

block_offset sounds good, though perhaps we could call it export_offset to be more consistant with the export_bounds_* variables.

StandingPadAnimations commented 3 months ago

Working on defining offsets, but I'm a bit lost, can you give a visual representation of how that might look?

StandingPadAnimations commented 3 months ago

Ok I think I get it now, is it just how much the center is offset in world space (3D software side) from the center of the bounding box?

StandingPadAnimations commented 3 months ago

@mmdanggg2 @TheDuckCow is this a good definition for offsets?:

Offsets are defined as the coordinate offsets from the center of the Selection's volume in meters (it should be kept in mind that Selections are 3D bounding boxes). This offset can be any floating point value and is not based off of Minecraft coordinates, but rather world space in 3D software.

mmdanggg2 commented 3 months ago

Just going back to my previous example, the block in the minecraft world is at X: 343, Y: 125, Z: 130 If I set the offset to none (0, 0, 0), then in the obj it is exported with the vertices for that block at the same coordinates: Screenshot 2024-03-23 033001 If I then set the offset to centre the model, that same block now has its verticies at coordinates at X: 19, Y: 178, Z: 15 Screenshot 2024-03-23 033036 The offset is then simply the translation vector from where the minecraft block coordinates are to where they are exported in the model. In this case the offset would be this

export_offset: (-324, 53, -115)

Animation

I think it makes sense to have these be in minecraft coordinates, so if there's scale, it is not applied to this transform.

StandingPadAnimations commented 3 months ago

So in order words, offsetting the coordinate of export_bounds_max? Makes sense

mmdanggg2 commented 3 months ago

It's not specifically of the max, its of all coordinates, the whole model has been translated by the offset vector.

StandingPadAnimations commented 3 months ago

Alright

StandingPadAnimations commented 3 months ago

After a bit of writing, we've got this definition of offsets:

Offsets are defined as the translation vector by which all blocks are offset from their original location in the final export, defined in Minecraft coordinates.

StandingPadAnimations commented 3 months ago

I think we're ready to finalize V1, any changes that need to be made? (CommonMCOBJ can also be updated as time passes)

mmdanggg2 commented 3 months ago

Nearly there. last couple of bits.

We probably should have, as @TheDuckCow suggested, a block_origin_offset. In minecraft the coordinate of a block is actually the lowest corner point of the block and so in a similar way to the export offset, this would specify how the model is translated from the normal minecraft coordinates. In the case of jmc, the block coordinate is in the centre of the block model and so has a offset of -0.5 on each axis.

block_origin_offset: (-0.5, -0.5, -0.5)

Screenshot 2024-03-23 052149 image

I think scale should be float, why be restricted to whole values.

The description for split blocks still reads to me as though you mean that there is only one object per block type, not per individual block.

StandingPadAnimations commented 3 months ago

Block offsets have been added now, and scale has been change to float. To clarify on split blocks, it is split on a block type basis, not individual blocks

mmdanggg2 commented 3 months ago

Ok so that is then closest to jmc's object per material option, not object per block.

StandingPadAnimations commented 3 months ago

Assuming there's nothing else to add or change, CommonMCOBJ V1 is finalized now! :tada:

Thanks for all of the feedback @mmdanggg2