📄 walker.c
字号:
else
fStep = Step = (int)((float)x/glutGet(GLUT_WINDOW_WIDTH) * CYCLE_SIZE);
CurveDownBtn = button;
WasWalking = Walking;
StopWalking();
RedisplayBoth();
} else if (button == CurveDownBtn) {
CurveDownBtn = -1;
if (WasWalking) {
Walking = 1;
agvSetAllowIdle(0);
glutIdleFunc(IncrementStep);
}
}
}
float CurveEditConstrain(float fx)
{
if (CurvePickedPoint == 0)
fx = 0;
else if (CurvePickedPoint == RotCurve[EditingCurve].numpoints-1)
fx = 1;
else if (!(CurvePickedPoint % 3)) { /* is a pivot */
fx = MAX(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint-1]);
fx = MIN(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint+1]);
fx = MAX(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint-3]);
fx = MIN(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint+3]);
} else if (!((CurvePickedPoint - 1) % 3)) { /* is right slope */
fx = MAX(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint-1]);
} else {
fx = MIN(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint+1]);
}
return fx;
}
void RemovePoint(int pt)
{
int i;
for (i = pt - 1; i < RotCurve[EditingCurve].numpoints; i++) {
RotCurve[EditingCurve].xcoords[i] = RotCurve[EditingCurve].xcoords[i+3];
RotCurve[EditingCurve].angles[i] = RotCurve[EditingCurve].angles[i+3];
}
RotCurve[EditingCurve].numpoints -= 3;
}
void AddPoint(float fx)
{
int i, j;
if (fx < 0.05 || fx > 0.95 || RotCurve[EditingCurve].numpoints + 3 >=
MAX_CPOINTS)
return;
for (i = 3; i < RotCurve[EditingCurve].numpoints; i += 3) {
if (fx < RotCurve[EditingCurve].xcoords[i]) {
for (j = RotCurve[EditingCurve].numpoints + 2; j > i + 1; j--) {
RotCurve[EditingCurve].xcoords[j] =
RotCurve[EditingCurve].xcoords[j-3];
RotCurve[EditingCurve].angles[j] =
RotCurve[EditingCurve].angles[j-3];
}
RotCurve[EditingCurve].xcoords[i] = fx;
RotCurve[EditingCurve].angles[i] =
Walk_cycle[0][EditingCurve][(int)(fx*CYCLE_SIZE)];
RotCurve[EditingCurve].xcoords[i-1] = fx - 0.05;
RotCurve[EditingCurve].angles[i-1] =
Walk_cycle[0][EditingCurve][(int)((fx-0.05)*CYCLE_SIZE)];
RotCurve[EditingCurve].xcoords[i+1] = fx + 0.05;
RotCurve[EditingCurve].angles[i+1] =
Walk_cycle[0][EditingCurve][(int)((fx+0.05)*CYCLE_SIZE)];
RotCurve[EditingCurve].numpoints += 3;
break;
}
}
}
void CurveEditHandleButton(int button, int state, int x, int y)
{
float fx, fy;
int point;
fy = -(((float)y - ((float)CurveWHeight/NUM_JOINTS * EditingCurve)) /
((float)CurveWHeight/NUM_JOINTS) - 0.5) * 180.0,
fx = (float)x/CurveWWidth;
if (state == GLUT_DOWN && button == GLUT_LEFT_BUTTON &&
CurveDownBtn == -1) {
CurvePickedPoint = -1;
for (point = 0; point < RotCurve[EditingCurve].numpoints; point++) {
if (fabs(RotCurve[EditingCurve].xcoords[point] - fx) < 0.01 &&
fabs(RotCurve[EditingCurve].angles[point] - fy) < 4) {
CurvePickedPoint = point;
CurveLastX = x;
CurveLastY = y;
glutIdleFunc(CurveCPointDrag);
break;
}
}
if (CurvePickedPoint == -1)
CurveHandleButton(button, state, x, y);
CurveDownBtn = button;
} else if (state == GLUT_DOWN && button == GLUT_MIDDLE_BUTTON &&
CurveDownBtn == -1) {
for (point = 3; point < RotCurve[EditingCurve].numpoints - 1; point += 3) {
if (fabs(RotCurve[EditingCurve].xcoords[point] - fx) < 0.01 &&
fabs(RotCurve[EditingCurve].angles[point] - fy) < 4) {
break;
}
}
if (point >= 3 && point < RotCurve[EditingCurve].numpoints - 1)
RemovePoint(point);
else if (fabs(Walk_cycle[0][EditingCurve][(int)(fx*CYCLE_SIZE)] - fy) < 4)
AddPoint(fx);
ComputeCurve(EditingCurve);
MakeJointLists(EditingCurve);
RedisplayBoth();
} else if (button == GLUT_LEFT_BUTTON && button == CurveDownBtn) {
y = MAX(y, 0); y = MIN(y, CurveWHeight);
x = MAX(x, 0); x = MIN(x, CurveWWidth);
fy = -(((float)y - ((float)CurveWHeight/NUM_JOINTS * EditingCurve)) /
((float)CurveWHeight/NUM_JOINTS) - 0.5) * 180.0,
fx = (float)x/CurveWWidth;
CurveDownBtn = -1;
if (CurvePickedPoint != -1) {
fx = CurveEditConstrain(fx);
RotCurve[EditingCurve].xcoords[CurvePickedPoint] = fx;
RotCurve[EditingCurve].angles[CurvePickedPoint] = fy;
ComputeCurve(EditingCurve);
MakeJointLists(EditingCurve);
glutIdleFunc(NULL);
RedisplayBoth();
}
}
}
void CurveHandleMotion(int x, int y)
{
if (CurvePickedPoint == -1) {
if (CurveDownBtn == GLUT_LEFT_BUTTON || CurveDownBtn ==
GLUT_MIDDLE_BUTTON) {
Step = (int)((float)x/glutGet(GLUT_WINDOW_WIDTH) * CYCLE_SIZE)
% CYCLE_SIZE;
if (Step < 0)
Step = CYCLE_SIZE + Step;
fStep = Step;
RedisplayBoth();
}
} else {
y = MAX(y, 0); y = MIN(y, CurveWHeight);
x = MAX(x, 0); x = MIN(x, CurveWWidth);
CurveLastX = x;
CurveLastY = y;
}
}
void CurveCPointDrag(void)
{
float fx, fy;
if (CurveDownBtn == GLUT_LEFT_BUTTON && CurvePickedPoint != -1) {
fy = -(((float)CurveLastY -
((float)CurveWHeight/NUM_JOINTS * EditingCurve)) /
((float)CurveWHeight/NUM_JOINTS) - 0.5) * 180.0,
fx = (float)CurveLastX/CurveWWidth;
fx = CurveEditConstrain(fx);
RotCurve[EditingCurve].xcoords[CurvePickedPoint] = fx;
RotCurve[EditingCurve].angles[CurvePickedPoint] = fy;
ComputeCurve(EditingCurve);
MakeJointLists(EditingCurve);
RedisplayBoth();
}
}
/* ARGSUSED1 */
void CurveHandleKeys(unsigned char key, int x, int y)
{
if (key > '0' && key < '9')
CurveHandleEditMenu((key-'0')-1);
else if (key == 'd')
CurveHandleMenu(CMENU_DONEEDIT);
else {
switch(key) {
case 'f':
case ' ': Step++;
StopWalking(); break;
case 'F': Step += 5;
StopWalking(); break;
case 'b': Step--;
StopWalking(); break;
case 'B': Step -= 5;
StopWalking(); break;
}
Step %= CYCLE_SIZE;
if (Step < 0)
Step = CYCLE_SIZE + Step;
fStep = Step;
RedisplayBoth();
}
}
void CurveHandleEditMenu(int curve)
{
if (curve >= NUM_JOINTS)
return;
if (EditingCurve == -1) {
WasWalking = Walking;
Walking = 0;
agvSetAllowIdle(0); /* don't allow spinning, just slows us down */
glutIdleFunc(NULL);
glutMouseFunc(CurveEditHandleButton);
}
EditingCurve = curve;
glutPostRedisplay();
}
void CurveHandleSZMenu(int size)
{
IncStep = (float)size/100;
}
void CurveHandleMenu(int value)
{
switch (value) {
case CMENU_QUIT:
exit(0);
break;
case CMENU_CURVE:
CurveAsPoints = !CurveAsPoints;
glutPostRedisplay();
break;
case CMENU_HORIZ:
DrawHorizontals = !DrawHorizontals;
glutPostRedisplay();
break;
case CMENU_WALK:
if (EditingCurve != -1)
break;
Walking = !Walking;
if (Walking) {
agvSetAllowIdle(0);
glutIdleFunc(IncrementStep);
} else {
agvSetAllowIdle(1);
}
break;
case CMENU_DONEEDIT:
glutMouseFunc(CurveHandleButton);
EditingCurve = -1;
CurvePickedPoint = -1;
Walking = WasWalking;
if (Walking)
glutIdleFunc(IncrementStep);
else
agvSetAllowIdle(1);
glutPostRedisplay();
break;
case CMENU_RESET:
FlatCSet();
ComputeCSetAndMakeLists();
glutPostRedisplay();
break;
case CMENU_MIRROR:
MirrorLegs = !MirrorLegs;
ComputeCSetAndMakeLists();
glutPostRedisplay();
}
}
void CurveMenuInit(void)
{
int i;
char label[3];
if (CurveEditMenu != -1) {
glutDestroyMenu(CurveEditMenu);
glutDestroyMenu(CurveMenu);
glutDestroyMenu(StepSizeMenu);
}
CurveEditMenu = glutCreateMenu(CurveHandleEditMenu);
for (i = 0; i < NUM_JOINTS; i++) {
sprintf(label, " %d ", i+1);
glutAddMenuEntry(label, i);
}
StepSizeMenu = glutCreateMenu(CurveHandleSZMenu);
glutAddMenuEntry("0.25", 25);
glutAddMenuEntry("0.5", 50);
glutAddMenuEntry("1.0", 100);
glutAddMenuEntry("2.0", 200);
glutAddMenuEntry("3.0", 300);
glutAddMenuEntry("5.0", 500);
CurveMenu = glutCreateMenu(CurveHandleMenu);
glutAddSubMenu("Load Curve Set", LoadMenu);
glutAddSubMenu("Save As Curve Set", SaveMenu);
glutAddSubMenu("Edit Curve", CurveEditMenu);
glutAddMenuEntry("Done Editing", CMENU_DONEEDIT);
glutAddMenuEntry("Flatten Curve Set", CMENU_RESET);
glutAddMenuEntry("Toggle mirrored", CMENU_MIRROR);
glutAddSubMenu("Step size", StepSizeMenu);
glutAddMenuEntry("Toggle dotted", CMENU_CURVE);
glutAddMenuEntry("Toggle horizontals", CMENU_HORIZ);
glutAddMenuEntry("Toggle walking", CMENU_WALK);
glutAddMenuEntry("Quit", CMENU_QUIT);
glutSetWindow(CurveWindow);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
void CurveVisible(int v)
{
if (v == GLUT_VISIBLE)
CurveWindowVisible = 1;
else
CurveWindowVisible = 0;
}
/***************************************************************/
/*********************** GUY WINDOW ****************************/
/***************************************************************/
void GuyDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFlush();
glLoadIdentity();
agvViewTransform();
if (DrawAxes)
glCallList(AxesList);
switch(GuyModel) {
case WIRECUBE: DrawTheGuy_WC(); break;
case SOLIDCUBE: DrawTheGuy_SC(); break;
case CYLINDER1: DrawTheGuy_SL(); break;
case CYLINDER2: DrawTheGuy_SL2(); break;
}
glutSwapBuffers();
glFlush();
}
void GuyReshape(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (ViewPerspective)
gluPerspective(60.0, (GLdouble)w/h, 0.01, 100);
else
glOrtho(-1.2, 1.2, -1.2, 1.2, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glFlush();
}
void GuyGLInit(void)
{
GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 0.3, 0.5, 0.8, 0.0 };
GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glShadeModel(GL_SMOOTH);
/* Cylinder stuff */
StoreTheGuy_SL();
StoreTheGuy_SL2();
}
void GuyHandleKeys(unsigned char key, int x, int y)
{
switch(key) {
case 'f':
case ' ': Step++;
StopWalking(); break;
case 'F': Step += 5;
StopWalking(); break;
case 'b': Step--;
StopWalking(); break;
case 'B': Step -= 5;
StopWalking(); break;
}
Step %= CYCLE_SIZE;
if (Step < 0)
Step = CYCLE_SIZE + Step;
agvHandleKeys(key, x, y);
RedisplayBoth();
}
typedef enum { GMENU_QUIT, GMENU_CURVE, GMENU_HORIZ,
GMENU_AXES, GMENU_PERSP } GuyMenuChoices;
void GuyModelHandleMenu(int model)
{
GuyModel = model;
if (model == WIRECUBE)
glDisable(GL_LIGHTING);
else
glEnable(GL_LIGHTING);
glutPostRedisplay();
}
void GuyHandleMenu(int value)
{
switch (value) {
case GMENU_QUIT:
exit(0);
break;
case GMENU_AXES:
DrawAxes = !DrawAxes;
glutPostRedisplay();
break;
case GMENU_PERSP:
ViewPerspective = !ViewPerspective;
GuyReshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
glutPostRedisplay();
break;
}
}
void GuyMenuInit(void)
{
int sub2, sub1 = glutCreateMenu(agvSwitchMoveMode);
glutAddMenuEntry("Flying move", FLYING);
glutAddMenuEntry("Polar move", POLAR);
sub2 = glutCreateMenu(GuyModelHandleMenu);
glutAddMenuEntry("Wire cubes", WIRECUBE);
glutAddMenuEntry("Solid cubes", SOLIDCUBE);
glutAddMenuEntry("Cylinder 1", CYLINDER1);
glutAddMenuEntry("Cylinder 2", CYLINDER2);
glutCreateMenu(GuyHandleMenu);
glutAddSubMenu("Viewing", sub1);
glutAddSubMenu("Model", sub2);
glutAddMenuEntry("Toggle Axes", GMENU_AXES);
glutAddMenuEntry("Toggle Perspective View", GMENU_PERSP);
glutAddMenuEntry("Quit", GMENU_QUIT);
glutSetWindow(GuyWindow);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
/***************************************************************/
/********************* BOTH WINDOWS ****************************/
/***************************************************************/
void RedisplayBoth(void)
{
glutPostWindowRedisplay(GuyWindow);
if (CurveWindowVisible) {
glutPostWindowRedisplay(CurveWindow);
}
}
void IncrementStep(void)
{
fStep = fmod(fStep + IncStep, CYCLE_SIZE);
Step = (int)fStep;
if (agvMoving)
agvMove();
RedisplayBoth();
}
void StopWalking(void)
{
if (Walking) {
Walking = 0;
agvSetAllowIdle(1);
}
}
void SetWindowTitles(char *csetname)
{
char windowtitle[MAX_CSETNAMELEN + 20];
strcpy(windowtitle, "Rotation Curves: ");
strcat(windowtitle, csetname);
glutSetWindow(CurveWindow);
glutSetWindowTitle(windowtitle);
strcpy(windowtitle, "The Guy: ");
strcat(windowtitle, csetname);
glutSetWindow(GuyWindow);
glutSetWindowTitle(windowtitle);
}
/***************************************************************/
/***************************** MAIN ****************************/
/***************************************************************/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(512, 512);
glutInitWindowPosition(700, 250);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
GuyWindow = glutCreateWindow("The Guy:");
agvInit(!Walking);
AxesList = glGenLists(1);
agvMakeAxesList(AxesList);
GuyGLInit();
GuyMenuInit();
glutDisplayFunc(GuyDisplay);
glutReshapeFunc(GuyReshape);
glutKeyboardFunc(GuyHandleKeys);
glutInitWindowSize(512, 1024);
glutInitWindowPosition(100, 0);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
CurveWindow = glutCreateWindow("Rotation Curves:");
CurveGLInit();
glutDisplayFunc(CurveDisplay);
glutReshapeFunc(CurveReshape);
glutMouseFunc(CurveHandleButton);
glutMotionFunc(CurveHandleMotion);
glutKeyboardFunc(CurveHandleKeys);
glutVisibilityFunc(CurveVisible);
FlatCSet();
MakeLists();
if (MakeLoadAndSaveMenus() > 0) /* read first curve if there was one */
HandleLoadMenu(0);
CurveMenuInit();
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -