OBJ Loader

Neue Quaternionklasse
header in emath fuer punkt3d rausgenommen
This commit is contained in:
Sebastian 2008-06-17 02:46:39 +02:00
parent 026961a7a6
commit 1c613ca59c
30 changed files with 853 additions and 87 deletions

View File

@ -1,9 +1,9 @@
CC = g++ CC = g++
AR = ar AR = ar
OBJECTS = punkt3d.o punkt2d.o emath.o emath_opengl.o glcolor.o gldrawhelper.o glfontengine.o glrect.o gltexture.o matrix.o quaternion.o rotationsmatrix.o glsdlscreen.o sdlfuncs.o fpsmanager.o glcamera.o catmullromspline.o OBJECTS = punkt3d.o punkt2d.o emath.o emath_opengl.o glcolor.o gldrawhelper.o glfontengine.o glrect.o gltexture.o matrix.o quaternion.o rotationsmatrix.o glsdlscreen.o sdlfuncs.o fpsmanager.o glcamera.o catmullromspline.o extstring.o
OBJOPT = -Wall -c `sdl-config --cflags` OBJOPT = -Wall -c `sdl-config --cflags`
SUBDIRS = glgui glmenu models SUBDIRS = glgui glmenu model
SUBDIROBJECTS = glgui/*.o glmenu/*.o models/*.o SUBDIROBJECTS = glgui/*.o glmenu/*.o model/*.o
VERSION = 0.0.1 VERSION = 0.0.1
LIBNAME = libsegl LIBNAME = libsegl

View File

@ -27,7 +27,6 @@ float ssin(float c) {
case 270: case 270:
return -1.0f; return -1.0f;
default: default:
// std::cout << "ssin sollte keinen defaultwert zurückliefern. c=" << c << ", t=" << t << std::endl;
return sin(deg2rad(c)); return sin(deg2rad(c));
} }
} }

View File

@ -5,7 +5,6 @@
#include <cmath> #include <cmath>
#include <SDL_opengl.h> #include <SDL_opengl.h>
#include "punkt3d.h" /* aus kompatibilitätsgründen */
float deg2rad(float deg); float deg2rad(float deg);
float rad2deg(float rad); float rad2deg(float rad);

View File

@ -2,6 +2,7 @@
#define __EMATH_OPENGL #define __EMATH_OPENGL
#include <cmath> #include <cmath>
#include "punkt3d.h"
#include "emath.h" #include "emath.h"
#include "rotationsmatrix.h" #include "rotationsmatrix.h"
#include <SDL_opengl.h> #include <SDL_opengl.h>

47
extstring.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "extstring.h"
int explode(std::string str, std::string delim, std::vector<std::string> *erg, bool clean) {
erg->clear();
int treffer=0;
std::string tmp;
unsigned int pos;
while((pos = str.find(delim))!=std::string::npos) {
tmp = str.substr(0, pos);
if(!clean || tmp!="") {
// tmp nicht leer, hinzufügen
erg->push_back(tmp);
treffer++;
}
str = str.substr(pos+1); // alten kram entfernen
}
if(str.length()>0) {
treffer++;
erg->push_back(str);
}
return treffer;
}
std::string trim(std::string t) {
while(t.length() && isspace(t[0])) {
t = t.substr(1);
}
while(t.length() && ( isspace(t[t.length()-1]) )) {
t = t.substr(0, t.length()-2);
}
return t;
}
std::string basename(std::string str) {
return str.substr( str.rfind("/"));
}
std::string rbasename(std::string str) {
return str.substr(0, str.rfind("/")+1);
}

12
extstring.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef __EXTSTRING_H
#define __EXTSTRING_H
#include <string>
#include <vector>
int explode(std::string str, std::string delim, std::vector<std::string> *erg, bool clean=false);
std::string trim(std::string t);
std::string basename(std::string str);
std::string rbasename(std::string str);
#endif

View File

@ -100,7 +100,7 @@ void GLCamera::rotateUp(float sec) {
rotmatX.set(rotx); rotmatX.set(rotx);
doupdate = true; doupdate = true;
} else { } else {
//std::cout << "zu groß" << std::endl; //std::cout << "zu gro<EFBFBD>" << std::endl;
} }
// rotmat.set(dir.kreuzprodukt(norm), -apersec*sec); // rotmat.set(dir.kreuzprodukt(norm), -apersec*sec);
// norm = rotmat * norm; // norm = rotmat * norm;
@ -122,6 +122,27 @@ void GLCamera::rotateDown(float sec) {
// dir.normalize(); // dir.normalize();
} }
void GLCamera::handleKeys(float sec) {
Uint8 *keys = SDL_GetKeyState(NULL);
if(keys[SDLK_w])
moveForward(sec);
if(keys[SDLK_s])
moveBackward(sec);
if(keys[SDLK_UP])
rotateUp(sec);
if(keys[SDLK_DOWN])
rotateDown(sec);
if(keys[SDLK_LEFT])
rotateLeft(sec);
if(keys[SDLK_RIGHT])
rotateRight(sec);
if(keys[SDLK_a])
moveLeft(sec);
if(keys[SDLK_d])
moveRight(sec);
}
float GLCamera::getXrot() { float GLCamera::getXrot() {
return rotx; return rotx;
} }

View File

@ -44,6 +44,8 @@ class GLCamera {
void rotateUp(float sec); void rotateUp(float sec);
void rotateDown(float sec); void rotateDown(float sec);
void handleKeys(float sec);
float getXrot(); float getXrot();
float getYrot(); float getYrot();

View File

@ -4,6 +4,7 @@
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include "punkt3d.h"
#include "emath.h" #include "emath.h"
class Matrix { class Matrix {

13
model/Makefile Executable file
View File

@ -0,0 +1,13 @@
CC = g++
OBJOPT = -c `sdl-config --cflags` -Wall
OBJECTS = model.o modelloader.o loadobj.o
glguilib: $(OBJECTS)
# rm glgui.a -f
ar crus glmenu.a $(OBJECTS)
%.o: %.cpp %.h
$(CC) $(OBJOPT) $<
clean:
rm -f $(OBJECTS)

235
model/loadobj.cpp Normal file
View File

@ -0,0 +1,235 @@
#include "loadobj.h"
LoadOBJ::LoadOBJ(std::string _filename) : Modelloader(_filename) {
}
bool LoadOBJ::load(Model *m) {
// Filestreams
std::ifstream file(filename.c_str());
std::ifstream matfile;
std::string inbuf; // TMP-Var
std::vector<std::string> v;
std::vector<std::string> v2;
int anz;
unsigned int vertanz=0, polyanz=0, matanz=0, texanz=0, normanz=0;
std::string materials;
// Punkt2D *texdata = 0;
// texdataanz = 0;
// Punkt3D *normdata = 0;
// normdata = 0;
Material *usemat;
if(!file)
return false;
// start counting items, read file
while(getline(file, inbuf)) {
anz = explode(inbuf, " ", &v);
if(!anz)
continue;
if(v[0]=="f")
polyanz++; // polygon
else if(v[0]=="v")
vertanz++; // vertex
else if(v[0]=="mtllib") {
if(anz>1)
materials = trim(v[1]);
// std::cout << "V1: " << v[1] << std::endl;
} else if(v[0]=="vt")
texanz++; // texcoord
else if(v[0]=="vn")
normanz++; // normal
}
if(materials!="") {
matfile.open((rbasename(filename)+materials).c_str());
if(matfile) {
while(getline(matfile, inbuf)) {
anz = explode(inbuf, " ", &v);
if(!anz)
continue;
if(v[0]=="newmtl")
matanz++;
}
}
}
// std::cout << "Vert: " << vertanz << " Poly: " << polyanz << " Mat: " << matanz << " (Matfile: " << materials << ") Norm: " << normanz << std::endl;
if(!vertanz || !polyanz)
return false;
if(m->isLoaded())
m->unload();
// Allocate memory for filecontent
m->meshdataanz = vertanz;
m->meshdata = new Punkt3D[vertanz];
m->polydataanz = polyanz;
m->polydata = new Meshpolygon[polyanz];
if(matanz) {
m->matdataanz = matanz;
m->matdata = new Material[matanz];
}
m->texdataanz = texanz;
m->texdata = new Punkt2D[matanz];
m->normdataanz = normanz;
m->normdata = new Punkt3D[normanz];
// Readout Material
matfile.clear();
matfile.seekg(0);
if(matanz&&matfile) { // Got milk.. eh.. material?
matanz = 0;
Material mat;
while(getline(matfile, inbuf)) {
anz = explode(inbuf, " ", &v);
if(!anz)
continue;
if(v[0]=="newmtl") {
if(matanz!=0)
m->matdata[matanz-1] = mat; // Push material
matanz++;
mat = Material();
mat.name = trim(v[1]);
} else if(v[0]=="Ka") {
if(anz<4)
continue;
mat.ambient.set(std::atof(v[1].c_str()), std::atof(v[2].c_str()), std::atof(v[3].c_str()));
} else if(v[0]=="Kd") {
if(anz<4)
continue;
mat.diffuse.set(std::atof(v[1].c_str()), std::atof(v[2].c_str()), std::atof(v[3].c_str()));
} else if(v[0]=="Ks") {
if(anz<4)
continue;
mat.specular.set(std::atof(v[1].c_str()), std::atof(v[2].c_str()), std::atof(v[3].c_str()));
}
}
// Last material wasnt pushed
if(matanz!=0)
m->matdata[matanz-1] = mat;
}
// Readout File
usemat = &(m->backupmat); // If material required but not avilable use backup
file.clear();
file.seekg(0);
polyanz = vertanz = normanz = texanz = 0; // Reset counters
while(getline(file, inbuf)) {
anz = explode(inbuf, " ", &v);
if(!anz)
continue;
if(v[0]=="v") {
if(anz<4)
continue;
m->meshdata[vertanz].set(std::atof(v[1].c_str()), std::atof(v[2].c_str()), std::atof(v[3].c_str()));
vertanz++;
} else if(v[0]=="vn") {
if(anz<4)
continue;
m->normdata[normanz].set(std::atof(v[1].c_str()), std::atof(v[2].c_str()), std::atof(v[3].c_str()));
normanz++;
} else if(v[0]=="vt") {
if(anz<3)
continue;
m->texdata[texanz].set(std::atof(v[1].c_str()), std::atof(v[2].c_str()));
texanz++;
} else if(v[0]=="f") {
if(anz<4)
continue;
unsigned int arr[3][3] = { {0,0,0}, {0,0,0}, {0,0,0} };
for(unsigned int i=0; i<3; i++) {
int zanz = explode(v[i+1], "/", &v2);
// std::cout << "explode " << v[i+1] << " anz " << zanz << std::endl;
if(zanz<3) {
if(zanz==1)
arr[i][0] = std::atoi(v2[0].c_str());
continue;
}
arr[i][0] = std::atoi(v2[0].c_str());
arr[i][1] = std::atoi(v2[1].c_str());
arr[i][2] = std::atoi(v2[2].c_str());
// std::cout << "Loaded: " << arr[i][0] << " " << arr[i][1] << " " << arr[i][2] << " " << std::endl;
// std::cout << "From: " << v2[0] << " " << v2[1] << " " << v2[2] << " " << std::endl;
}
if(arr[0][0])
m->polydata[polyanz].m1.point = &(m->meshdata[arr[0][0]-1]);
if(arr[0][1])
m->polydata[polyanz].m1.tex = &(m->texdata[arr[0][1]-1]);
if(arr[0][2])
m->polydata[polyanz].m1.normal = &(m->normdata[arr[0][2]-1]);
if(arr[1][0])
m->polydata[polyanz].m2.point = &(m->meshdata[arr[1][0]-1]);
if(arr[1][1])
m->polydata[polyanz].m2.tex = &(m->texdata[arr[1][1]-1]);
if(arr[1][2])
m->polydata[polyanz].m2.normal = &(m->normdata[arr[1][2]-1]);
if(arr[2][0])
m->polydata[polyanz].m3.point = &(m->meshdata[arr[2][0]-1]);
if(arr[2][1])
m->polydata[polyanz].m3.tex = &(m->texdata[arr[2][1]-1]);
if(arr[2][2])
m->polydata[polyanz].m3.normal = &(m->normdata[arr[2][2]-1]);
// std::cout << "POLY " << polyanz << std::endl;
polyanz++;
} else if(v[0]=="usemtl") {
if(anz<2)
continue;
std::string fterm = trim(v[1]);
for(unsigned int i=0; i < m->matdataanz; i++) {
if(m->matdata[i].name==fterm) {
usemat = &(m->matdata[i]);
break;
}
}
}
v.clear();
}
// Calculate bounding box
float minx=m->meshdata[0].x, maxx=m->meshdata[0].x, miny=m->meshdata[0].y, maxy=m->meshdata[0].y, minz=m->meshdata[0].z, maxz=m->meshdata[0].z;
for(unsigned int i=0; i<m->meshdataanz; i++) {
minx = std::min(minx, m->meshdata[i].x);
maxx = std::max(maxx, m->meshdata[i].x);
miny = std::min(miny, m->meshdata[i].y);
maxy = std::max(maxy, m->meshdata[i].y);
minz = std::min(minz, m->meshdata[i].z);
maxz = std::max(maxz, m->meshdata[i].z);
}
std::cout << "(" << minx << ", " << maxx << ") " << "(" << miny << ", " << maxy << ") " << "(" << minz << ", " << maxz << ") " << std::endl;
m->boundingbox.d.set(minx, miny, minz);
m->boundingbox.a.set(minx, miny, maxz);
m->boundingbox.b.set(maxx, miny, maxz);
m->boundingbox.c.set(maxx, miny, minz);
m->boundingbox.h.set(minx, maxy, minz);
m->boundingbox.e.set(minx, maxy, maxz);
m->boundingbox.f.set(maxx, maxy, maxz);
m->boundingbox.g.set(maxx, maxy, minz);
m->boundingrad = std::max( std::abs(minx)+std::abs(maxx),
std::max( std::abs(miny)+std::abs(maxy),
std::abs(minz)+std::abs(maxz)));
m->loaded = true;
// std::cout << "Loaded!" << std::endl;
return true;
}

16
model/loadobj.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef __LOADOBJ_H
#define __LOADOBJ_H
#include "modelloader.h"
#include "model.h"
#include "../extstring.h"
class LoadOBJ : public Modelloader {
private:
public:
LoadOBJ(std::string _filename);
bool load(Model *m);
};
#endif

153
model/model.cpp Normal file
View File

@ -0,0 +1,153 @@
#include "model.h"
// Class Meshpoint
Meshpoint::Meshpoint() {
}
Meshpoint::Meshpoint(Punkt3D v, Punkt2D vt) {
set(v, vt);
}
void Meshpoint::set(Punkt3D v, Punkt2D vt) {
vertex = v;
texcoord = vt;
// normal = n;
}
void Meshpoint::use() {
glTexCoordP2D(texcoord);
// glNormalP3D(normal);
glVertexP3D(vertex);
}
// Class Material
Material::Material() {
name = "none";
ambient.set(1.0f, 1.0f, 1.0f);
diffuse.set(1.0f, 1.0f, 1.0f);
specular.set(1.0f, 1.0f, 1.0f);
}
Material::Material(std::string _name, GLColor _a, GLColor _d, GLColor _s) {
set(_name, _a, _d, _s);
}
void Material::set(std::string _name, GLColor _a, GLColor _d, GLColor _s) {
name = _name;
ambient = _a;
diffuse = _d;
specular = _s;
}
void Material::use() {
glColorGLC(diffuse);
}
// Polygonpoint
Polygonpoint::Polygonpoint() {
point = 0;
tex = 0;
normal = 0;
}
void Polygonpoint::use() {
if(normal)
glNormalP3D(*normal);
if(tex)
glTexCoordP2D(*tex);
if(point)
glVertexP3D(*point);
}
// Class Meshpolygon
Meshpolygon::Meshpolygon() {
a = b = c = 0;
}
Meshpolygon::Meshpolygon(Meshpoint *_a, Meshpoint *_b, Meshpoint *_c) {
set(_a, _b, _c);
}
void Meshpolygon::set(Meshpoint *_a, Meshpoint *_b, Meshpoint *_c) {
a = _a;
b = _b;
c = _c;
}
void Meshpolygon::render(GLenum mode) {
// if(!a || !b || !c)
// return;
glBegin(mode);
m1.use();
m2.use();
m3.use();
glEnd();
// std::cout << "Pos 1 " << *m1.point << std::endl;
// std::cout << "Pos 2 " << *m2.point << std::endl;
// std::cout << "Pos 3 " << *m3.point << std::endl;
}
// Class Model
Model::Model() {
meshdata = 0;
meshdataanz = 0;
matdata = 0;
matdataanz = 0;
polydata = 0;
polydataanz = 0;
texdata = 0;
texdataanz = 0;
normdata = 0;
normdataanz = 0;
loaded = false;
backupmat.diffuse.set(1.0f, 1.0f, 1.0f);
}
bool Model::isLoaded() {
return loaded;
}
void Model::unload() {
if(meshdata)
delete[](meshdata);
if(polydata)
delete[](polydata);
if(matdata)
delete[](matdata);
if(texdata)
delete[](texdata);
if(normdata)
delete[](normdata);
meshdataanz = polydataanz = matdataanz = texdataanz = normdataanz = 0;
meshdata = 0;
polydata = 0;
matdata = 0;
texdata = 0;
normdata = 0;
loaded = false;
}
void Model::render() {
if(!loaded) {
// std::cout << "Model not loaded" << std::endl;
return;
}
glPushMatrix();
// std::cout << " --- begin --- " << std::endl;
for(unsigned int i=0; i<polydataanz; i++) {
// glColor3f((float)i/polydataanz, 0.0f, 1.0f);
polydata[i].render(GL_LINE_LOOP);
}
glPopMatrix();
// std::cout << " --- end --- " << std::endl;
}
Model::~Model() {
unload();
}

89
model/model.h Normal file
View File

@ -0,0 +1,89 @@
#ifndef __MODEL_H
#define __MODEL_H
#include <iostream>
#include <SDL_opengl.h>
#include "../punkt3d.h"
#include "../punkt2d.h"
#include "../glcolor.h"
#include "../quader.h"
class Meshpoint {
public:
Meshpoint();
Meshpoint(Punkt3D v, Punkt2D vt);
void set(Punkt3D v, Punkt2D vt);
void use();
Punkt3D vertex;
Punkt2D texcoord;
};
class Material {
public:
Material();
Material(std::string _name, GLColor _a, GLColor _d, GLColor _s);
void set(std::string _name, GLColor _a, GLColor _d, GLColor _s);
void use();
std::string name;
GLColor ambient, diffuse, specular;
};
class Polygonpoint {
public:
Polygonpoint();
void use();
Punkt3D *point;
Punkt2D *tex;
Punkt3D *normal;
};
class Meshpolygon {
public:
Meshpolygon();
Meshpolygon(Meshpoint *a, Meshpoint *b, Meshpoint *c);
void set(Meshpoint *a, Meshpoint *b, Meshpoint *c);
void render(GLenum mode=GL_TRIANGLES);
Polygonpoint m1, m2, m3;
Meshpoint *a, *b, *c;
Material *mat;
};
class Model {
friend class Modelloader;
friend class LoadOBJ;
private:
bool loaded;
unsigned int meshdataanz;
unsigned int polydataanz;
unsigned int matdataanz;
unsigned int texdataanz;
unsigned int normdataanz;
Punkt3D *meshdata;
Meshpolygon *polydata;
Material *matdata;
Punkt2D *texdata;
Punkt3D *normdata;
Material backupmat;
Quader boundingbox;
float boundingrad;
public:
Model();
~Model();
bool isLoaded();
void unload();
void render();
Quader getBoundingBox() { return boundingbox; }
float getBoundingRadius() { return boundingrad; }
};
#endif

5
model/modelloader.cpp Normal file
View File

@ -0,0 +1,5 @@
#include "modelloader.h"
Modelloader::Modelloader(std::string _filename) {
filename = _filename;
}

17
model/modelloader.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef __MODELLOADER_H
#define __MODELLOADER_H
#include <string>
#include <fstream>
#include "model.h"
class Modelloader {
protected:
std::string filename;
public:
Modelloader(std::string _filename);
virtual bool load(Model *m)=0;
};
#endif

View File

@ -19,6 +19,9 @@ void Punkt2D::print(std::string coordname) {
std::cout << coordname << "Coord: (" << x << ", " << y << ")" << std::endl; std::cout << coordname << "Coord: (" << x << ", " << y << ")" << std::endl;
} }
float Punkt2D::abs() {
return sqrt(x*x + y*y);
}
Punkt2D Punkt2D::operator+(const Punkt2D &b) { Punkt2D Punkt2D::operator+(const Punkt2D &b) {
Punkt2D c; Punkt2D c;
@ -131,6 +134,11 @@ void glTexCoord2f(Punkt2D p) {
glTexCoord2f(p.x, p.y); glTexCoord2f(p.x, p.y);
} }
// float abs(Punkt2D p) { float abs(Punkt2D p) {
// return p.abs(); return p.abs();
// } }
// Fixed Headers
void glTexCoordP2D(Punkt2D p) {
glTexCoord2f(p.x, p.y);
}

View File

@ -14,6 +14,7 @@ class Punkt2D {
void set(float, float); void set(float, float);
void print(std::string=""); void print(std::string="");
float abs();
// Operatoren // Operatoren
Punkt2D operator+(const Punkt2D&); Punkt2D operator+(const Punkt2D&);
@ -45,6 +46,9 @@ class Punkt2D {
}; };
void glTexCoord2f(Punkt2D); void glTexCoord2f(Punkt2D);
// float abs(Punkt3D); float abs(Punkt2D);
// Fixed Headers
void glTexCoordP2D(Punkt2D p);
#endif #endif

View File

@ -205,7 +205,7 @@ float abs(Punkt3D p) {
return p.abs(); return p.abs();
} }
// OpenGL Funktionen für Punkt3D // OpenGL Funktionen f<EFBFBD>r Punkt3D
void glVertex3f(Punkt3D p) { void glVertex3f(Punkt3D p) {
glVertex3f(p.x, p.y, p.z); glVertex3f(p.x, p.y, p.z);
@ -239,3 +239,9 @@ void glNormalP3D(Punkt3D p) {
void glRotateP3D(float deg, Punkt3D vec) { void glRotateP3D(float deg, Punkt3D vec) {
glRotatef(deg, vec.x, vec.y, vec.z); glRotatef(deg, vec.x, vec.y, vec.z);
} }
void gluLookAt(Punkt3D pos, Punkt3D viewport, Punkt3D normal) {
gluLookAt( pos.x, pos.y, pos.z,
viewport.x, viewport.y, viewport.z,
normal.x, normal.y, normal.z );
}

View File

@ -57,7 +57,7 @@ class Punkt3D {
float abs(Punkt3D); float abs(Punkt3D);
// OpenGL-Funktionen für Punkt3D // OpenGL-Functions for Punkt3D
void glVertex3f(Punkt3D); void glVertex3f(Punkt3D);
void glTranslatef(Punkt3D); void glTranslatef(Punkt3D);
@ -71,6 +71,6 @@ void glTranslateP3D(Punkt3D);
void glNormalP3D(Punkt3D); void glNormalP3D(Punkt3D);
void glRotateP3D(float, Punkt3D); void glRotateP3D(float, Punkt3D);
void gluLookAt(Punkt3D pos, Punkt3D viewport, Punkt3D normal);
#endif #endif

10
quader.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "quader.h"
void Quader::clean() {
a.set(0.0f, 0.0f, 0.0f);
b = c = d = e = f = g = h = a;
}
void Quader::render() {
glB
}

15
quader.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef __QUADER_H
#define __QUADER_H
#include <SDL_opengl.h>
#include "punkt3d.h"
class Quader {
public:
Punkt3D a, b, c, d, e, f, g, h;
void clean();
void render();
};
#endif

View File

@ -1,77 +1,165 @@
#include "quaternion.h" #include "quaternion.h"
Quaternion::Quaternion() { Quaternion::Quaternion() {
w = 1.0f; w = 1.0f,
x = y = z = 0.0f; x = y = z = 0.0f;
} }
void Quaternion::createFromRotation(float deg, float _x, float _y, float _z) { Quaternion::Quaternion(float _x, float _y, float _z, float _w) {
float tmpres = sin(deg2rad(deg) / 2.0f); x = _x;
y = _y;
z = _z;
w = _w;
}
w = cos(deg2rad(deg) / 2.0f); Quaternion::Quaternion(float deg, Punkt3D p) {
x = _x * tmpres; set(deg, p);
y = _y * tmpres; }
z = _z * tmpres;
Quaternion::Quaternion(float _x, float _y, float _z) {
set(_x, _y, _z);
}
void Quaternion::set(float rotx, float roty, float rotz) {
rotx = deg2rad(rotx);
roty = deg2rad(roty);
rotz = deg2rad(rotz);
float sinx = sin(rotx);
float siny = sin(roty);
float sinz = sin(rotz);
float cosx = cos(rotx);
float cosy = cos(roty);
float cosz = cos(rotz);
x = sinz * cosx * cosy - cosz * sinx * siny;
y = cosz * sinx * cosy + sinz * cosx * siny;
z = cosz * cosx * siny - sinz * sinx * cosy;
w = cosz * cosx * cosy - sinz * sinx * siny;
normalize();
}
void Quaternion::set(float deg, Punkt3D p) {
float angle = deg2rad(0.5f*deg);
float sinangle = sin(angle);
x = p.x * sinangle;
y = p.y * sinangle;
z = p.z * sinangle;
w = cos(angle);
normalize();
}
void Quaternion::normalize() {
float len = x*x+y*y+z*z+w*w;
if(std::fabs(len-1.0f)>0.00001f) {
len = sqrt(len);
x /= len;
y /= len;
z /= len;
w /= len;
}
}
Quaternion Quaternion::getConjugate() {
return Quaternion(-x, -y, -z, w);
}
// Rotationsmatrix Quaternion::getRotMat() {
//
// }
Punkt3D Quaternion::rotP3D(const Punkt3D &p) {
Quaternion q(p.x, p.y, p.z, 0.0f);
Quaternion erg = *this * q * this->getConjugate();
return Punkt3D(erg.x, erg.y, erg.z);
} }
Quaternion Quaternion::operator*(const Quaternion &q) { Quaternion Quaternion::operator*(const Quaternion &q) {
Quaternion ret; return Quaternion(w*q.x - x*q.w + y*q.z - z*q.y,
w*q.y - y*q.w + z*q.x - x*q.z,
ret.w = w*q.w - x*q.x - y*q.y - z*q.z; w*q.z - z*q.w + x*q.y - y*q.x,
ret.x = w*q.x + x*q.w + y*q.z - z*q.y; w*q.w - x*q.x - y*q.y - z*q.z);
ret.y = w*q.y + y*q.w + z*q.x - x*q.z;
ret.z = w*q.z + z*q.w + x*q.y - y*q.x;
return ret;
} }
void Quaternion::createGlMatrix(GLfloat *matrix) {
if(!matrix)
return;
matrix[0] = 1.0f - 2.0f * ( y*y + z*z);
matrix[1] = 2.0f * ( x*y + z*w);
matrix[2] = 2.0f * ( x*z - y*w);
matrix[3] = 0.0f;
matrix[4] = 2.0f * ( x*y - z*w); // Quaternion::Quaternion() {
matrix[5] = 1.0f - 2.0f * ( x*x + z*z); // w = 1.0f;
matrix[6] = 2.0f * ( z*y + x*w); // x = y = z = 0.0f;
matrix[7] = 0.0f; // }
//
matrix[8] = 2.0f * ( x*z + y*w); // void Quaternion::createFromRotation(float deg, float _x, float _y, float _z) {
matrix[9] = 2.0f * ( y*z - x*w); // float tmpres = sin(deg2rad(deg) / 2.0f);
matrix[10] = 1.0f - 2.0f * ( x*x + y*y); //
matrix[11] = 0.0f; // w = cos(deg2rad(deg) / 2.0f);
// x = _x * tmpres;
matrix[12] = 0.0f; // y = _y * tmpres;
matrix[13] = 0.0f; // z = _z * tmpres;
matrix[14] = 0.0f; // }
matrix[15] = 1.0f; //
// Quaternion Quaternion::operator*(const Quaternion &q) {
} // Quaternion ret;
//
Punkt3D Quaternion::getDirectionVector() { // ret.w = w*q.w - x*q.x - y*q.y - z*q.z;
GLfloat matrix[16]; // ret.x = w*q.x + x*q.w + y*q.z - z*q.y;
createGlMatrix(matrix); // ret.y = w*q.y + y*q.w + z*q.x - x*q.z;
// ret.z = w*q.z + z*q.w + x*q.y - y*q.x;
return getDirectionVector(matrix); //
} // return ret;
// }
Punkt3D Quaternion::getDirectionVector(GLfloat *matrix) { //
if(!matrix) // void Quaternion::createGlMatrix(GLfloat *matrix) {
return Punkt3D(); // if(!matrix)
Punkt3D tmp; // return;
//
tmp.x = matrix[8]; // matrix[0] = 1.0f - 2.0f * ( y*y + z*z);
tmp.y = matrix[9]; // matrix[1] = 2.0f * ( x*y + z*w);
tmp.z = matrix[10]; // matrix[2] = 2.0f * ( x*z - y*w);
// matrix[3] = 0.0f;
return tmp; //
} // matrix[4] = 2.0f * ( x*y - z*w);
// matrix[5] = 1.0f - 2.0f * ( x*x + z*z);
void glMultMatrixf(Quaternion q) { // matrix[6] = 2.0f * ( z*y + x*w);
GLfloat matrix[16]; // matrix[7] = 0.0f;
q.createGlMatrix(matrix); //
glMultMatrixf(matrix); // matrix[8] = 2.0f * ( x*z + y*w);
} // matrix[9] = 2.0f * ( y*z - x*w);
// matrix[10] = 1.0f - 2.0f * ( x*x + y*y);
// matrix[11] = 0.0f;
//
// matrix[12] = 0.0f;
// matrix[13] = 0.0f;
// matrix[14] = 0.0f;
// matrix[15] = 1.0f;
//
// }
//
// Punkt3D Quaternion::getDirectionVector() {
// GLfloat matrix[16];
// createGlMatrix(matrix);
//
// return getDirectionVector(matrix);
// }
//
// Punkt3D Quaternion::getDirectionVector(GLfloat *matrix) {
// if(!matrix)
// return Punkt3D();
// Punkt3D tmp;
//
// tmp.x = matrix[8];
// tmp.y = matrix[9];
// tmp.z = matrix[10];
//
// return tmp;
// }
//
// void glMultMatrixf(Quaternion q) {
// GLfloat matrix[16];
// q.createGlMatrix(matrix);
// glMultMatrixf(matrix);
// }

View File

@ -4,27 +4,51 @@
#include <iostream> #include <iostream>
#include <cmath> #include <cmath>
#include <SDL_opengl.h> #include <SDL_opengl.h>
// #include "rotationsmatrix.h"
#include "punkt3d.h"
#include "emath.h" #include "emath.h"
class Quaternion { class Quaternion {
private: private:
float w; float x, y, z, w;
float x,y,z;
public: public:
Quaternion(); Quaternion();
void createFromRotation(float, float, float, float); Quaternion(float _x, float _y, float _z, float _w);
Quaternion(float deg, Punkt3D p);
Quaternion(float _x, float _y, float _z);
void set(float rotx, float roty, float rotz);
void createGlMatrix(GLfloat*); void set(float deg, Punkt3D axis);
Punkt3D getDirectionVector(); void normalize();
Punkt3D getDirectionVector(GLfloat*); Quaternion getConjugate();
// Rotationsmatrix getRotMat();
Punkt3D rotP3D(const Punkt3D &p);
Quaternion operator*(const Quaternion&); Quaternion operator*(const Quaternion&);
}; };
void glMultMatrixf(Quaternion);
// class Quaternion {
// private:
// float w;
// float x,y,z;
// public:
// Quaternion();
// void createFromRotation(float, float, float, float);
//
//
// void createGlMatrix(GLfloat*);
// Punkt3D getDirectionVector();
// Punkt3D getDirectionVector(GLfloat*);
//
// Quaternion operator*(const Quaternion&);
//
//
// };
//
// void glMultMatrixf(Quaternion);
#endif #endif

View File

@ -2,6 +2,7 @@
#define __ROTATIONSMATRIX_H #define __ROTATIONSMATRIX_H
#include <cmath> #include <cmath>
#include "punkt3d.h"
#include "emath.h" #include "emath.h"
#include "matrix.h" #include "matrix.h"