summaryrefslogtreecommitdiffstats
path: root/sdl/glframe.c
blob: b3dc33eb40f961f5971fe383d96f0bd249c2104a (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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* glframe.c
 *
 * Camera
 *
 * notes: we could make these functions to be inlined, but they would need
 * to be moved into a header
 *
 */

#include <GL/glew.h>
#include "glframe.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 camera 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 be passed in as a parameter */
	int rot_only = 0;
	
    M3DMatrix44f m;
    glframe_get_camera_orientation(frame, m);
    m3dPrintMatrix44f(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;
}

/* rotate left or right */
void glframe_rotate_local_y(GLFrame *frame, float angle)
{
    M3DMatrix44f rotmat;
    M3DVector3f newvect;

    /* just rotate around the up vector */
    /* create a rotation matrix around up vector */
    m3dRotationMatrix44f(rotmat, angle, frame->v_up[0], frame->v_up[1], frame->v_up[2]);

    /* 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);
}

/* rotate up or down */
void glframe_rotate_local_x(GLFrame *frame, float angle)
{
    M3DMatrix44f rotmat;
    M3DVector3f newfwdvec;
    M3DVector3f newupvec;
    M3DVector3f x, z;

    /* 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);

    /* create a rotation matrix around x axis */
    m3dRotationMatrix44f(rotmat, angle, x[0], x[1], x[2]);

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

    /* calculate new up vector */
    m3dCrossProductf(newupvec, x, newfwdvec);

    m3dCopyVector3f(frame->v_forward, newfwdvec);
    m3dCopyVector3f(frame->v_up, newupvec);
}