#include <iostream>
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <windows.h>
#include "bmp.h"
#include "geometry.h"
using namespace std;
#define PI 3.14159
// texture handle
unsigned int floorTexture;
// function prototypes
void initializeTexture();
void display(void);
void reshape(int width, int height);
void keyboard(unsigned char key, int x, int y);
void motion(int x, int y);
void main_menu(int value);
void init(void);
void idle(void);
void robot(void);
void head(void);
void body(void);
void leg(void);
void arm(void);
void floor(void);
void rotateRobot(void);
unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader);
static enum {
ZOOM_IN,
ZOOM_OUT,
HEAD_UP,
HEAD_DOWN,
ALL_VIEW,
ROBOT_EYE,
FOG_ON,
FOG_OFF,
ROOM_LIGHT_ON,
ROOM_LIGHT_OFF,
POINT_LIGHT_ON,
POINT_LIGHT_OFF,
SPOT_ON,
SPOT_OFF
};
// viewpoint
double theta=0, phi=0, d=100;
double globalRight[3] = {1,0,0};
double center[3]={0,0,0};
double up[3]={0,1,0};
// window
int width = 800;
int height = 800;
int spin;
int allViewAni = 0;
int headBang=0;
int xTranslate;
int zTranslate;
//fog
GLfloat density = 0.01;
GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0};
float TorusRotated = 0.0;
float shoulder, elbow, wrist = 0.0;
int spot=0;
static GLfloat MatSpec[] = {1.0,1.0,1.0,1.0};
static GLfloat MatShininess[] = {45.0};
float pointLightPosition[]={-3.0f,2.0f,0.0f,1.0f};
float SpotLightPos[] = {0.0,0.0,30.0,1.0};
float spotDir[]={0.0f,0.0f,1.0f}; // spot light direction
//color material
GLfloat white[] = {1.0f,1.0f,1.0f,1.0f}; // white
GLfloat purple[] = {1.0f,0.0f,1.0f,1.0f}; // purple
GLfloat green[] = {0.0f,1.0f,0.0f,1.0f}; // green
GLfloat blue[] = {0.0f,0.0f,1.0f,1.0f}; // blue
//quadricObj for cylinder
GLUquadricObj *quadObj = gluNewQuadric();
void main_menu(int value)
{
switch (value) {
case ZOOM_IN:
cout << "zoom in." << endl;
d=d-10;
display();
break;
case ZOOM_OUT: //zoom out
cout << "zoom out." <<endl;
if(d>10){
d=d+10;
display();
}
break;
case HEAD_UP: //head node
headBang -= 15.0;
display();
break;
case HEAD_DOWN: //head node
headBang += 15.0;
display();
break;
case ALL_VIEW:
allViewAni = 1 - allViewAni; //Toggle
if (allViewAni){
glutIdleFunc(rotateRobot);
display();
} else {
glutIdleFunc(NULL);
display();
}
break;
case ROBOT_EYE:
break;
case FOG_ON:
glEnable (GL_FOG); //enable the fog
glFogi (GL_FOG_MODE, GL_EXP2);
glFogfv (GL_FOG_COLOR, fogColor);
glFogf (GL_FOG_DENSITY, density);
glHint (GL_FOG_HINT, GL_NICEST);
display();
break;
case FOG_OFF:
glDisable (GL_FOG);
display();
break;
case ROOM_LIGHT_ON:
glEnable (GL_LIGHT0);
display();
break;
case ROOM_LIGHT_OFF:
glDisable (GL_LIGHT0);
display();
break;
case POINT_LIGHT_ON:
glEnable (GL_LIGHT1);
display();
break;
case POINT_LIGHT_OFF:
glDisable (GL_LIGHT1);
display();
break;
case SPOT_ON:
glEnable (GL_LIGHT2);
spot = 1;
display();
break;
case SPOT_OFF:
glDisable (GL_LIGHT2);
spot=0;
display();
break;
case 666:
exit(0);
break;
}
}
void
rotateRobot(void)
{
spin += 2;
spin = spin % 360;
glutPostRedisplay();
}
int main(int argc, char **argv)
{
// set up window
glutInitWindowSize(400, 400);
glutInit(&argc, argv);
//glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_STENCIL);
glutCreateWindow("Viewpoint Demo");
// register callback functions
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMotionFunc(motion);
glutIdleFunc(idle);
// initalize opengl parameters
init();
//glutHideWindow();
glutCreateMenu(main_menu);
glutAddMenuEntry("zoom in", ZOOM_IN);
glutAddMenuEntry("zoom out", ZOOM_OUT);
glutAddMenuEntry("head up", HEAD_UP);
glutAddMenuEntry("head down", HEAD_DOWN);
glutAddMenuEntry("360 view", ALL_VIEW);
glutAddMenuEntry("robot eye view", ROBOT_EYE);
glutAddMenuEntry("fog on", FOG_ON);
glutAddMenuEntry("fog off", FOG_OFF);
glutAddMenuEntry("room light on", ROOM_LIGHT_ON);
glutAddMenuEntry("room light off", ROOM_LIGHT_OFF);
glutAddMenuEntry("point light on", POINT_LIGHT_ON);
glutAddMenuEntry("point light off", POINT_LIGHT_OFF);
glutAddMenuEntry("SPOT light on", SPOT_ON);
glutAddMenuEntry("SPOT light off", SPOT_OFF);
glutAddMenuEntry("Quit", 666);
glutAttachMenu(GLUT_RIGHT_BUTTON);
// loop until something happens
glutMainLoop();
return 0;
}
void init()
{
// initialize viewing system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, 1.0, 1.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
// create some ambient light
float ambient[]={0.5f,0.5f,0.5f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
// create a point light
float pointLightColor[]={1.0f,1.0f,1.0f,1.0f};
glLightfv(GL_LIGHT1, GL_POSITION, pointLightPosition);
glLightfv(GL_LIGHT1, GL_DIFFUSE, pointLightColor);
glLightfv(GL_LIGHT1, GL_SPECULAR, pointLightColor);
// set spot light position
glLightfv(GL_LIGHT2,GL_POSITION,SpotLightPos);
glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, spotDir);
glLightf(GL_LIGHT2, GL_SPOT_CUTOFF,45.0); // set cutoff angle
glLightf(GL_LIGHT2, GL_SPOT_EXPONENT,7.0); // set focusing strength
// enable lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0); //ROOM - AMBIENT
glEnable(GL_LIGHT1); //POINT
glEnable(GL_LIGHT2); //SPOT
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
// initialize graphics
initializeTexture();
}
void reshape(int newWidth, int newHeight)
{
width = newWidth;
height = newHeight;
// preserve aspect ratio
if (width < height)
glViewport(0,0,width,width);
else
glViewport(0,0,height,height);
}
void display()
{
GLfloat position[] = { 10.0, 20.0, 10.0, 1.0 };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
double eye[3]={0,0,0};
eye[0] = center[0] + (float) d * cos(theta) * sin(phi);
eye[1] = center[1] + (float) d * sin(theta);
eye[2] = center[2] + (float) d * cos(theta) * cos(phi);
glPushMatrix();
//glTranslatef(0.0,20.0,0.0);
gluLookAt(eye[0],eye[1],eye[2], center[0],center[1],center[2],up[0], up[1], up[2]);
glPushMatrix();
glTranslated (0.0, 0.0, 1.5);
//glDisable (GL_LIGHTING);
//glEnable (GL_LIGHTING);
glPopMatrix();
//draw shapes
floor();
robot();
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void robot(){
glPushMatrix();
glRotatef(spin, 0.0, 1.0, 0.0); //360 view
glTranslatef(xTranslate,0.0,0.0); //left right
glTranslatef(0.0,0.0,zTranslate); //up down
glPushMatrix();
head();
body();
leg();
arm();
glPopMatrix();
glPopMatrix();
}
void arm(){
glPushMatrix();
glTranslatef(3.5,10.0,0.0);
glRotatef(shoulder, 1.0,0.0,0.0);
glPushMatrix();
glTranslatef(0.0,0.0,0.0); //upper arm
glPushMatrix();
glTranslatef(0.0,-2.0,0.0); //elbow
glRotatef(elbow, 1.0,0.0,0.0);
glPushMatrix();
glTranslatef(0.0,-1.0,0.0); //lower arm
glPushMatrix();
glTranslatef(0.0,-1.0,0.0); //wrist
glRotatef(wrist, 1.0,0.0,0.0);
glPushMatrix();
//hand
glTranslatef(0.0,-2.0,0.0);
glRotatef(-90.0, 1.0, 0.0, 0.0); //rotate on the x axis
gluCylinder(quadObj,0.0f,0.5f,2.0f,15,15);
glPopMatrix();
//wrist
glMaterialfv(GL_FRONT, GL_DIFFUSE, green);
glutSolidSphere(1.0,20,10);
glPopMatrix();
//lower arm
glRotatef(90.0, 1.0, 0.0, 0.0); //rotate on the z axis
glMaterialfv(GL_FRONT, GL_DIFFUSE, purple);
gluCylinder(quadObj,0.5f,0.5f,1.0f,15,15);
glPopMatrix();
//elbow
glMaterialfv(GL_FRONT, GL_DIFFUSE, green);
glutSolidSphere(1.0,20,10);
glPopMatrix();
//upper arm
glRotatef(90.0, 1.0, 0.0, 0.0); //rotate on the z axis
glMaterialfv(GL_FRONT, GL_DIFFUSE, purple);
gluCylinder(quadObj,0.5f,0.5f,2.0f,15,15);
glPopMatrix();
glMaterialfv(GL_FRONT, GL_DIFFUSE, green);
glutSolidSphere(1.0,20,10);
glPopMatrix();
}
void head(){
//head
glPushMatrix();
glTranslatef(0.0,13.0,0.0);
glRotatef(headBang, 1.0,0.0,0.0);
//hat
glPushMatrix();
glTranslatef(0.0,1.5,0.0);
glRotatef(90.0, 1.0,0.0,0.0);
glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
glMateriali(GL_FRONT,GL_SHININESS,10);
glutSolidTorus(0.3,2.5,8,16);
glPopMatrix();
glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
glMateriali(GL_FRONT,GL_SHININESS,20);
glutSolidSphere(3.0,20,20);
glPopMatrix();
}
void body(){
//body
glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
glPushMatrix();
glTranslatef(0.0,12.0,0.0);
glRotatef(90.0, 1.0, 0.0, 0.0); //rotate on the z axis
gluCylinder(quadObj,3.0f,3.0f,8.0f,15,15);
glPopMatrix();
}
void leg(){
glPushMatrix();
glTranslatef(0.0,3.0,0.0);
glutSolidCube(2);
glPopMatrix();
}
void floor(){
glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
glMateriali(GL_FRONT,GL_SHININESS,40);
glNormal3f(0,1,0);
glBegin(GL_QUADS);
glVertex3f(-50.0,2.0,-50.0);
glVertex3f(-50.0,2.0,50.0);
glVertex3f(50.0,2.0,50.0);
glVertex3f(50.0,2.0,-50.0);
glEnd();
/*
//glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
//glNormal3f(0,1,0);
glMateriali(GL_FRONT,GL_SHININESS,40);
glPushMatrix();
glDisable(GL_TEXTURE_2D);
glEnd();
glVertex3f(50.0,2.0,-50.0);
//glTexCoord2f(1,0);
glVertex3f(50.0,2.0,50.0);
//glTexCoord2f(1,1);
glVertex3f(-50.0,2.0,50.0);
//glTexCoord2f(0,1);
glVertex3f(-50.0,2.0,-50.0);
//glTexCoord2f(0,0);
glBegin(GL_QUADS);
glBindTexture(GL_TEXTURE_2D, floorTexture);
glEnable(GL_TEXTURE_2D);
glPopMatrix();
glMateriali(GL_FRONT,GL_SHININESS,40);
glNormal3f(0,1,0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, floorTexture);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex3f(-50.0,2.0,-50.0);
glTexCoord2f(0,1);
glVertex3f(-50.0,2.0,50.0);
glTexCoord2f(1,1);
glVertex3f(50.0,2.0,50.0);
glTexCoord2f(1,0);
glVertex3f(50.0,2.0,-50.0);
glEnd();
*/
}
void keyboard(unsigned char key, int mouseX, int mouseY)
{
switch (key) {
case 'h':
cout << "You should add instructions on your UI. " <<endl;
cout << "'d' is change center of attntion of camera ->right " <<endl;
cout << "'a' is change center of attntion of camera ->left" <<endl;
cout << "'s' is change center of attntion of camera ->up " <<endl;
cout << "'w' is change center of attntion of camera ->down " <<endl;
cout << "'p' is play ani " <<endl;
break;
case 'j': //left
xTranslate -= 2;
display();
break;
case 'l': //right
xTranslate += 2;
display();
break;
case 'i': //up
zTranslate -= 2;
display();
break;
case 'k': //down
zTranslate += 2;
display();
break;
case 'd': //4. change center of attntion ->right
center[0] = center[0] + (globalRight[0]*(-5));
display();
break;
case 'a': //4. change center of attntion ->left
center[0] = center[0] + (globalRight[0]*5);
display();
break;
case 's': //4. change center of attntion ->up
center[1] = center[1] + (up[1]*(-5));
// Position = Position + (UpVector*Distance);
display();
break;
case 'w': //4. change center of attntion ->down
center[1] = center[1] + (up[1]*5);
display();
break;
case 'z':
shoulder -= 2.0;
display();
break;
case 'x':
elbow -= 2.0;
display();
break;
case 'c':
wrist -= 2.0;
display();
break;
case 'm':
spot += 1;
if (spot = 1)
spot -= 1;
display();
break;
//case 'l': //fog
}
glutPostRedisplay();
}
/*******************************************************************
* BMP reader from: Program: Chapter 7 Bitmap Example 4
* Author: Kevin Hawkins
*
********************************************************************/
// LoadBitmapFile
// desc: Returns a pointer to the bitmap image of the bitmap specified
// by filename. Also returns the bitmap header information.
// No support for 8-bit bitmaps.
unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
FILE *filePtr; // the file pointer
BITMAPFILEHEADER bitmapFileHeader; // bitmap file header
unsigned char *bitmapImage; // bitmap image data
unsigned int imageIdx = 0; // image index counter
unsigned char tempRGB; // swap variable
// open filename in "read binary" mode
filePtr = fopen(filename, "rb");
if (filePtr == NULL)
return NULL;
// read the bitmap file header
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
// verify that this is a bitmap by checking for the universal bitmap id
if (bitmapFileHeader.bfType != BITMAP_ID)
{
fclose(filePtr);
return NULL;
}
// read the bitmap information header
fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);
// move file pointer to beginning of bitmap data
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
// allocate enough memory for the bitmap image data
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
// verify memory allocation
if (!bitmapImage)
{
free(bitmapImage);
fclose(filePtr);
return NULL;
}
// read in the bitmap image data
fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);
// make sure bitmap image data was read
if (bitmapImage == NULL)
{
fclose(filePtr);
return NULL;
}
// swap the R and B values to get RGB since the bitmap color format is in BGR
for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}
// close the file and return the bitmap image data
fclose(filePtr);
return bitmapImage;
}
/*
* This routine reads mouse movement and adjusts
* camera position/orientation.
*/
void motion(int x, int y)
{
static int currX=-1;
static int currY=-1;
// wait until a mouse position is recorded and
// avoid really big jumps
if (currX>0 && abs(x-currX) < width/6 && abs(y-currY) < height/6) {
phi += (double) (x-currX)/ (double) width * 3.14159;
theta += (double) (y-currY)/ (double) height * 3.14159;
// limit theta to -4pi/9 and 4pi/9
// it is disorienting to lose "up"
if (theta < -4*3.14159/9.0)
theta = -4*3.14159/9.0;
if (theta > 4*3.14159/9.0)
theta = 4*3.14159/9.0;
}
currX = x;
currY = y;
glutPostRedisplay();
}
void idle(void)
{
}
void initializeTexture()
{
// read in the texture
// the texture file name is hard coded as ball.bmp
BITMAPINFOHEADER bitmapInfoHeader; // bitmap info header
unsigned char* bitmapData; // the bitmap data
bitmapData = LoadBitmapFile("check.bmp", &bitmapInfoHeader);
//adding texture part
// generate texture object
glGenTextures(1,&floorTexture);
// create texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, floorTexture);
//end of adding texture
// the following two commands tell openGL how to interpolate texture
// values between the sampled values in your texture bitmap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// the following two commands tell openGL how to extend the texture
// when needed
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// now give it the texture map
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmapInfoHeader.biWidth,
bitmapInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
bitmapData);
glDisable(GL_TEXTURE_2D);
}
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630:
631:
632:
633:
634:
635:
636:
637:
638:
639:
640:
641:
642:
643:
644:
645:
646:
647:
648:
649:
650:
651:
652:
653:
654:
655:
656:
657:
658:
659:
660:
661:
662:
663:
664:
665:
666:
667:
668:
669:
670:
671:
672:
673:
674:
675:
676:
677:
678:
679:
680:
681:
682:
683:
684:
685:
686:
687:
688:
689:
690:
691:
692:
693:
694:
695:
696:
697: