world_of_cow/cow.c

131 lines
3.8 KiB
C

#include <GL/freeglut_std.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include "cow.h"
#include "vec.h"
#include <math.h>
#include <stdio.h>
vec3 headRot = { -30.0, 0.0, 0.0 };
const vec3 headLimit = { 90.0, 90.0 ,90.0 };
vec3 cowPos = { 0.0, 6.0, 0.0 };
float cowRot = 0.0; // rotation along the Y axis
const float COW_ROT_SPEED = 5.0;
const float COW_MOVE_SPEED = 1.0;
enum COW_CONTROL control;
float deg2rad(float deg) {
return deg * 3.14 / 180.0;
}
float addAndWrapRot(float rot, float add) {
rot += add;
if(rot > 180.0) { rot -= 360.0; }
else if(rot < -180.0) { rot += 360.0; }
return rot;
}
void cowMove(char c) {
// check for rotations
cowRot = addAndWrapRot(cowRot, ((c == 'e') - (c == 'q')) * COW_ROT_SPEED);
// movement
vec3 dir = vec3_new((c == 'a') - (c == 'd'), 0.0, (c == 'w') - (c == 's'));
vec3 r = vec3_splat(0.0);
float rot = -deg2rad(cowRot);
r.z = cosf(rot) * dir.z + sinf(rot) * dir.x;
r.x = -sinf(rot) * dir.z + cosf(rot) * dir.x;
cowPos = vec3_add(cowPos, vec3_mult(r, COW_MOVE_SPEED));
glutPostRedisplay();
}
void cowHead(char c) {
headRot.z = addAndWrapRot(headRot.z, ((c == 'e') - (c == 'q')) * COW_ROT_SPEED);
headRot.y = addAndWrapRot(headRot.y, ((c == 'a') - (c == 'd')) * COW_ROT_SPEED);
headRot.x = addAndWrapRot(headRot.x, ((c == 's') - (c == 'w')) * COW_ROT_SPEED);
glutPostRedisplay();
}
void drawCow(char cowsPOV) {
glMatrixMode(GL_MODELVIEW);
glEnable(GL_COLOR_MATERIAL);
glPushMatrix(); // cow pos
// Main cow position - as center of cow body
glTranslatef(cowPos.x, cowPos.y, cowPos.z);
glRotatef(cowRot, 0.0, 1.0, 0.0);
// Draw cow body
glPushMatrix(); // cow body scale
glColor3f(0.8,0.4,0.11);
glScalef(1.0, 1.0, 1.5);
glutSolidSphere(4.0, 16, 16);
glPopMatrix(); // cow body scale
if(!cowsPOV) {
// head
glPushMatrix(); // head center
glTranslatef(0.0, 1.0, 5.0);
glRotatef(headRot.y, 0.0, 1.0, 0.0);
glRotatef(headRot.x, 1.0, 0.0, 0.0);
glTranslatef(0.0, 0.0, 1.0);
glRotatef(headRot.z, 0.0, 0.0 ,1.0);
glutSolidSphere(2.0, 16, 16);
vec3 ePos = vec3_new(0.7, 0.8, 1.3);
vec3 pPos = vec3_new(0.0, 0.2, 0.5);
glPushMatrix(); // eye 1
glTranslatef(ePos.x, ePos.y, ePos.z);
glColor3f(1.0, 1.0, 1.0);
glutSolidSphere(0.5, 8, 8);
glPushMatrix(); // pupil 1
glTranslatef(pPos.x, pPos.y, pPos.z);
glColor3f(0.0, 0.0, 0.0);
glutSolidSphere(0.1, 8, 8);
glPopMatrix(); // pupil 1
glPopMatrix(); // eye 1
glPushMatrix(); // eye 2
glTranslatef(-ePos.x, ePos.y, ePos.z);
glColor3f(1.0, 1.0, 1.0);
glutSolidSphere(0.5, 8, 8);
glPushMatrix(); // pupil 2
glTranslatef(pPos.x, pPos.y, pPos.z);
glColor3f(0.0, 0.0, 0.0);
glutSolidSphere(0.1, 8, 8);
glPopMatrix(); // pupil 2
glPopMatrix(); // eye 2
glPopMatrix(); // head center
}
glPopMatrix(); // cow pos
glColor3f(1.0, 1.0, 1.0);
glDisable(GL_COLOR_MATERIAL);
}
void onCowKeyboardInput(char key) {
switch(control) {
case COW_CONTROL_MOVE:
cowMove(key);
break;
case COW_CONTROL_HEAD:
cowHead(key);
default:
break;
}
}
void updateCowControl(enum COW_CONTROL c) {
control = c;
}
void setCameraToCowPOV() {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// rotate to look at Z+
glRotatef(180.0, 0.0, 1.0, 0.0);
// head
glRotatef(-headRot.z, 0.0, 0.0 ,1.0);
glTranslatef(0.0, 0.0, -1.0);
glRotatef(-headRot.x, 1.0, 0.0, 0.0);
glRotatef(-headRot.y, 0.0, 1.0, 0.0);
glTranslatef(0.0, 0.0, -5.0);
// body
glTranslatef(-cowPos.x, -cowPos.y, -cowPos.z);
glRotatef(-cowRot, 0.0, 1.0, 0.0);
}