ousnius / nifly

C++ NIF library for the Gamebryo/NetImmerse File Format
GNU General Public License v3.0
52 stars 23 forks source link

reading and writing external mesh data (starfield), writing untested #41

Closed Caliente8 closed 3 weeks ago

Caliente8 commented 9 months ago

Changes to nifly library to enable import of starfield nifs that use BSGeometry nodes referencing external mesh files.

import is working -- currently scaling mesh vertices by a factor of 64 for them to be appropriately sized for outfit studio.
export is coded, but untested.

hexabits commented 9 months ago

@Caliente8 Why 64x? In my comparisons previous games are 32x larger not 64x.

Caliente8 commented 9 months ago

@Caliente8 Why 64x? In my comparisons previous games are 32x larger not 64x.

In Outfit Studio, it seems that 64x gave a similar size to previous bodies. Honestly, that's a magic number that needs to go away, and the scale should be applied in the library consumer. Thanks for pointing it out, I'll fix that

hexabits commented 9 months ago

@Caliente8 Ah ok, also I think ousni already told you this but for posterity/clarity:

I haven't audited the commits so in case you haven't thought about it, the float values will have to be normalized to -1.0, 1.0 in any component and then the scale of the .mesh adjusted by the normalization factor. Or -32.0, 32.0 if you keep the scale in the lib.

So if you keep the .mesh scale separately for transforming in the renderer, and keep the vertices untransformed, then if some vertex component were increased to -64.0 or 64.0 (or -2.0/2.0 if scale is removed from lib), you'd double the scale value associated with the .mesh and then halve all the vertices to keep the SNORM in range after it's packed again.

hexabits commented 9 months ago

Also my 32.0x came from comparing files that exist in both games, maybe this comparison is flawed if they also changed their true scale by 2.0x for display in the CK.

image image

Caliente8 commented 9 months ago

@Caliente8 Ah ok, also I think ousni already told you this but for posterity/clarity:

I haven't audited the commits so in case you haven't thought about it, the float values will have to be normalized to -1.0, 1.0 in any component and then the scale of the .mesh adjusted by the normalization factor. Or -32.0, 32.0 if you keep the scale in the lib.

So if you keep the .mesh scale separately for transforming in the renderer, and keep the vertices untransformed, then if some vertex component were increased to -64.0 or 64.0 (or -2.0/2.0 if scale is removed from lib), you'd double the scale value associated with the .mesh and then halve all the vertices to keep the SNORM in range after it's packed again.

Right, should be doing the normalization properly -- normalizing uint16_t components to float [0..1] and multiplying by mesh data precision scale value. The 64 (now probably 70) is additional scale on top of that.