273 lines
6.0 KiB
C++
Executable File
273 lines
6.0 KiB
C++
Executable File
#include "BeachBall.h"
|
|
|
|
#include <igl/quat_to_mat.h>
|
|
#include <igl/report_gl_error.h>
|
|
#include <igl/trackball.h>
|
|
#include <igl/canonical_quaternions.h>
|
|
#include <igl/PI.h>
|
|
|
|
#include <GLUT/GLUT.h>
|
|
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
#include <vector>
|
|
#include <cmath>
|
|
|
|
double back[3] = {85.0/255.0,85.0/255.0,85.0/255.0};
|
|
double width,height;
|
|
double scene_rot[4] = {0,0,0,1};
|
|
double * BeachBall::scene_rot = NULL;
|
|
double down_scene_rot[4] = {0,0,0,1};
|
|
int down_mouse_x=-1,down_mouse_y=-1;
|
|
bool trackball_on = false;
|
|
const float light_pos[4] = {-0.2, -0.1, 1,0};
|
|
|
|
std::vector<BeachBall> balls;
|
|
float plane[4] = {0,0,1,1.5};
|
|
|
|
int display_count = 0;
|
|
|
|
void push_scene()
|
|
{
|
|
using namespace igl;
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
//gluOrtho2D(0,width,0,height);
|
|
gluPerspective(15,(double)width/(double)height,1e-2,300);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
glPushMatrix();
|
|
gluLookAt(0,0,20,0,0,0,0,1,0);
|
|
double mat[4*4];
|
|
quat_to_mat(scene_rot,mat);
|
|
glMultMatrixd(mat);
|
|
}
|
|
|
|
void lights()
|
|
{
|
|
using namespace std;
|
|
using namespace igl;
|
|
|
|
glEnable(GL_LIGHTING);
|
|
float ones[4] = {1.0,1.0,1.0,1.0};
|
|
glLightfv(GL_LIGHT0,GL_AMBIENT,ones);
|
|
glLightfv(GL_LIGHT0,GL_DIFFUSE,ones);
|
|
glLightfv(GL_LIGHT0,GL_SPECULAR,ones);
|
|
glLightfv(GL_LIGHT0,GL_POSITION,light_pos);
|
|
glEnable(GL_LIGHT0);
|
|
}
|
|
|
|
void pop_scene()
|
|
{
|
|
glPopMatrix();
|
|
}
|
|
|
|
void display()
|
|
{
|
|
using namespace std;
|
|
using namespace igl;
|
|
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
if(true || display_count==0 || display_count==200)
|
|
{
|
|
glClearColor(back[0],back[1],back[2],0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
lights();
|
|
push_scene();
|
|
|
|
//// Normal list
|
|
//for(int i = 0;i<(int)balls.size();i++)
|
|
//{
|
|
// balls[i].draw();
|
|
//}
|
|
|
|
// single root
|
|
balls[0].draw();
|
|
balls[0].push();
|
|
for(int i = 1;i<(int)balls.size();i++)
|
|
{
|
|
balls[i].radius = 0.5;
|
|
balls[i].draw();
|
|
}
|
|
balls[0].pop();
|
|
|
|
// Draw floor
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
|
glPolygonOffset(10.0,1);
|
|
float size = 10;
|
|
glBegin(GL_QUADS);
|
|
glNormal3f(0,0,1);
|
|
glColor4f(0,0.2,0.8,0.5);
|
|
glVertex4f(-size,-size,-plane[3],1);
|
|
glColor4f(0,0,1,0.5);
|
|
glVertex4f( size,-size,-plane[3],1);
|
|
glColor4f(0.0,0.1,0.5,0.5);
|
|
glVertex4f( size, size,-plane[3],1);
|
|
//glColor4f(back[0],back[1],back[2],1);
|
|
glColor4f(0.0,0.1,0.5,0.5);
|
|
glVertex4f(-size, size,-plane[3],1);
|
|
glEnd();
|
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
|
pop_scene();
|
|
}
|
|
|
|
|
|
//// Animation
|
|
//for(int i = 0;i<(int)balls.size();i++)
|
|
//{
|
|
// balls[i].r[0] += cos(double(i*display_count)/1000.0) + sin(double(display_count)/1000.0);
|
|
// balls[i].r[1] += sin(double(2*i*display_count)/1000.0) + cos(double(2*display_count)/1000.0);
|
|
// balls[i].r[2] += cos(double(3*i*display_count)/1000.0) + sin(double(3*display_count)/1000.0);
|
|
// balls[i].r[3] += sin(double(4*i*display_count)/1000.0) + cos(double(4*display_count)/1000.0);
|
|
// double len =
|
|
// sqrt(balls[i].r[0]*balls[i].r[0]+
|
|
// balls[i].r[1]*balls[i].r[1]+
|
|
// balls[i].r[2]*balls[i].r[2]+
|
|
// balls[i].r[3]*balls[i].r[3]);
|
|
// for(int j = 0;j<4;j++)
|
|
// {
|
|
// balls[i].r[j] /= len;
|
|
// }
|
|
//}
|
|
|
|
report_gl_error();
|
|
glutSwapBuffers();
|
|
glutPostRedisplay();
|
|
|
|
display_count++;
|
|
}
|
|
|
|
void reshape(int width, int height)
|
|
{
|
|
using namespace std;
|
|
::width = width;
|
|
::height = height;
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glViewport(0,0,width,height);
|
|
}
|
|
|
|
void key(unsigned char key, int /*mouse_x*/, int /*mouse_y*/)
|
|
{
|
|
using namespace std;
|
|
|
|
switch(key)
|
|
{
|
|
case char(27):
|
|
exit(0);
|
|
default:
|
|
cout<<"Unknown key command: "<<key<<" "<<int(key)<<endl;
|
|
}
|
|
}
|
|
|
|
void mouse(int glutButton, int glutState, int mouse_x, int mouse_y)
|
|
{
|
|
mouse_y = height-mouse_y;
|
|
using namespace std;
|
|
push_scene();
|
|
if(glutState==1)
|
|
{
|
|
for(int i = 0;i<(int)balls.size();i++)
|
|
{
|
|
balls[i].up(mouse_x,mouse_y);
|
|
balls[i].hover(mouse_x,mouse_y);
|
|
}
|
|
trackball_on = false;
|
|
}else if(glutState==0)
|
|
{
|
|
// down
|
|
bool any = false;
|
|
for(int i = 0;!any && i<(int)balls.size();i++)
|
|
{
|
|
if(glutButton==0)
|
|
{
|
|
any |= balls[i].down(mouse_x,mouse_y);
|
|
}else if(glutButton==2)
|
|
{
|
|
any |= balls[i].right_down(mouse_x,mouse_y);
|
|
}
|
|
}
|
|
trackball_on = !any;
|
|
copy(scene_rot,scene_rot+4,down_scene_rot);
|
|
down_mouse_x = mouse_x;
|
|
down_mouse_y = mouse_y;
|
|
}
|
|
pop_scene();
|
|
}
|
|
|
|
void mouse_drag(int mouse_x, int mouse_y)
|
|
{
|
|
mouse_y = height-mouse_y;
|
|
using namespace std;
|
|
using namespace igl;
|
|
if(trackball_on)
|
|
{
|
|
trackball<double>(
|
|
width,
|
|
height,
|
|
2,
|
|
down_scene_rot,
|
|
down_mouse_x,
|
|
height-down_mouse_y,
|
|
mouse_x,
|
|
height-mouse_y,
|
|
scene_rot);
|
|
}
|
|
push_scene();
|
|
for(int i = 0;i<(int)balls.size();i++)
|
|
{
|
|
balls[i].drag(mouse_x,mouse_y);
|
|
}
|
|
pop_scene();
|
|
|
|
}
|
|
|
|
void mouse_move(int mouse_x, int mouse_y)
|
|
{
|
|
mouse_y = height-mouse_y;
|
|
push_scene();
|
|
bool any = false;
|
|
for(int i = 0;!any && i<(int)balls.size();i++)
|
|
{
|
|
any |= balls[i].hover(mouse_x,mouse_y);
|
|
}
|
|
pop_scene();
|
|
}
|
|
|
|
|
|
int main(int argc,char * argv[])
|
|
{
|
|
using namespace igl;
|
|
using namespace std;
|
|
glutInit(&argc,argv);
|
|
glutInitDisplayString( "rgba depth double samples>=8 ");
|
|
glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH),glutGet(GLUT_SCREEN_HEIGHT)/2);
|
|
glutCreateWindow(__FILE__);
|
|
glutDisplayFunc(display);
|
|
glutReshapeFunc(reshape);
|
|
glutKeyboardFunc(key);
|
|
glutMouseFunc(mouse);
|
|
glutMotionFunc(mouse_drag);
|
|
glutPassiveMotionFunc(mouse_move);
|
|
|
|
//copy(XZ_PLANE_QUAT_D,XZ_PLANE_QUAT_D+4,scene_rot);
|
|
|
|
balls.push_back(BeachBall());
|
|
const int children = 10;
|
|
for(int i = 1;i<=children;i++)
|
|
{
|
|
balls.push_back(BeachBall());
|
|
balls[i].t[0] = 2.5*sin(double(i)*2.0*PI/double(children));
|
|
balls[i].t[1] = 2.5*cos(double(i)*2.0*PI/double(children));
|
|
}
|
|
BeachBall::scene_rot = scene_rot;
|
|
|
|
glutMainLoop();
|
|
return 0;
|
|
}
|