Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translation and rotation format #34

Open
spaarmann opened this issue May 7, 2020 · 15 comments
Open

Translation and rotation format #34

spaarmann opened this issue May 7, 2020 · 15 comments

Comments

@spaarmann
Copy link

Hi there.

While writing a parser for the .vox files, I discovered that the documentation doesn't quite match what MagicaVoxel actually produces for the translation and rotation of nTRN chunks.
(Tested in the most recent, unstable 0.99.5).

(_r : int8) ROTATION, see (c)
(_t : int32x3) translation

Both of these are actually ASCII encoded versions of what they describe.

For the translation, instead of just three int32 packed after each other, there is a string of the format "x y z", i.e. the three integers encoded as ASCII and separated by a space.

Similarly, for the rotation, instead of a single byte, there is a string containing a decimal representation of that byte which then matches the format described in the documentation:

(c) ROTATION type
store a row-major rotation in the bits of a byte
for example :
R =
0 1 0
0 0 -1
-1 0 0
==>
unsigned char _r = (1 << 0) | (2 << 2) | (0 << 4) | (1 << 5) | (1 << 6)
bit | value
0-1 : 1 : index of the non-zero entry in the first row
2-3 : 2 : index of the non-zero entry in the second row
4 : 0 : the sign in the first row (0 : positive; 1 : negative)
5 : 1 : the sign in the second row (0 : positive; 1 : negative)
6 : 1 : the sign in the third row (0 : positive; 1 : negative)

As an example,

0 -1 0
1  0 0
0  0 1

is packed into 0b0010001 which is then written into the file as the string "17", i.e. the bytes 0x31 0x37.

Hope this helps anybody stumbling across the same issue, or that @ephtracy perhaps updates the repository to include this information.

@mchorse
Copy link

mchorse commented May 7, 2020

@spaarmann yeah, I documented that in my pull request #33, I’m waiting on @ephtracy’s feedback ☺️

@spaarmann
Copy link
Author

Ah, I didn't see that. I searched through the issues here, but not the PRs, I really wish I would've done that, would've saved me some time :)

I also just realized the documentation does say that DICT values are strings, so it's not exactly wrong... Still think it'd be nice to make this a bit more explicit though.

@mchorse
Copy link

mchorse commented May 9, 2020

Yeah, I suppose I can edit that, what should exactly clarify? That these are in ASCII?

@spaarmann
Copy link
Author

Sorry, this

I also just realized the documentation does say that DICT values are strings, so it's not exactly wrong... Still think it'd be nice to make this a bit more explicit though.

was commenting on the current text in the repository, not the text in your PR :)

@mchorse
Copy link

mchorse commented May 13, 2020

Ahhh, thanks for clarifying 😅

@TomWor
Copy link

TomWor commented May 26, 2021

I'm trying to apply the flip (rotation) in my VOX importer (C#, Unity) and stumbled over this issue.
I already figured out the (_r) dictionary value is made up of two bytes - but what does that actually mean for the "byte-encoded" rotation? Is the second byte to be discarded, how does it relate to the table of bit/value's in the documentation?

I'm also trying to figure out how to apply the rotation, I'm a really rusty on the math.
If I have to apply this rotation to every voxel in my model, could you give me a hint on how the formula needs to look?
(I'm sitting over the Math Primer by Dunn & Parberry, but I just can't map this to the solutions in the book)

               [rx1, ry1, rz1]
[x1, y1, z1] * [rx2, ry2, rz2] = ?
               [rx3, ry3, rz3]

@mchorse
Copy link

mchorse commented May 26, 2021

I'm trying to apply the flip (rotation) in my VOX importer (C#, Unity) and stumbled over this issue.
I already figured out the (_r) dictionary value is made up of two bytes - but what does that actually mean for the "byte-encoded" rotation? Is the second byte to be discarded, how does it relate to the table of bit/value's in the documentation?

I'm also trying to figure out how to apply the rotation, I'm a really rusty on the math.
If I have to apply this rotation to every voxel in my model, could you give me a hint on how the formula needs to look?
(I'm sitting over the Math Primer by Dunn & Parberry, but I just can't map this to the solutions in the book)

               [rx1, ry1, rz1]
[x1, y1, z1] * [rx2, ry2, rz2] = ?
               [rx3, ry3, rz3]

@TomWor, I replied to you in the comments on my PR with this code excerpt. I think this wouldn’t be too hard convert to C#.

@TomWor
Copy link

TomWor commented May 26, 2021

@mchorse I converted your code to C# and it seems to work, thanks!
Do you by any chance have a link or something on how to apply the rotation?

@mchorse
Copy link

mchorse commented May 26, 2021

@mchorse I converted your code to C# and it seems to work, thanks!

No problem!

Do you by any chance have a link or something on how to apply the rotation?

Well, when you'll be constructing a mesh, you'll need to transform your vertices through the transformation matrix, that's how I do it (this.transform should be the rotation matrix that was parsed from the rotation byte).

@TomWor
Copy link

TomWor commented May 26, 2021

I found this to be a good explanation of what I needed:
https://computergraphics.stackexchange.com/questions/5232/row-and-column-majored-rotation-matrix-pre-or-post-multiplied

The mesh geometry is flipped/rotated fine now, only now the translation seems a little off (applying before or after rotation?) and my Normals are flipped. But it looks like I'm getting there.

@mchorse
Copy link

mchorse commented May 26, 2021

I found this to be a good explanation of what I needed:
https://computergraphics.stackexchange.com/questions/5232/row-and-column-majored-rotation-matrix-pre-or-post-multiplied

The mesh geometry is flipped/rotated fine now, only now the translation seems a little off (applying before or after rotation?) and my Normals are flipped. But it looks like I'm getting there.

As far as I remember, you need to apply matrix transformations from the mid point of the voxel chunk. I.e. if you have 16^3 object, you need to apply transformations relative to (8,8,8).

@TomWor
Copy link

TomWor commented May 26, 2021

You're right. With translations I was able to get around that issue easily so far, but with flip and rotate it's a whole different story. So much so that I think I have to restructure my importer to cleanly integrate it.

@wazazhang
Copy link

using DeepCore;
using DeepCore.Reflection;
using DeepCore.Voxel.Data;
using DeepCore.Voxel.Extensions.MagicaVoxel;
using DeepEditor.Common.G2D;
using DeepEditor.Common.G2D.DataGrid;
using DeepEditor.Common.Voxel;
using System;
using System.IO;
using System.Windows.Forms;

namespace SampleBattle2D.Win32
{
static class Program
{
[STAThread]
static void Main(string[] args)
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
ViewVOX(@"E:\dev\DeepWorkspace\DeepSamples2D\SampleEditors\GameEditor\voxel\MagicaVoxel\untitled.vox");
}
public static void ViewVOX(string path)
{
var file = new FileInfo(path);
var vox = MagicaVoxelFile.Load(file);
var world = vox.ConvertToVoxelWorld();
var dialog = new FormVoxelViewer();
dialog.Load += (s, e) =>
{
dialog.LoadVoxelWorld(world);
};
Application.Run(dialog);
}
}
}

@wazazhang
Copy link

image
image
Why this Shape Translatoin X is 1 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants