- Home /
Check direction in local space against direction in world space.
Hello, I've hit a wall trying to figure out a clean way to compare directions between local and world rotation. If it was simply comparing the rotation of an object against the world that would be easy enough, I'm sure I could get that functioning even if not the most optimal way. The issue I'm having is because there is no transform to work from, only a rotation.
A quick overview, what I'm making is a voxel builder, data for each index is defined in a custom Block class. I'm currently working on a connection system so that I can have blocks that are completely detached treated correctly and have them "break off" etc (eventually I want to have destruction and a damage system). The problem I have is that not everything I want implemented is a 1x1 cube that connects on all sides. I have, for example, a prism/sloped block which only connects on 4 sides, and other structural blocks such as doorways which are a complex volume that have connecting faces spread over multiple array indices & in various directions. On top of this, things can be rotated to 90 degree angles around any axis, and so need to correctly convert any connecting face from the local rotation to world space in the voxel grid.
I'm at a complete loss as to how I can take a direction from a local rotation and cleanly assign it to a correct global axis. When a new Block is initialised the constructor is fed the block type (enum), position (vector3), and rotation (quaternion) and derives everything about the Block from that, as things stand I have 6 booleans for connections in each direction that can be set per Block (I realise there are much cleaner ways to do this, storing the booleans within a byte and doing bitwise operations, for example, I just don't know enough to implement it) and had planned on somehow including a reference to any "connectable nodes" (child indices of the Block, if you will) for larger objects that take the space of multiple blocks.
Hoping someone might be able to point me in the right direction as I'm truly stuck, I've been bashing my head against this brick wall for over a week now and it's really beginning to drain my enthusiasm and confidence.
Answer by Namey5 · Apr 03, 2020 at 11:23 PM
So long as you have a position and rotation, you should be able to derive a transformation matrix yourself. For example, if you want to find the local-to-world transform you can use this matrix;
//Where position and rotation are the total offsets that have been applied to the block
Matrix4x4.TRS (position, rotation, Vector3.one);
Similarly, if you want a world-to-local transform, it's just the inverse of the above matrix. From there you can multiply the matrix by whatever you need, or use one of it's functions to handle different multiplications for you.
I see. I've been playing around with $$anonymous$$atrix4x4 and I had what I thought was a functioning implementation but it behaved oddly as soon as I rotated the object.
$$anonymous$$atrix4x4 node$$anonymous$$atrix = $$anonymous$$atrix4x4.TRS(nodeOffset, rotation, Vector3.one);
Is what I used to set it, I've tried various ways to derive the node index from this but it always seems to produce very strange results as soon as the object is rotated.
For the record, the offset in this example is the simplest object I have which takes the space of two voxel volumes and has an extra node +1 on the z-axis (depending on rotation, obviously) that connects on all sides. I was trying to derive what index the node would be in each rotation but everything I tried (all of the different $$anonymous$$ultiply functions) threw strange results.
It's difficult to get an understanding of this from the outside, as it is a fairly complex system with an implementation unique to you. In general, these are the inputs to the TRS constructor;
Position: this is the final world-space position of the node, therefore if you have a base position/rotation and the node's coordinates are defined in that local space, you would need to first define the base TRS and use that to find the nodeOffset, i.e.
$$anonymous$$atrix4x4 volumeToWorld = $$anonymous$$atrix4x4.TRS (volumePosition, volumeRotation, Vector3.one);
Vector3 nodeWorldPos = volumeToWorld.$$anonymous$$ultiplyPoint (nodeOffset);
Rotation: this is similar, except to find the node's rotation, we just need to accumulate all rotations applied to the node in the order they are applied, i.e.
Quaternion nodeRotation = volumeRotation * localRotation;
From there you should be able to use those, if I'm understanding the question correctly. Without knowing your setup it is difficult to diagnose, however.