sq / JSIL

CIL to Javascript Compiler
http://jsil.org/
Other
1.73k stars 240 forks source link

Matrix.CreateTranslation(Vector3.Zero) produces NaN result #416

Open vchelaru opened 10 years ago

vchelaru commented 10 years ago

A translation with a Vector of 0 should produce the matrix:

1000 0100 0010 0001

But instead the M4X values get a float.NaN:

        float value = Matrix.CreateTranslation(Vector3.Zero).M41;

        System.Console.WriteLine(value);

This will give you NaN in the output.

vchelaru commented 10 years ago

I'm getting more weird behavior with Matrices, but it's not 100% consistent. Will add more info as I find it.

vchelaru commented 10 years ago

Well, crap, it seems to only happen in certain situations, and I can't figure out what it is exactly. May have to do with being in a virtual property, may have to do with how deep the stack is.

kg commented 10 years ago

You can and should assume all the 3d math related APIs in stock JSIL to be completely busted. For proper 3D you'll want to use cross-compiled monogame (which naturally is not completely finished since they never merged it)

I'll take a look at this anyway. There are probably 2D games that use 3D matrices.

vchelaru commented 10 years ago

Thanks kg. I don't want to burn all my bug fixing equity on something so hard to reproduce so let me give you some more help on this.

This issue manifested itself in a project I'm working on to port the FlatRedBall XNA game engine to JSIL. I'm not taking the entire engine and dropping it in, but rather piece by piece, line by line, to help find issues like this.

The bug happens deep in the call stack in the rendering code, and when I try to grab an identity matrix right in the XNA game, everything works perfectly. I'm currently trying to get a simpler case that reproduces the problem. Fortunately once the problem reproduces, it continually reproduces execution after execution and frame by frame (I'm doing a Console.WriteLine in Draw).

Worst case I'm going to get a simple project built up where this reproduces in the simplest possible case I can create and I'll upload it somewhere so you can grab it for this issue.

Thanks again for being so responsive, I'll be posting updates very soon.

vchelaru commented 10 years ago

Got it! In a fairly simple case too. All you need is a Game1 class and this other class that I created. Here's a link to the source:

http://pastebin.com/dqbYWZEX

If you run this you will see the following output:

This works fine: 0 Invalid (in property): undefined Invalid (in function): undefined (repeated indefinitely)

It seems like the Matrix class is working fine, but the problem occurs based on where the calls to get the identity matrix are made. You can see specifically it happens when I try to get a matrix from either a property or a function of this simple class.

So even though the post originally suspected something in Matrix was busted, it turns out it's perhaps much worse - that things behave improperly depending on where on the stack they are used. Who knows where else this manifests itself.

If you'd like a full project or any other information, please let me know and I'll do my best to provide it. I'm also available on Google Hangouts (I believe I sent you a message earlier) if you'd like to see it over screen share.

iskiselev commented 10 years ago

I've checked it - there is no problems in JSIL except not fully implemented Matrix features. It doesn't use M11, M12 and so on fields at all - instead it use x/y/z Rotation/Scale/Translation. Besides of this, it implement castom copy constructor, that skips copying default fields (that have 0 value in initial Matrix, as they are defined in XNA translated assemblies). So, when JSIL generates MemberwiseClone for matrix, M41, same as all other Mxy became undefined (but even in identity matrix nobody initialize them with values, other then 0). JSIL generates MemberwiseClone, when function returns Matrix - as it is struct. I can only suggest rewrite current Matrix implementation and use Mxy fields/properties inside.

kg commented 10 years ago

That is the best solution, yes. I've deferred it since JSIL XNA isn't intended to support 3D (and that's why the matrix implementation is focused on 2D - a few games I tried porting used matrices for 2d; never saw a full use of 3d matrices).

Ideally you could translate monogame's matrix and use that. Might have to translate their vector also, but our vector structs are relatively complete in comparison

vchelaru commented 10 years ago

SpriteBatch.Begin has an overload which takes a matrix. This (in my experience) is used quite commonly to implement simple 2D camera scrolling in 2D. games. I mention this to hopefully add some importance to having an implemented Matrix in jsil. On Apr 29, 2014 11:58 PM, "K. Gadd" notifications@github.com wrote:

That is the best solution, yes. I've deferred it since JSIL XNA isn't intended to support 3D (and that's why the matrix implementation is focused on 2D - a few games I tried porting used matrices for 2d; never saw a full use of 3d matrices).

Ideally you could translate monogame's matrix and use that. Might have to translate their vector also, but our vector structs are relatively complete in comparison

— Reply to this email directly or view it on GitHubhttps://github.com/sq/JSIL/issues/416#issuecomment-41763373 .

vchelaru commented 10 years ago

Sorry for the bump but I see that this issue was referenced in another issue which was closed. Does this mean that this issue has been fixed?

iskiselev commented 10 years ago

Sorry, that reference was added by typo. I already fixed reference in original place, but it can't be removed from this bug. So, nothing has changed for this bug - and will not change until somebody will create proper implementation for Matrix in JSIL libraries or try to port original classes.