diff --git a/Makefile b/Makefile index c095a2f..07dddfb 100755 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ CC = g++ 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` -SUBDIRS = glgui glmenu models -SUBDIROBJECTS = glgui/*.o glmenu/*.o models/*.o +SUBDIRS = glgui glmenu model +SUBDIROBJECTS = glgui/*.o glmenu/*.o model/*.o VERSION = 0.0.1 LIBNAME = libsegl diff --git a/emath.cpp b/emath.cpp index 3aada5f..07ba569 100644 --- a/emath.cpp +++ b/emath.cpp @@ -27,7 +27,6 @@ float ssin(float c) { case 270: return -1.0f; default: -// std::cout << "ssin sollte keinen defaultwert zurückliefern. c=" << c << ", t=" << t << std::endl; return sin(deg2rad(c)); } } diff --git a/emath.h b/emath.h index 6a1a3c8..39b518b 100644 --- a/emath.h +++ b/emath.h @@ -5,7 +5,6 @@ #include #include -#include "punkt3d.h" /* aus kompatibilitätsgründen */ float deg2rad(float deg); float rad2deg(float rad); diff --git a/emath_opengl.h b/emath_opengl.h index f696817..dfcff71 100644 --- a/emath_opengl.h +++ b/emath_opengl.h @@ -2,6 +2,7 @@ #define __EMATH_OPENGL #include +#include "punkt3d.h" #include "emath.h" #include "rotationsmatrix.h" #include diff --git a/extstring.cpp b/extstring.cpp new file mode 100644 index 0000000..4ff1cba --- /dev/null +++ b/extstring.cpp @@ -0,0 +1,47 @@ +#include "extstring.h" + +int explode(std::string str, std::string delim, std::vector *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); +} diff --git a/extstring.h b/extstring.h new file mode 100644 index 0000000..03639e5 --- /dev/null +++ b/extstring.h @@ -0,0 +1,12 @@ +#ifndef __EXTSTRING_H +#define __EXTSTRING_H + +#include +#include + +int explode(std::string str, std::string delim, std::vector *erg, bool clean=false); +std::string trim(std::string t); +std::string basename(std::string str); +std::string rbasename(std::string str); + +#endif diff --git a/glcamera.cpp b/glcamera.cpp index 3a28aee..263524c 100644 --- a/glcamera.cpp +++ b/glcamera.cpp @@ -100,7 +100,7 @@ void GLCamera::rotateUp(float sec) { rotmatX.set(rotx); doupdate = true; } else { - //std::cout << "zu groß" << std::endl; + //std::cout << "zu gro�" << std::endl; } // rotmat.set(dir.kreuzprodukt(norm), -apersec*sec); // norm = rotmat * norm; @@ -122,6 +122,27 @@ void GLCamera::rotateDown(float sec) { // 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() { return rotx; } diff --git a/glcamera.h b/glcamera.h index 3a57183..3bea881 100644 --- a/glcamera.h +++ b/glcamera.h @@ -44,6 +44,8 @@ class GLCamera { void rotateUp(float sec); void rotateDown(float sec); + void handleKeys(float sec); + float getXrot(); float getYrot(); diff --git a/matrix.h b/matrix.h index 663831d..94d55e1 100644 --- a/matrix.h +++ b/matrix.h @@ -4,6 +4,7 @@ #include #include +#include "punkt3d.h" #include "emath.h" class Matrix { diff --git a/model/Makefile b/model/Makefile new file mode 100755 index 0000000..f227cb7 --- /dev/null +++ b/model/Makefile @@ -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) diff --git a/model/loadobj.cpp b/model/loadobj.cpp new file mode 100644 index 0000000..e829d4d --- /dev/null +++ b/model/loadobj.cpp @@ -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 v; + std::vector 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; imeshdataanz; 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; +} diff --git a/model/loadobj.h b/model/loadobj.h new file mode 100644 index 0000000..cd0ab07 --- /dev/null +++ b/model/loadobj.h @@ -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 diff --git a/model/model.cpp b/model/model.cpp new file mode 100644 index 0000000..4eda93b --- /dev/null +++ b/model/model.cpp @@ -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 +#include +#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 diff --git a/model/modelloader.cpp b/model/modelloader.cpp new file mode 100644 index 0000000..07541aa --- /dev/null +++ b/model/modelloader.cpp @@ -0,0 +1,5 @@ +#include "modelloader.h" + +Modelloader::Modelloader(std::string _filename) { + filename = _filename; +} diff --git a/model/modelloader.h b/model/modelloader.h new file mode 100644 index 0000000..8d1a8ec --- /dev/null +++ b/model/modelloader.h @@ -0,0 +1,17 @@ +#ifndef __MODELLOADER_H +#define __MODELLOADER_H + +#include +#include +#include "model.h" + + +class Modelloader { + protected: + std::string filename; + public: + Modelloader(std::string _filename); + virtual bool load(Model *m)=0; +}; + +#endif diff --git a/models/Makefile b/model/old/Makefile similarity index 100% rename from models/Makefile rename to model/old/Makefile diff --git a/models/load3ds.cpp b/model/old/load3ds.cpp similarity index 100% rename from models/load3ds.cpp rename to model/old/load3ds.cpp diff --git a/models/load3ds.h b/model/old/load3ds.h similarity index 100% rename from models/load3ds.h rename to model/old/load3ds.h diff --git a/models/model.cpp b/model/old/model.cpp similarity index 100% rename from models/model.cpp rename to model/old/model.cpp diff --git a/models/model.h b/model/old/model.h similarity index 100% rename from models/model.h rename to model/old/model.h diff --git a/punkt2d.cpp b/punkt2d.cpp index 5fb98b8..6df3036 100644 --- a/punkt2d.cpp +++ b/punkt2d.cpp @@ -19,6 +19,9 @@ void Punkt2D::print(std::string coordname) { std::cout << coordname << "Coord: (" << x << ", " << y << ")" << std::endl; } +float Punkt2D::abs() { + return sqrt(x*x + y*y); +} Punkt2D Punkt2D::operator+(const Punkt2D &b) { Punkt2D c; @@ -131,6 +134,11 @@ void glTexCoord2f(Punkt2D p) { glTexCoord2f(p.x, p.y); } -// float abs(Punkt2D p) { -// return p.abs(); -// } +float abs(Punkt2D p) { + return p.abs(); +} + +// Fixed Headers +void glTexCoordP2D(Punkt2D p) { + glTexCoord2f(p.x, p.y); +} diff --git a/punkt2d.h b/punkt2d.h index 40e0abc..5ce98dc 100644 --- a/punkt2d.h +++ b/punkt2d.h @@ -14,6 +14,7 @@ class Punkt2D { void set(float, float); void print(std::string=""); + float abs(); // Operatoren Punkt2D operator+(const Punkt2D&); @@ -45,6 +46,9 @@ class Punkt2D { }; void glTexCoord2f(Punkt2D); -// float abs(Punkt3D); +float abs(Punkt2D); + +// Fixed Headers +void glTexCoordP2D(Punkt2D p); #endif diff --git a/punkt3d.cpp b/punkt3d.cpp index ba71702..e69bf91 100644 --- a/punkt3d.cpp +++ b/punkt3d.cpp @@ -205,7 +205,7 @@ float abs(Punkt3D p) { return p.abs(); } -// OpenGL Funktionen für Punkt3D +// OpenGL Funktionen f�r Punkt3D void glVertex3f(Punkt3D p) { glVertex3f(p.x, p.y, p.z); @@ -239,3 +239,9 @@ void glNormalP3D(Punkt3D p) { void glRotateP3D(float deg, Punkt3D vec) { 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 ); +} diff --git a/punkt3d.h b/punkt3d.h index c581aae..bb394f6 100644 --- a/punkt3d.h +++ b/punkt3d.h @@ -57,7 +57,7 @@ class Punkt3D { float abs(Punkt3D); -// OpenGL-Funktionen für Punkt3D +// OpenGL-Functions for Punkt3D void glVertex3f(Punkt3D); void glTranslatef(Punkt3D); @@ -71,6 +71,6 @@ void glTranslateP3D(Punkt3D); void glNormalP3D(Punkt3D); void glRotateP3D(float, Punkt3D); - +void gluLookAt(Punkt3D pos, Punkt3D viewport, Punkt3D normal); #endif diff --git a/quader.cpp b/quader.cpp new file mode 100644 index 0000000..735cf8d --- /dev/null +++ b/quader.cpp @@ -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 +} diff --git a/quader.h b/quader.h new file mode 100644 index 0000000..6ef34b0 --- /dev/null +++ b/quader.h @@ -0,0 +1,15 @@ +#ifndef __QUADER_H +#define __QUADER_H + +#include +#include "punkt3d.h" + + +class Quader { + public: + Punkt3D a, b, c, d, e, f, g, h; + void clean(); + void render(); +}; + +#endif diff --git a/quaternion.cpp b/quaternion.cpp index 881535c..862220e 100644 --- a/quaternion.cpp +++ b/quaternion.cpp @@ -1,77 +1,165 @@ #include "quaternion.h" Quaternion::Quaternion() { - w = 1.0f; + w = 1.0f, x = y = z = 0.0f; } -void Quaternion::createFromRotation(float deg, float _x, float _y, float _z) { - float tmpres = sin(deg2rad(deg) / 2.0f); - - w = cos(deg2rad(deg) / 2.0f); - x = _x * tmpres; - y = _y * tmpres; - z = _z * tmpres; +Quaternion::Quaternion(float _x, float _y, float _z, float _w) { + x = _x; + y = _y; + z = _z; + w = _w; } -Quaternion Quaternion::operator*(const Quaternion &q) { - Quaternion ret; - - ret.w = w*q.w - x*q.x - y*q.y - z*q.z; - ret.x = w*q.x + x*q.w + y*q.z - z*q.y; - 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; +Quaternion::Quaternion(float deg, Punkt3D p) { + set(deg, p); } -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); - matrix[5] = 1.0f - 2.0f * ( x*x + z*z); - matrix[6] = 2.0f * ( z*y + x*w); - matrix[7] = 0.0f; - - 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; +Quaternion::Quaternion(float _x, float _y, float _z) { + set(_x, _y, _z); +} - matrix[12] = 0.0f; - matrix[13] = 0.0f; - matrix[14] = 0.0f; - matrix[15] = 1.0f; +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(); } -Punkt3D Quaternion::getDirectionVector() { - GLfloat matrix[16]; - createGlMatrix(matrix); +void Quaternion::set(float deg, Punkt3D p) { + float angle = deg2rad(0.5f*deg); + float sinangle = sin(angle); - return getDirectionVector(matrix); + 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); } -Punkt3D Quaternion::getDirectionVector(GLfloat *matrix) { - if(!matrix) - return Punkt3D(); - Punkt3D tmp; +// Rotationsmatrix Quaternion::getRotMat() { +// +// } + +Punkt3D Quaternion::rotP3D(const Punkt3D &p) { + Quaternion q(p.x, p.y, p.z, 0.0f); - tmp.x = matrix[8]; - tmp.y = matrix[9]; - tmp.z = matrix[10]; + Quaternion erg = *this * q * this->getConjugate(); - return tmp; + return Punkt3D(erg.x, erg.y, erg.z); } -void glMultMatrixf(Quaternion q) { - GLfloat matrix[16]; - q.createGlMatrix(matrix); - glMultMatrixf(matrix); +Quaternion Quaternion::operator*(const Quaternion &q) { + 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, + w*q.z - z*q.w + x*q.y - y*q.x, + w*q.w - x*q.x - y*q.y - z*q.z); } + + + +// Quaternion::Quaternion() { +// w = 1.0f; +// x = y = z = 0.0f; +// } +// +// void Quaternion::createFromRotation(float deg, float _x, float _y, float _z) { +// float tmpres = sin(deg2rad(deg) / 2.0f); +// +// w = cos(deg2rad(deg) / 2.0f); +// x = _x * tmpres; +// y = _y * tmpres; +// z = _z * tmpres; +// } +// +// Quaternion Quaternion::operator*(const Quaternion &q) { +// Quaternion ret; +// +// ret.w = w*q.w - x*q.x - y*q.y - z*q.z; +// ret.x = w*q.x + x*q.w + y*q.z - z*q.y; +// 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); +// matrix[5] = 1.0f - 2.0f * ( x*x + z*z); +// matrix[6] = 2.0f * ( z*y + x*w); +// matrix[7] = 0.0f; +// +// 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); +// } diff --git a/quaternion.h b/quaternion.h index 1b58aaf..22d5adf 100644 --- a/quaternion.h +++ b/quaternion.h @@ -4,27 +4,51 @@ #include #include #include - +// #include "rotationsmatrix.h" +#include "punkt3d.h" #include "emath.h" class Quaternion { private: - float w; - float x,y,z; + float x, y, z, w; + public: 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 createGlMatrix(GLfloat*); - Punkt3D getDirectionVector(); - Punkt3D getDirectionVector(GLfloat*); + void set(float rotx, float roty, float rotz); + void set(float deg, Punkt3D axis); + void normalize(); + Quaternion getConjugate(); +// Rotationsmatrix getRotMat(); + Punkt3D rotP3D(const Punkt3D &p); 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 diff --git a/rotationsmatrix.h b/rotationsmatrix.h index 3297662..34f18f1 100644 --- a/rotationsmatrix.h +++ b/rotationsmatrix.h @@ -2,6 +2,7 @@ #define __ROTATIONSMATRIX_H #include +#include "punkt3d.h" #include "emath.h" #include "matrix.h"