Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotating 6 sides of a block

I've been following a XNA tutorial by The Hazy Mind I have a base object that has a Position (Vector3) and a Rotation (Quaternion). The object model looks like this Class Diagram

From the camera implementation in the tutorial, i've made a copy of the Rotation and Revolve methods and implemented them on the Object

public virtual void Rotate(Vector3 axis, float angle)
{
    axis = Vector3.Transform(axis, Matrix.CreateFromQuaternion(Rotation));
    Rotation = Quaternion.Normalize(Quaternion.CreateFromAxisAngle(axis, angle) * Rotation);
}

public virtual void Revolve(Vector3 target, Vector3 axis, float angle)
{
    Vector3 revolveAxis = Vector3.Transform(axis, Matrix.CreateFromQuaternion(Rotation));

    Quaternion rotate = Quaternion.Normalize(Quaternion.CreateFromAxisAngle(revolveAxis, angle));

    Position = Vector3.Transform(Position - target, Matrix.CreateFromQuaternion(rotate)) + target;

    Rotate(axis, angle);
}

My Block object creates 6 instances of Quad and calls the render method on each Quad object, I have offsets and rotations assigned on each Quad to form a textured Block looking like this: Block rendered by 6 Quad objects

And now we have the actual problem, calling Rotate on my Block object causes the object itself to change rotation, and my Quad objects does not rotate, thus I implemented a new Rotate function on my Block object.

public override void Rotate(Vector3 axis, float angle)
{
    for (int i = 0; i < mySides.Length; i++)
    {
        Quad side = mySides[i];
        side.Revolve(this.Position, axis, angle);
    }
}

This however did not give me the expected result as seen here:

Block object rotated

The wrong solution

The following solution will work but will not be very generic and will be limited: A bunch of if statements that checks on what axis i want to rotate around and then rotates every side (Quad object) the correct way.

The proper solution

Alternatively I could make the rendering of the Quad objects dependant on the Rotation of the Block object(their parent), but I am unsure on how to do this.

The third and last option is to have the Rotate method update each Quad objects rotation and position to the correct values, this I am unsure on how to do aswell.

The Question

So what i'm asking for is some ideas or thoughts on this, perhaps some links and/or tutorials explaining how to use Quaternions in XNA, preferably in a visual way.

Cheers, looking forward to your input :)

like image 463
thmsn Avatar asked Oct 25 '11 20:10

thmsn


1 Answers

What you should do, and you mentioned this, make the rendering of the Quad objects dependant on the rotation of the parent.

This is fairly easy to do with a hierachal system like yours. When your renderer goes to render the block, it should store the block's transformation in a matrix, let's call it BlockWorld. When you go to render each Quad, multiply the Quad's local transform by BlockWorld.

like image 109
Hannesh Avatar answered Oct 23 '22 20:10

Hannesh