Find the "unrotated" location of a collision point

Hey monkeys! First of all I’m new here, and so far I love the engine. My friend and I are working on a fun little space simulator based on games like Shores of Hazeron and Minecraft :stuck_out_tongue:

Anyway, I’m looking for some help finding the “unrotated” location of a collision point. Basically I have a cube that constantly spins. When I click the cube and get the collision point, I want to find where the collision point would have been had the cube not been rotated. I hope that makes sense. I have tried quaternions by getting the rotation of the cube and multiplying it by the collision point, but that seems to give me less accurate results the more the cube rotates. I’ve personally never seen quaternions before fiddling with this problem, so I am probably doing something wrong there. Any help would be appreciated, and if this doesn’t make sense to anyone I will try to make it clearer. Thanks!

From the math for dummies tutorial, it shows you, that you can rotate a vector by a Quaternion. So you just have to rotate your collision vector by the inverse of the cube’s rotation, to cancel it out. Something like:

[java]cube.getLocalRotation().inverse().mult(collisionVec);[/java]

Edit: Actually I think that would only help converting the collision normal back to the original

Or you could getWorldTransform().transformInverseVector()

<cite>@wezrule said:</cite> From the math for dummies tutorial, it shows you, that you can rotate a vector by a Quaternion. So you just have to rotate your collision vector by the inverse of the cube's rotation, to cancel it out. Something like:

[java]cube.getLocalRotation().inverse().mult(collisionVec);[/java]

Edit: Actually I think that would only help converting the collision normal back to the original

Yeah, I have tried that, it doesn’t give me correct results. I think you are right with it only working with its normals, which in my case won’t be useful, as I need the actual world vector, not just a normal of it. Thanks for the help!

Edit: Actually, I just tried it again and it seems to work rather fine except for that it isn’t very precise. I added a node to the cube at the corner of the cube (so the cube spins around its center, and has a child node at its corner.) I know exactly where this node should be if it was unrotated, (-72, -72, -72), though I am getting close numbers like (-71.99994, -71.99968, -72.00008) when rotating by the center’s local inverse. Obviously by rounding I would get the right number, but in my case I need it to be more precise and return whole numbers. Is there a reason it returns very close decimals? Thanks!

<cite>@zarch said:</cite> Or you could getWorldTransform().transformInverseVector()

I’m not sure you understand what I want. I don’t want the inverse of the point, I want the “unrotated” point. So if I had a cube that was rotated 10 degrees on the x axis and I clicked and got a collision point somewhere on the cube, I would want to know what the coordinates of that collision point would be if the point was rotated -10 degrees on the x axis. So if you think of the point as being attached to the cube like a child node, and the cube rotated -10 degrees on the x axis, I want to know where that point ends up. Thanks!

Oh rly? I wouldn’t have expected it to work at all ^^ so that’s surprising

Also I had a look at the transformInverseVector() source, and it would be useful for what you want. Although it does reverse all transformations, so you would need to add scale and translation again. Or you could implement the parts you need. I think this should work (not tried it though).

[java]
Vector3f vec = collisionVec.substract(cube.getLocalTranslation ());
Vector3f anotherVec = cube.getLocalRotation ().inverse().mult(vec);
Vector3f originalVec = cube.getLocalTranslation ().add(anotherVec);
[/java]

Another way I potentially found while messing around with this on paper is (completely untested):

(Original Normal - Collision Normal) + Collision Point

You can calculate the “Original normal” using the first equation I posted. I’m quite tired, so I might be talking jibberish right now xD

<cite>@wezrule said:</cite> Oh rly? I wouldn't have expected it to work at all ^^ so that's surprising

Also I had a look at the transformInverseVector() source, and it would be useful for what you want. Although it does reverse all transformations, so you would need to add scale and translation again. Or you could implement the parts you need. I think this should work (not tried it though).

[java]
Vector3f vec = collisionVec.substract(cube.getLocalTranslation ());
Vector3f anotherVec = cube.getLocalRotation ().inverse().mult(vec);
Vector3f originalVec = cube.getLocalTranslation ().add(anotherVec);
[/java]

Another way I potentially found while messing around with this on paper is (completely untested):

(Original Normal - Collision Normal) + Collision Point

You can calculate the “Original normal” using the first equation I posted. I’m quite tired, so I might be talking jibberish right now xD

The first equation sort of works, though it’s still giving me just close numbers and not exact numbers. I’m wondering if I’m just not going to be able to get the exact point but only really close. I tried the equation you made on paper, but it didn’t work at all :stuck_out_tongue: There’s a reason it needs to be so precise, and it’s because the cube is actually a giant cube made up of hundreds of smaller cubes (48x48x48 cubes). I need to find the cube that was clicked, and remove it, or if I am adding a cube I need to find the face clicked and add a cube relative to the face clicked. Finding the face clicked is simple when the cube isn’t rotated, because when you click any face of the cube, one of your coordinates will be a whole number, since the cube is sized exactly 3f x 3f x 3f. So on one face it may look like (48.0, 31.2639, 24.4475) and another maybe (45.3423, 42.0, 13.4250). Notice how the whole numbers are divisible by 3f, the size of the cube. So determining which axis is divisible by 3f, I can determine which face was clicked. This is a problem when “unrotating” the point, because it doesn’t give me exact numbers. So what should be 48.0 may be 48.0009 or 47.6653 or something close. You would think, well, just round the number! But that doesn’t work sometimes as there are times when two numbers end up being rounded to whole numbers divisible by three, so the code picks the first axis it encounters divisible by three, and you end up replacing cubes sometimes. I hope that made sense.

Of course none of this would work if the wrong block was selected, and that also happens sometimes. Because the cube selected is determined by dividing the vector by the size of the cube, 3f, and flooring it, if one number is even a little off, it can choose the next cube over. So sometimes when I select the cube which should be 0,0,0 I get a cube 0,-1,0 or 1,0,0 etc.

I hope a tiny bit of that made sense. If it helps I can make a video later.

(You might be noticing by now where the Minecraft idea comes into play. I am making planets out of cubes… cube planets. :slight_smile: )

Box worlds are not made out of boxes :wink:

Take a look at the cubes framework plugin - it should do most of this for you.

<cite>@zarch said:</cite> Box worlds are not made out of boxes ;)

Take a look at the cubes framework plugin - it should do most of this for you.

I am using the cubes framework. :stuck_out_tongue: I shoulda said that, sorry.

Doesn’t that already have methods to tell you which cube has been clicked? I’d be very surprised if it doesn’t.

<cite>@zarch said:</cite> Doesn't that already have methods to tell you which cube has been clicked? I'd be very surprised if it doesn't.

It does, based on the collision contact point, except it doesn’t work when the planet is rotated. Which is why I’m trying to find the unrotated point

Ahh, ok. That sounds like a bug in the cubes framework.

I’d report it there, or even better investigate and submit a patch.

I don’t think it’s a bug, I don’t think the cubes are meant to be rotated anyway. I’ll go talk to them on the cubes thread and see if anyone has come up with a solution, though. Thanks for the help!

<cite>@PewPewKapowie said:</cite> I tried the equation you made on paper, but it didn't work at all :P

yeh completely ignore that one, what was I thinking xD