Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm writing a small 3D renderer (using an orthographic projection right now).

I've run into some trouble with my 3D rotation matrices. They seem to squeeze my 3D object (a box primitive) at certain angles.

Here's a live demo (only tested in Google Chrome): http://dl.dropbox.com/u/109400107/3D/index.html

The box is viewed from the top along the Y axis and is rotating around the X and Z axis.

These are my 3 rotation matrices (Only rX and rZ are being used):

var rX = new Matrix([
        [1, 0, 0],
        [0, Math.cos(radiants), -Math.sin(radiants)],
        [0, Math.sin(radiants), Math.cos(radiants)]
    ]);

    var rY = new Matrix([
        [Math.cos(radiants), 0, Math.sin(radiants)],
        [0, 1, 0],
        [-Math.sin(radiants), 0, Math.cos(radiants)]
    ]);

    var rZ = new Matrix([
        [Math.cos(radiants), -Math.sin(radiants), 0],
        [Math.sin(radiants), Math.cos(radiants), 0],
        [0, 0, 1]
    ]);

Before projecting the verticies I multiply them by rZ and rX like so:

vert1.multiply(rZ);
vert1.multiply(rX);

vert2.multiply(rZ);
vert2.multiply(rX);

vert3.multiply(rZ);
vert3.multiply(rX);

The projection itself looks like this:

bX = (pos.x + (vert1.x*scale));
bY = (pos.y + (vert1.z*scale));

Where "pos.x" and "pos.y" is an offset for centering the box on the screen.

I just can't seem to find a solution to this and I'm still relativly new to working with Matricies.

You can view the source-code of the demo page if you want to see the whole thing.

share|improve this question
    
The "multiply" calls in your sample code look suspiciously like they are actually permanently changing the values in the vertices and accumulating those changes across frames over time. Is this true? –  Josh Petrie Oct 15 '12 at 23:02
    
Shouldn't you be using 4x4 matrices instead of 3x3? –  Gustavo Maciel Oct 15 '12 at 23:03
add comment

2 Answers

up vote 4 down vote accepted

The problem is in the vector/matrix multiplication code (Vector3.prototype.multiply):

    this.x = ((vector3.rows[0][0] * this.x) + (vector3.rows[0][1] * this.y) + (vector3.rows[0][2] * this.z));
    this.y = ((vector3.rows[1][0] * this.x) + (vector3.rows[1][1] * this.y) + (vector3.rows[1][2] * this.z));
    this.z = ((vector3.rows[2][0] * this.x) + (vector3.rows[2][1] * this.y) + (vector3.rows[2][2] * this.z));

You are modifying the this.x, and then using the modified value for subsequent multiplication! Multiply with the original vector values and then set the new values on the vector, eg:

            var new_x, new_y, new_z;
            new_x = ((vector3.rows[0][0] * this.x) + (vector3.rows[0][1] * this.y) + (vector3.rows[0][2] * this.z));
            new_y = ((vector3.rows[1][0] * this.x) + (vector3.rows[1][1] * this.y) + (vector3.rows[1][2] * this.z));
            new_z = ((vector3.rows[2][0] * this.x) + (vector3.rows[2][1] * this.y) + (vector3.rows[2][2] * this.z));
share|improve this answer
    
That was exactly it! It's such a silly mistake. –  Spiderhund Oct 16 '12 at 17:00
    
Thank you very much! Would probably never have spotted that :) –  Spiderhund Oct 16 '12 at 17:01
add comment

I think that you are doing multiplication out of order. I believe you first have to combine the matrices and only then perform the transform. Basically:

transform = rZ * rY;

and then:

vert1.multiply(transform);

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.