* now it seems to work better.
[hkl3d.git] / gui / ghkl3d / hkl3d-gui-model.cpp
blob1d36b1d5d9bac2ae48ec26c57d4a6bf32c2b7178
1 /*
2 * This file is part of the hkl3d library.
3 * inspired from logo-model.c of the GtkGLExt logo models.
4 * written by Naofumi Yasufuku <naofumi@users.sourceforge.net>
6 * The hkl library is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * The hkl library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
19 * Copyright (C) 2010 Synchrotron SOLEIL
20 * L'Orme des Merisiers Saint-Aubin
21 * BP 48 91192 GIF-sur-YVETTE CEDEX
23 * Authors: Oussama Sboui <oussama.sboui@synchrotron-soleil.fr>
24 * Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
27 #include <iostream>
29 #include "hkl3d-gui-model.h"
31 #include "btBulletDynamicsCommon.h"
33 // Trackball utilities.
35 namespace Trackball {
36 extern "C" {
37 #include "trackball.h"
40 namespace GLDRAW {
41 extern "C" {
42 #include "hkl3d-gui-gl.h"
45 namespace Logo
47 LogoModel::LogoModel(Hkl3D & hkl3d)
48 : _hkl3d(hkl3d)
52 LogoModel::~LogoModel(void)
55 void LogoModel::drawSphere(void)
57 #ifndef M_PI
58 # define M_PI 3.14159265358979323846
59 #endif
60 #define PAS (M_PI/24)
61 #define DEBUT 0
62 #define FIN (2*M_PI - DEBUT)
63 for (double a = 0; a < M_PI; a+=PAS)
65 double b1;
66 double a1 = a + PAS;
67 glBegin(GL_QUADS);
69 glVertex3d(sin(a)*cos(DEBUT), cos(a), sin(a)*sin(DEBUT));
71 glVertex3d(sin(a1)*cos(DEBUT), cos(a1), sin(a1)*sin(DEBUT));
73 glVertex3d(0, cos(a1), 0);
74 glVertex3d(0, cos(a), 0);
75 for (double b = DEBUT; b < FIN; b+=PAS) {
76 b1 = b + PAS;
77 if (b1 > FIN)
78 b1 = FIN;
79 glVertex3d(sin(a)*cos(b), cos(a), sin(a)*sin(b));
81 glVertex3d(sin(a1)*cos(b), cos(a1), sin(a1)*sin(b));
83 glVertex3d(sin(a1)*cos(b1), cos(a1), sin(a1)*sin(b1));
85 glVertex3d(sin(a)*cos(b1), cos(a), sin(a)*sin(b1));
88 glEnd();
93 void LogoModel::model_draw(void)
95 int i;
96 int len;
97 int numManifolds;
98 btScalar m[16];
99 btVector3 worldBoundsMin;
100 btVector3 worldBoundsMax;
102 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
103 glDisable(GL_LIGHTING);
104 GL_ShapeDrawer::drawCoordSystem();
106 // draw the diffractometer
107 // get the world bounding box from bullet
108 _hkl3d._btCollisionWorld->getBroadphase()->getBroadphaseAabb(worldBoundsMin,
109 worldBoundsMax);
111 len = _hkl3d._btCollisionObjects.size();
112 GLDRAW::G3DGLRenderOptions *options = g_new0(GLDRAW::G3DGLRenderOptions, 1);
113 options->glflags = G3D_FLAG_GL_SPECULAR
114 | G3D_FLAG_GL_SHININESS
115 | G3D_FLAG_GL_TEXTURES
116 | G3D_FLAG_GL_COLORS;
117 options->updated=true;
118 options->initialized=false;
120 ///one way to draw all the contact points is iterating over contact manifolds / points:
121 numManifolds = _hkl3d._btDispatcher->getNumManifolds();
122 for (i=0; i<numManifolds; i++){
123 btPersistentManifold *contactManifold;
124 btCollisionObject *obA;
125 btCollisionObject *obB;
126 int numContacts;
127 int j;
129 contactManifold = _hkl3d._btDispatcher->getManifoldByIndexInternal(i);
130 obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
131 obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
133 // now draw the manifolds / points
134 numContacts = contactManifold->getNumContacts();
135 for (j=0; j<numContacts; j++){
136 btManifoldPoint & pt = contactManifold->getContactPoint(j);
137 btScalar dist= pt.getDistance();
138 printf("%f\n",dist);
139 glBegin(GL_LINES);
140 glColor4f(0, 0, 0, 1);
141 btVector3 ptA = pt.getPositionWorldOnA();
142 btVector3 ptB = pt.getPositionWorldOnB();
143 glVertex3d(ptA.x(),ptA.y(),ptA.z());
144 glVertex3d(ptB.x(),ptB.y(),ptB.z());
145 glEnd();
146 glColor4f(1, 0, 0, 1);
147 glPushMatrix();
148 glTranslatef (ptB.x(),ptB.y(),ptB.z());
149 glScaled(0.2,0.2,0.2);
150 this->drawSphere();
151 glPopMatrix();
152 glColor4f(1, 1, 0, 1);
153 glPushMatrix();
154 glTranslatef (ptA.x(),ptA.y(),ptA.z());
155 glScaled(0.2,0.2,0.2);
156 this->drawSphere();
157 glPopMatrix();
158 //contactManifold->clearManifold();
161 GLDRAW::gl_draw(options, _hkl3d._model);
162 glFlush();
165 // dummy methods
166 void LogoModel::initPhysics(void){};
168 void LogoModel::clientMoveAndDisplay(void){};
170 void LogoModel::displayCallback(void){};
173 // Model class implementation.
176 const float Model::MAT_SPECULAR[4] = { 0.5, 0.5, 0.5, 1.0 };
177 const float Model::MAT_SHININESS[1] = { 10.0 };
178 const float Model::MAT_BLACK[4] = { 0.0, 0.0, 0.0, 1.0 };
179 const float Model::MAT_RED[4] = { 1.0, 0.0, 0.0, 1.0 };
180 const float Model::MAT_GREEN[4] = { 0.0, 1.0, 0.0, 1.0 };
181 const float Model::MAT_BLUE[4] = { 0.0, 0.0, 1.0, 1.0 };
183 const unsigned int Model::DEFAULT_ROT_COUNT = 100;
185 static float AXIS_X[3] = { 1.0, 0.0, 0.0 };
186 static float AXIS_Y[3] = { 0.0, 1.0, 0.0 };
187 static float AXIS_Z[3] = { 0.0, 0.0, 1.0 };
189 const Model::RotMode Model::ROT_MODE[] = {
190 { AXIS_X, 1.0 },
191 { AXIS_Y, 1.0 },
192 { AXIS_X, 1.0 },
193 { AXIS_Z, 1.0 },
194 { AXIS_X, 1.0 },
195 { AXIS_Y, -1.0 },
196 { AXIS_X, 1.0 },
197 { AXIS_Z, -1.0 },
198 { 0, 0.0 } // terminator
201 Model::Model(Hkl3D & hkl3d, unsigned int rot_count,
202 bool enable_anim, bool enable_wireframe)
203 : _hkl3d(hkl3d), m_RotCount(rot_count),
204 m_EnableAnim(enable_anim), m_EnableWireframe(enable_wireframe), m_Mode(0), m_Counter(0)
206 this->reset_anim();
209 Model::~Model(void)
213 void Model::init_gl(LogoModel* logoM)
215 glEnable(GL_CULL_FACE);
217 glPushMatrix();
219 glMaterialfv(GL_FRONT, GL_SPECULAR, MAT_SPECULAR);
220 glMaterialfv(GL_FRONT, GL_SHININESS, MAT_SHININESS);
222 glNewList(MODEL, GL_COMPILE);
223 this->logoM = new LogoModel(_hkl3d);
224 this->logoM->model_draw();
225 glEndList();
230 void Model::draw(void)
232 // Init GL context.
233 static bool initialized = false;
234 if (!initialized) {
235 init_gl(logoM);
236 initialized = true;
237 }else
238 init_gl(logoM);
240 // Animation.
241 if (m_EnableAnim) {
242 if (m_Counter == m_RotCount) {
243 if (ROT_MODE[++m_Mode].axis == 0)
244 m_Mode = 0;
245 m_Counter = 0;
248 float d_quat[4];
249 Trackball::axis_to_quat(ROT_MODE[m_Mode].axis,
250 ROT_MODE[m_Mode].sign * G_PI_2 / m_RotCount,
251 d_quat);
252 Trackball::add_quats(d_quat, m_Quat, m_Quat);
254 ++m_Counter;
256 // WireFrame
257 if(m_EnableWireframe)
259 glPolygonMode(GL_FRONT, GL_LINE);
260 glPolygonMode(GL_BACK, GL_LINE);
263 else
265 glPolygonMode(GL_FRONT, GL_FILL);
266 glPolygonMode(GL_BACK, GL_FILL);
270 // Draw logo model.
271 glPushMatrix();
272 glTranslatef(m_Pos[0], m_Pos[1], m_Pos[2]);
274 float m[4][4];
275 Trackball::build_rotmatrix(m, m_Quat);
276 glMultMatrixf(&m[0][0]);
278 glRotatef(0.0, 0.0, 0.0, 1.0);
280 glCallList(MODEL);
282 glPopMatrix();
285 void Model::reset_anim(void)
287 m_Pos[0] = 0.0;
288 m_Pos[1] = 0.0;
289 m_Pos[2] = 0.0;
291 m_Quat[0] = 0.0;
292 m_Quat[1] = 0.0;
293 m_Quat[2] = 0.0;
294 m_Quat[3] = 1.0;
296 m_Mode = 0;
297 m_Counter = 0;
300 } // namespace Logo