aboutsummaryrefslogtreecommitdiff
path: root/tests/bullet/Extras/glui/glui_rotation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/bullet/Extras/glui/glui_rotation.cpp')
-rw-r--r--tests/bullet/Extras/glui/glui_rotation.cpp473
1 files changed, 473 insertions, 0 deletions
diff --git a/tests/bullet/Extras/glui/glui_rotation.cpp b/tests/bullet/Extras/glui/glui_rotation.cpp
new file mode 100644
index 00000000..b02d7435
--- /dev/null
+++ b/tests/bullet/Extras/glui/glui_rotation.cpp
@@ -0,0 +1,473 @@
+/****************************************************************************
+
+ GLUI User Interface Toolkit
+ ---------------------------
+
+ glui_rotation - GLUI_Rotation control class
+
+
+ --------------------------------------------------
+
+ Copyright (c) 1998 Paul Rademacher
+
+ WWW: http://sourceforge.net/projects/glui/
+ Forums: http://sourceforge.net/forum/?group_id=92496
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
+
+#include "GL/glui.h"
+#include "arcball.h"
+#include "algebra3.h"
+
+/*************************** GLUI_Rotation::iaction_mouse_down_handler() ***/
+
+int GLUI_Rotation::iaction_mouse_down_handler( int local_x, int local_y )
+{
+ copy_float_array_to_ball();
+
+ init_ball();
+
+ local_y = (int) floor(2.0 * ball->center[1] - local_y);
+
+ ball->mouse_down( local_x, local_y );
+
+ /* printf( "%d %d - %f %f\n", local_x, local_y, ball->center[0], ball->center[1] ); */
+
+ copy_ball_to_float_array();
+
+ spinning = false;
+
+ return false;
+}
+
+
+/*********************** GLUI_Rotation::iaction_mouse_up_handler() **********/
+
+int GLUI_Rotation::iaction_mouse_up_handler( int local_x, int local_y,
+ bool inside )
+{
+ copy_float_array_to_ball();
+
+ ball->mouse_up();
+
+ return false;
+}
+
+
+/******************* GLUI_Rotation::iaction_mouse_held_down_handler() ******/
+
+int GLUI_Rotation::iaction_mouse_held_down_handler( int local_x, int local_y,
+ bool inside)
+{
+ if ( NOT glui )
+ return 0;
+
+ copy_float_array_to_ball();
+
+ local_y = (int) floor(2.0 * ball->center[1] - local_y);
+
+ /* printf( "%d %d\n", local_x, local_y ); */
+
+ ball->mouse_motion( local_x, local_y, 0,
+ (glui->curr_modifiers & GLUT_ACTIVE_ALT) != 0,
+ (glui->curr_modifiers & GLUT_ACTIVE_CTRL) != 0 );
+
+ copy_ball_to_float_array();
+
+ if ( can_spin )
+ spinning = true;
+
+ return false;
+}
+
+
+/******************** GLUI_Rotation::iaction_draw_active_area_persp() **************/
+
+void GLUI_Rotation::iaction_draw_active_area_persp( void )
+{
+ /********** arcball *******/
+ copy_float_array_to_ball();
+
+ setup_texture();
+ setup_lights();
+
+ glEnable(GL_CULL_FACE );
+
+ glMatrixMode( GL_MODELVIEW );
+ glPushMatrix();
+
+ mat4 tmp_rot = *ball->rot_ptr;
+ glMultMatrixf( (float*) &tmp_rot[0][0] );
+
+ /*** Draw the checkered box ***/
+ /*glDisable( GL_TEXTURE_2D ); */
+ draw_ball(1.35); // 1.96 );
+
+ glPopMatrix();
+
+ glBindTexture(GL_TEXTURE_2D,0); /* unhook our checkerboard texture */
+ glDisable( GL_TEXTURE_2D );
+ glDisable( GL_LIGHTING );
+ glDisable( GL_CULL_FACE );
+}
+
+
+/******************** GLUI_Rotation::iaction_draw_active_area_ortho() **********/
+
+void GLUI_Rotation::iaction_draw_active_area_ortho( void )
+{
+ float radius;
+ radius = (float)(h-22)/2.0; /*MIN((float)w/2.0, (float)h/2.0); */
+
+ /********* Draw emboss circles around arcball control *********/
+ int k;
+ glLineWidth( 1.0 );
+ glBegin( GL_LINE_LOOP);
+ for( k=0; k<60; k++ ) {
+ float phi = 2*M_PI*(float)k/60.0;
+ vec2 p( cos(phi) * (2.0 + radius), sin(phi) * (2.0 + radius));
+ if ( p[1] < -p[0] ) glColor3ub( 128,128,128 );
+ else glColor3ub( 255,255,255 );
+ glVertex2fv((float*)&p[0]);
+ }
+ glEnd();
+
+ glBegin( GL_LINE_LOOP);
+ for( k=0; k<60; k++ ) {
+ float phi = 2*M_PI*(float)k/60.0;
+ vec2 p( cos(phi) * (1.0 + radius), sin(phi) * (1.0 + radius));
+ if ( enabled ) {
+ if ( p[1] < -p[0] ) glColor3ub( 0,0,0);
+ else glColor3ub( 192,192,192);
+ }
+ else
+ {
+ if ( p[1] < -p[0] ) glColor3ub( 180,180,180);
+ else glColor3ub( 192,192,192);
+ }
+ glVertex2fv((float*)&p[0]);
+ }
+ glEnd();
+}
+
+
+/******************************** GLUI_Rotation::iaction_dump() **********/
+
+void GLUI_Rotation::iaction_dump( FILE *output )
+{
+}
+
+
+/******************** GLUI_Rotation::iaction_special_handler() **********/
+
+int GLUI_Rotation::iaction_special_handler( int key,int modifiers )
+{
+
+ return false;
+}
+
+/********************************** GLUI_Rotation::init_ball() **********/
+
+void GLUI_Rotation::init_ball( void )
+{
+ /*printf( "%f %f %f", float( MIN(w/2,h/2)), (float) w/2, (float) h/2 ); */
+
+ ball->set_params( vec2( (float)(w/2), (float)((h-18)/2)),
+ (float) 2.0*(h-18) );
+ /*ball->set_damping( .05 ); */
+ /*float( MIN(w/2,h/2))*2.0 ); */
+ /* ball->reset_mouse(); */
+}
+
+
+/****************************** GLUI_Rotation::setup_texture() *********/
+
+void GLUI_Rotation::setup_texture( void )
+{
+ static GLuint tex=0u;
+ GLenum t=GL_TEXTURE_2D;
+ glEnable(t);
+ glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+ glColor3f( 1.0, 1.0, 1.0 );
+ if (tex!=0u) {
+ /* (OSL 2006/06) Just use glBindTexture to avoid having to re-upload the whole checkerboard every frame. */
+ glBindTexture(t,tex);
+ return;
+ } /* Else need to make a new checkerboard texture */
+ glGenTextures(1,&tex);
+ glBindTexture(t,tex);
+ glEnable(t);
+
+ unsigned int i, j;
+ int dark, light; /*** Dark and light colors for ball checkerboard ***/
+
+/* Note: you can change the number of checkers across there sphere in draw_ball */
+#define CHECKBOARD_SIZE 64 /* pixels across whole texture */
+#define CHECKBOARD_REPEAT 32u /* pixels across one black/white sector */
+ unsigned char texture_image[CHECKBOARD_SIZE] [CHECKBOARD_SIZE] [3];
+ unsigned char c;
+ for( i=0; i<CHECKBOARD_SIZE; i++ )
+ {
+ for( j=0; j<CHECKBOARD_SIZE; j++ )
+ {
+ dark = 110;
+ light = 220;
+
+ if ((((i/CHECKBOARD_REPEAT)&0x1)==0) ^ (((j/CHECKBOARD_REPEAT)&0x1)==0))
+ c = light;
+ else
+ c = dark;
+
+ texture_image[i][j][0] = c;
+ texture_image[i][j][1] = c;
+ texture_image[i][j][2] = c;
+ }
+ }
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+ glTexParameteri( t, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameteri( t, GL_TEXTURE_WRAP_T, GL_REPEAT );
+ glTexParameteri( t, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( t, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
+ gluBuild2DMipmaps(t, GL_RGB, CHECKBOARD_SIZE, CHECKBOARD_SIZE,
+ GL_RGB, GL_UNSIGNED_BYTE, texture_image);
+
+/* Add some mipmapping LOD bias, to keep sphere texture sharp */
+ float bias=-0.5;
+ /* glTexEnvf(TEXTURE_FILTER_CONTROL_EXT,TEXTURE_LOD_BIAS_EXT,bias); */
+ /* glTexParameteri( t, GL_TEXTURE_MAX_LEVEL,1);*/
+ glTexEnvf(0x8500,0x8501,bias); /* <- numeric version for older OpenGL headers */
+ /* Cap out the mipmap level, to prevent blurring on horizon */
+ glTexParameteri(t, 0x813D, 1);
+ if (glGetError()) {
+ /* Ignore errors in setting funky texture state-- go with defaults.
+ If somebody knows how to check OpenGL 1.2 before doing this, please do!
+ */
+ }
+}
+
+/****************************** GLUI_Rotation::setup_lights() ***********/
+
+void GLUI_Rotation::setup_lights( void )
+{
+ glEnable( GL_LIGHTING );
+ /* if ( enabled )
+ glEnable( GL_LIGHTING );
+ else
+ glDisable( GL_LIGHTING );*/
+ glEnable(GL_LIGHT0);
+ glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE );
+ glEnable(GL_COLOR_MATERIAL);
+ GLfloat light0_position[] = {-1.f, 1.f, 1.0f, 0.0f};
+ glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
+ if (enabled) { /* enabled colors */
+ GLfloat light0_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
+ GLfloat light0_diffuse[] = {1.f, 1.f, 1.0f, 1.0f};
+ glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
+ }
+ else { /* disabled colors */
+ GLfloat light0_ambient[] = {0.6f, 0.6f, 0.6f, 1.0f};
+ GLfloat light0_diffuse[] = {0.2f, 0.2f, 0.2f, 1.0f};
+ glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
+ }
+
+}
+
+
+/****************************** GLUI_Rotation::draw_ball() **************/
+
+void GLUI_Rotation::draw_ball( float radius )
+{
+ if ( NOT can_draw() )
+ return;
+
+ if (quadObj == NULL) quadObj = gluNewQuadric();
+ if (quadObj) {
+ gluQuadricDrawStyle(quadObj, GLU_FILL);
+ gluQuadricNormals(quadObj, GLU_SMOOTH);
+ gluQuadricTexture(quadObj, true );
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ double checkerTiles=2.0; /* black-white checker tiles across whole sphere */
+ glScalef(checkerTiles,checkerTiles,1.0);
+ gluSphere(quadObj, radius, 32, 16);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ }
+}
+
+
+/****************************** GLUI_Rotation::reset() **********/
+
+void GLUI_Rotation::reset( void )
+{
+ ball->init(); /** reset quaternion, etc. **/
+ ball->set_params( vec2( (float)(w/2), (float)((h-18)/2)),
+ (float) 2.0*(h-18) );
+
+ set_spin( this->damping );
+
+ copy_ball_to_float_array();
+
+ translate_and_draw_front();
+
+ output_live(true); /*** Output live and draw main grx window ***/
+}
+
+
+/****************************** GLUI_Rotation::needs_idle() *********/
+
+bool GLUI_Rotation::needs_idle( void ) const
+{
+ return can_spin;
+}
+
+
+/****************************** GLUI_Rotation::idle() ***************/
+
+void GLUI_Rotation::idle( void )
+{
+ spinning = ball->is_spinning?true:false;
+
+ if ( can_spin AND spinning ) {
+ copy_float_array_to_ball();
+ ball->idle();
+
+ *ball->rot_ptr = *ball->rot_ptr * ball->rot_increment;
+
+ mat4 tmp_rot;
+ tmp_rot = *ball->rot_ptr;
+
+ copy_ball_to_float_array();
+
+ draw_active_area_only = true;
+ translate_and_draw_front();
+ draw_active_area_only = false;
+
+ output_live(true); /** output live and update gfx **/
+ }
+ else {
+ }
+}
+
+
+/********************** GLUI_Rotation::copy_float_array_to_ball() *********/
+
+void GLUI_Rotation::copy_float_array_to_ball( void )
+{
+ int i;
+ float *fp_src, *fp_dst;
+
+ fp_src = &float_array_val[0];
+ fp_dst = &((*ball->rot_ptr)[0][0]);
+
+ for( i=0; i<16; i++ ) {
+ *fp_dst = *fp_src;
+
+ fp_src++;
+ fp_dst++;
+ }
+}
+
+
+/********************** GLUI_Rotation::copy_ball_to_float_array() *********/
+
+void GLUI_Rotation::copy_ball_to_float_array( void )
+{
+ mat4 tmp_rot;
+ tmp_rot = *ball->rot_ptr;
+
+ set_float_array_val( (float*) &tmp_rot[0][0] );
+}
+
+
+/************************ GLUI_Rotation::set_spin() **********************/
+
+void GLUI_Rotation::set_spin( float damp_factor )
+{
+ if ( damp_factor == 0.0 )
+ can_spin = false;
+ else
+ can_spin = true;
+
+ ball->set_damping( 1.0 - damp_factor );
+
+ this->damping = damp_factor;
+}
+
+
+/************** GLUI_Rotation::GLUI_Rotation() ********************/
+
+GLUI_Rotation::GLUI_Rotation( GLUI_Node *parent,
+ const char *name, float *value_ptr,
+ int id,
+ GLUI_CB cb )
+{
+ common_init();
+ set_ptr_val( value_ptr );
+ user_id = id;
+ set_name( name );
+ callback = cb;
+ parent->add_control( this );
+ init_live();
+
+ /*** Init the live 4x4 matrix. This is different than the standard
+ live variable behavior, since the original value of the 4x4 matrix
+ is ignored and reset to Identity ***/
+/*
+NO! WVB
+ if ( value_ptr != NULL ) {
+ int i, j, index;
+ for( i=0; i<4; i++ ) {
+ for( j=0; j<4; j++ ) {
+ index = i*4+j;
+ if ( i==j )
+ value_ptr[index] = 1.0;
+ else
+ value_ptr[index] = 0.0;
+ }
+ }
+ }
+*/
+ /*init_ball(); */
+
+
+}
+
+
+/************** GLUI_Rotation::common_init() ********************/
+
+void GLUI_Rotation::common_init( void )
+{
+ glui_format_str( name, "Rotation: %p", this );
+// type = GLUI_CONTROL_ROTATION;
+ w = GLUI_ROTATION_WIDTH;
+ h = GLUI_ROTATION_HEIGHT;
+ can_activate = true;
+ live_type = GLUI_LIVE_FLOAT_ARRAY;
+ float_array_size = 16;
+ quadObj = NULL;
+ alignment = GLUI_ALIGN_CENTER;
+ can_spin = false;
+ spinning = false;
+ damping = 0.0;
+ ball = new Arcball;
+
+ reset();
+}