From e5c50afed6f0d7af099ea4a87a160451a706a186 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Thu, 11 Sep 2008 11:19:34 +0000 Subject: * Quaternion: added dot product and angularDistance functions. The latter is based on the former. * opengl_demo: makes IcoSphere better (vertices are instanciated only once) and removed the generation of a big geometry for the fancy spheres... --- demos/opengl/icosphere.cpp | 40 +++++--- demos/opengl/quaternion_demo.cpp | 194 +++++++++++++++++++-------------------- 2 files changed, 123 insertions(+), 111 deletions(-) (limited to 'demos/opengl') diff --git a/demos/opengl/icosphere.cpp b/demos/opengl/icosphere.cpp index 5f7823124..042ad6076 100644 --- a/demos/opengl/icosphere.cpp +++ b/demos/opengl/icosphere.cpp @@ -25,6 +25,7 @@ #include "icosphere.h" #include +#include using namespace Eigen; @@ -74,24 +75,39 @@ const std::vector& IcoSphere::indices(int level) const void IcoSphere::_subdivide(void) { + typedef unsigned long long Key; + std::map edgeMap; const std::vector& indices = *mIndices.back(); mIndices.push_back(new std::vector); std::vector& refinedIndices = *mIndices.back(); int end = indices.size(); for (int i=0; ie0) + std::swap(e0,e1); + Key edgeKey = Key(e0) | (Key(e1)<<32); + std::map::iterator it = edgeMap.find(edgeKey); + if (it==edgeMap.end()) + { + ids1[k] = mVertices.size(); + edgeMap[edgeKey] = ids1[k]; + mVertices.push_back( (mVertices[e0]+mVertices[e1]).normalized() ); + } + else + ids1[k] = it->second; + } + refinedIndices.push_back(ids0[0]); refinedIndices.push_back(ids1[0]); refinedIndices.push_back(ids1[2]); + refinedIndices.push_back(ids0[1]); refinedIndices.push_back(ids1[1]); refinedIndices.push_back(ids1[0]); + refinedIndices.push_back(ids0[2]); refinedIndices.push_back(ids1[2]); refinedIndices.push_back(ids1[1]); + refinedIndices.push_back(ids1[0]); refinedIndices.push_back(ids1[1]); refinedIndices.push_back(ids1[2]); } mListIds.push_back(0); } diff --git a/demos/opengl/quaternion_demo.cpp b/demos/opengl/quaternion_demo.cpp index dbfc16c6b..31aeb4d73 100644 --- a/demos/opengl/quaternion_demo.cpp +++ b/demos/opengl/quaternion_demo.cpp @@ -41,6 +41,89 @@ using namespace Eigen; +class FancySpheres +{ + public: + FancySpheres() + { + const int levels = 4; + const float scale = 0.33; + float radius = 100; + std::vector parents; + + // leval 0 + mCenters.push_back(Vector3f::Zero()); + parents.push_back(-1); + mRadii.push_back(radius); + + // generate level 1 using icosphere vertices + radius *= 0.45; + { + float dist = mRadii[0]*0.9; + for (int i=0; i<12; ++i) + { + mCenters.push_back(mIcoSphere.vertices()[i] * dist); + mRadii.push_back(radius); + parents.push_back(0); + } + } + + static const float angles [10] = { + 0, 0, + M_PI, 0.*M_PI, + M_PI, 0.5*M_PI, + M_PI, 1.*M_PI, + M_PI, 1.5*M_PI + }; + + // generate other levels + int start = 1; + for (int l=1; l mCenters; + std::vector mRadii; + IcoSphere mIcoSphere; +}; + // generic linear interpolation method template T lerp(float t, const T& a, const T& b) @@ -156,7 +239,8 @@ void RenderingWidget::grabFrame(void) void RenderingWidget::drawScene() { - float length = 50; + static FancySpheres sFancySpheres; + float length = 200; gpu.drawVector(Vector3f::Zero(), length*Vector3f::UnitX(), Color(1,0,0,1)); gpu.drawVector(Vector3f::Zero(), length*Vector3f::UnitY(), Color(0,1,0,1)); gpu.drawVector(Vector3f::Zero(), length*Vector3f::UnitZ(), Color(0,0,1,1)); @@ -183,13 +267,14 @@ void RenderingWidget::drawScene() glEnable(GL_LIGHT1); glColor3f(0.4, 0.7, 0.4); - glVertexPointer(3, GL_FLOAT, 0, mVertices[0].data()); - glNormalPointer(GL_FLOAT, 0, mNormals[0].data()); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glDrawArrays(GL_TRIANGLES, 0, mVertices.size()); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + sFancySpheres.draw(); +// glVertexPointer(3, GL_FLOAT, 0, mVertices[0].data()); +// glNormalPointer(GL_FLOAT, 0, mNormals[0].data()); +// glEnableClientState(GL_VERTEX_ARRAY); +// glEnableClientState(GL_NORMAL_ARRAY); +// glDrawArrays(GL_TRIANGLES, 0, mVertices.size()); +// glDisableClientState(GL_VERTEX_ARRAY); +// glDisableClientState(GL_NORMAL_ARRAY); glDisable(GL_LIGHTING); } @@ -413,93 +498,6 @@ void RenderingWidget::initializeGL() mCamera.setTarget(Vector3f(0, 0, 0)); mInitFrame.orientation = mCamera.orientation().inverse(); mInitFrame.position = mCamera.viewMatrix().translation(); - - // create a kind of fractal sphere - { - IcoSphere pattern; - - int levels = 3; - float scale = 0.45; - float radius = 100; - std::vector centers; - std::vector parents; - std::vector radii; - centers.push_back(Vector3f::Zero()); - parents.push_back(-1); - radii.push_back(radius); - radius *= scale; - - // generate level 1 using icosphere vertices - { - float dist = radii[0]*0.9; - for (int i=0; i<12; ++i) - { - centers.push_back(pattern.vertices()[i] * dist); - radii.push_back(radius); - parents.push_back(0); - } - } - - scale = 0.33; - static const float angles [10] = { - 0, 0, - M_PI, 0.*M_PI, - M_PI, 0.5*M_PI, - M_PI, 1.*M_PI, - M_PI, 1.5*M_PI}; - - // generate other levels - int start = 1; - float maxAngle = M_PI/2; - for (int l=1; l& sphereIndices = pattern.indices(2); - std::cout << "instanciate geometry... (" << sphereIndices.size() * centers.size() << " vertices)\n"; - mVertices.reserve(sphereIndices.size() * centers.size()); - mNormals.reserve(sphereIndices.size() * centers.size()); - int end = centers.size(); - for (int i=0; iM_PI) - rangle = 2.*M_PI - rangle; - float duration = rangle * 0.9; + float duration = aux0.orientation.angularDistance(aux1.orientation) * 0.9; if (duration<0.1) duration = 0.1; // put the camera at that time step: @@ -660,3 +655,4 @@ int main(int argc, char *argv[]) } #include "quaternion_demo.moc" + -- cgit v1.2.3