Newer
Older
cg / sources / animation.cpp
#include "animation.h"

#ifndef UNIX
#include <SDL.h>        // This file import the SDL inteface
#else
#include <SDL/SDL.h>    // This file import the SDL inteface
#endif

#ifndef PI
#define PI                 3.14159265f
#endif

/* class Animation */

Animation::Animation() {
}

void Animation::tick() {
}

void Animation::init() {
}

/* class UserAnimation */

UserAnimation::UserAnimation() {
	current = -1;
}

UserAnimation::UserAnimation(Thing* ths) {
	things.push_back(ths);
	current = 0;
}

UserAnimation::UserAnimation(std::vector<Thing*> ths) {
	things = ths;
	current = 0;
}

void UserAnimation::init() {
	speed = 1.0f;
	current = -1;
	kbdlock = 0;
	mouseX = 0;
	mouseY = 0;
	delta = 0.0f;
	trace = false;
	showNormals = false;
	showMe = true;
	iterations = 0;
}

void UserAnimation::tick() {
#ifdef DEBUG
	int oldcurrent = current;
#endif
	/* get mouse */
	int newmouseX;
	int newmouseY;
	unsigned mouseButtons = SDL_GetMouseState(&newmouseX, &newmouseY);

	if ( mouseButtons & SDL_BUTTON(1) ) { }
	if ( mouseButtons & SDL_BUTTON(3) ) { }

	if ( newmouseX != mouseX || newmouseY != mouseY ) {
		Vec v = Vec(speed*0.1f*(newmouseY-mouseY), speed*0.1f*(newmouseX-mouseX), 0.0f);
		things.at(current)->rotate(v);
		mouseX = newmouseX;
		mouseY = newmouseY;
	}


	/* get keyboard */
	if ( kbdlock > 0 ) {
		kbdlock--;
	} else {
		Uint8 *kbd = SDL_GetKeyState(NULL);

		/* object selection */
		if ( kbd[SDLK_0] ) { current = 0; }
		if ( kbd[SDLK_1] ) { current = 1; }
		if ( kbd[SDLK_2] ) { current = 2; }
		if ( kbd[SDLK_3] ) { current = 3; }
		if ( kbd[SDLK_4] ) { current = 4; }
		if ( kbd[SDLK_5] ) { current = 5; }
		if ( kbd[SDLK_6] ) { current = 6; }
		if ( kbd[SDLK_7] ) { current = 7; }
		if ( kbd[SDLK_8] ) { current = 8; }
		if ( kbd[SDLK_9] ) { current = 9; }

		if ( kbd[SDLK_RIGHT] ) { current++; kbdlock = 20; }
		if ( kbd[SDLK_LEFT] ) { current--; kbdlock = 20; }

		if ( things.size() > 0 ) {
			if ( current < 0 ) {
				current = 0;
			} else {
				current = current % things.size();
			}
		} else {
			current = -1;
		}

#ifdef DEBUG
		if ( current != oldcurrent ) {
			printf("Switched to object %d\n", current);
		}
#endif

		/* speed */
		if ( kbd[SDLK_LSHIFT] || kbd[SDLK_RSHIFT] ) {
			speed = 10.0f;
		} else {
			if ( kbd[SDLK_LCTRL] || kbd[SDLK_RCTRL] ) {
				speed = 0.1f;
			} else {
				speed = 1.0f;
			}
		}

		/* only do operations if we have a current object */
		if ( current > -1 && current < (int)things.size() ) {
			/* move x */
			if ( kbd[SDLK_a] ) { things.at(current)->translate(Vec(1.0f*speed, 0.0f, 0.0f)); }
			if ( kbd[SDLK_d] ) { things.at(current)->translate(Vec(-1.0f*speed, 0.0f, 0.0f)); }
			/* move y */
			if ( kbd[SDLK_UP] ) { things.at(current)->translate(Vec(0.0f, -1.0f*speed, 0.0f)); }
			if ( kbd[SDLK_DOWN] ) { things.at(current)->translate(Vec(0.0f, 1.0f*speed, 0.0f)); }
			/* move z */
			if ( kbd[SDLK_w] ) { things.at(current)->translate(Vec(0.0f, 0.0f, 1.0f*speed)); }
			if ( kbd[SDLK_s] ) { things.at(current)->translate(Vec(0.0f, 0.0f, -1.0f*speed)); }

			/* rotate x */
			if ( kbd[SDLK_c] ) { things.at(current)->rotate(Vec(1.0f*speed, 0.0f, 0.0f)); }
			if ( kbd[SDLK_f] ) { things.at(current)->rotate(Vec(-1.0f*speed, 0.0f, 0.0f)); }

			/* rotate y */
			if ( kbd[SDLK_b] ) { things.at(current)->rotate(Vec(0.0f, 1.0f*speed, 0.0f)); }
			if ( kbd[SDLK_v] ) { things.at(current)->rotate(Vec(0.0f, -1.0f*speed, 0.0f)); }

			/* rotate z */
			if ( kbd[SDLK_q] ) { things.at(current)->rotate(Vec(0.0f, 0.0f, 1.0f*speed)); }
			if ( kbd[SDLK_e] ) { things.at(current)->rotate(Vec(0.0f, 0.0f, -1.0f*speed)); }

			/* scaling */
			if ( kbd[SDLK_x] ) { things.at(current)->scale(1.01f*speed); printf("anim scale: %f\n", 1.01f*speed); }
			if ( kbd[SDLK_y] ) { things.at(current)->scale(0.99f*speed); printf("anim scale: %f\n", 0.99f*speed); }

			/* cycle color */
			if ( kbd[SDLK_PERIOD] || kbd[SDLK_COMMA] ) {
				if ( kbd[SDLK_PERIOD] ) {
					colorpt--;
				} else {
					colorpt++;
				}

				if ( colors.size() > 0 ) {
					colorpt = colorpt % colors.size();
					things.at(current)->setColor(colors.at(colorpt));
					kbdlock = 20;
				}
			}
		
			/* normals */
			if ( kbd[SDLK_n] ) {
				if ( showNormals ) {
					things.at(current)->hideNormals();
					showNormals = false;
				} else {
					things.at(current)->showNormals();
					showNormals = true;
				}
				kbdlock = 20;
			}

			/* show/hide object */
			if ( kbd[SDLK_h] ) {
				if ( showMe ) {
					things.at(current)->hide();
				} else {
					things.at(current)->show();
				}
				showMe = !showMe;

				kbdlock = 20;
			}

			/* delta */
			if ( kbd[SDLK_m] ) { 
				if ( delta > 0.0f ) {
					if ( delta < PI/4.0f ) {
						delta = 0.0f;
					} else {
						delta = delta/2.0f;
					}
				} else {
					delta = PI;
				}
				things.at(current)->setDelta(delta);
				kbdlock = 20;
			}

			/* fractal iterations */
			if ( kbd[SDLK_i] ) {

				iterations = iterations % 5;

				iterations++;

				things.at(current)->setIterations(iterations);

				kbdlock = 20;
			}

			/* trace */
			if ( kbd[SDLK_t] ) { things.at(current)->trace(trace); trace = !trace; kbdlock = 20; }
		}
	}
}

void UserAnimation::addThing(Thing* t) {
	things.push_back(t);
	if ( current < 0 ) { current = 0; }
}

void UserAnimation::addColor(Color* c) {
	colors.push_back(c);
	if ( colorpt < 0 ) { colorpt = 0; }
}

UserAnimation::~UserAnimation ( ) { }

/* class StaticAnimation */

StaticAnimation::StaticAnimation ( ) {
}

StaticAnimation::StaticAnimation ( Thing* t ) {
	this->addThing(t);
}

void StaticAnimation::init ( ) {
	speed = 1.0f;
	rot_diff = new Vec(0,0,0);
	pos_diff = new Vec(0,0,0);
	amb_diff = new Vec(0,0,0);
	spec_diff = new Vec(0,0,0);
}

void StaticAnimation::addThing ( Thing* t ) {
	things.push_back(t);
}

void StaticAnimation::tick ( ) {
	if ( things.size() > 0 ) {
		for ( std::vector<Thing*>::size_type i = 0; i < things.size(); i++ ) {
			things.at(i)->translate(*pos_diff*speed);
			things.at(i)->rotate(*rot_diff*speed);
			// TODO change color
		}
	}
}

void StaticAnimation::setSpeed ( float s ) {
	speed = s;
}

void StaticAnimation::setRot ( Vec r ) {
	rot_diff = r.clone();
}

void StaticAnimation::setPos ( Vec p ) {
	pos_diff = p.clone();
}

StaticAnimation::~StaticAnimation ( ) {
	delete rot_diff;
	delete pos_diff;
	delete amb_diff;
	delete spec_diff;
}