summaryrefslogtreecommitdiffstats
path: root/sdl/glframe.c
blob: b8b45d911b15cd075ecf5da5ae4ff7a1bf8c3ec9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* glframe.c
 *
 * Camera
 *
 * notes: we could make these functions to be inlined, but they would need
 * to be moved into a header
 *
 */

#include "glframe.h"
#include "math3d.h"

void glframe_reset(GLFrame *frame)
{
	frame->v_location[0] = 0.0f;
	frame->v_location[1] = 0.0f;
	frame->v_location[2] = 0.0f;
	
	frame->v_forward[0] = 0.0f;
	frame->v_forward[1] = 0.0f;
	frame->v_forward[2] = -1.0f;
	
	frame->v_up[0] = 0.0f;
	frame->v_up[1] = 1.0f;
	frame->v_up[2] = 0.0f;
}

/* get a 4x4 transformation matrix that describes the ccamera orientation */
void glframe_get_camera_orientation(GLFrame *frame, M3DMatrix44f m)
{
    M3DVector3f x, z;

    /* make rotation matrix, z vector is reversed */
    z[0] = -frame->v_forward[0];
    z[1] = -frame->v_forward[1];
    z[2] = -frame->v_forward[2];

    /* x vector = y cross z */ 
    m3dCrossProductf(x, frame->v_up, z);

    /* matrix has no translation information and is transposed */
    #define M(row,col)  m[col*4+row]
    M(0, 0) = x[0];
    M(0, 1) = x[1];
    M(0, 2) = x[2];
    M(0, 3) = 0.0;
    M(1, 0) = frame->v_up[0];
    M(1, 1) = frame->v_up[1];
    M(1, 2) = frame->v_up[2];
    M(1, 3) = 0.0;
    M(2, 0) = z[0];
    M(2, 1) = z[1];
    M(2, 2) = z[2];
    M(2, 3) = 0.0;
    M(3, 0) = 0.0;
    M(3, 1) = 0.0;
    M(3, 2) = 0.0;
    M(3, 3) = 1.0;
    #undef M 
}

/* perform viewing or modeling transformations */
/* some of the code is unimplemented */     
void glframe_apply_camera_transform(GLFrame *frame)    
{
	/* XXX: rotation only, should passed in as a parameter */
	int rot_only = 0;
	
    M3DMatrix44f m;
    glframe_get_camera_orientation(frame, m);  
    glMultMatrixf(m);

    /* if Rotation only, then do not do the translation */
    if (!rot_only)
        glTranslatef(-frame->v_location[0], -frame->v_location[1], -frame->v_location[2]);
        
#if 0
    gluLookAt(v_location[0], v_location[1], v_location[2],
                v_location[0] + v_forward[0], 
                v_location[1] + v_forward[1], 
                v_location[2] + v_forward[2], 
                v_up[0], v_up[1], v_up[2]);
#endif                
}

void glframe_move_forward(GLFrame *frame, float delta)
{
    // Move along direction of front direction
    frame->v_location[0] += frame->v_forward[0] * delta;
    frame->v_location[1] += frame->v_forward[1] * delta;
    frame->v_location[2] += frame->v_forward[2] * delta;
}

void glframe_rotate_local_y(GLFrame *frame, float angle)
{
    M3DMatrix44f rotMat;

    /* just Rotate around the up vector */
    /* create a rotation matrix around my Up (Y) vector */
    m3dRotationMatrix44f(rotMat, angle, frame->v_up[0], frame->v_up[1], frame->v_up[2]);

    M3DVector3f newVect;

    /* rotate forward pointing vector (inlined 3x3 transform) */
    newVect[0] = rotMat[0] * frame->v_forward[0] + rotMat[4] * frame->v_forward[1] + rotMat[8] *  frame->v_forward[2];    
    newVect[1] = rotMat[1] * frame->v_forward[0] + rotMat[5] * frame->v_forward[1] + rotMat[9] *  frame->v_forward[2];    
    newVect[2] = rotMat[2] * frame->v_forward[0] + rotMat[6] * frame->v_forward[1] + rotMat[10] * frame->v_forward[2];    
    m3dCopyVector3f(frame->v_forward, newVect);
}