changed: auto add updateData callback to stages so that stagedata can be updated...
[opensg.git] / Source / WindowSystem / Cocoa / testWindowCocoa.mm
blob80021e9be993270b31ee2b8feb9c4ca0f15701b4
1 #include "OSGConfig.h"
3 #include <iostream>
5 #import <Cocoa/Cocoa.h>
7 #ifdef check
8 # undef check
9 #endif
11 #include "OSGFieldContainerFactory.h"
12 #include "OSGVector.h"
13 #include "OSGQuaternion.h"
14 #include "OSGMatrix.h"
15 #include "OSGMatrixUtility.h"
16 #include "OSGBoxVolume.h"
17 #include "OSGNode.h"
18 #include "OSGGroup.h"
19 #include "OSGTransform.h"
20 #include "OSGSimpleGeometry.h"
21 #include "OSGAction.h"
22 #include "OSGRenderAction.h"
23 #include "OSGSceneFileHandler.h"
24 #include "OSGDirectionalLight.h"
26 #include "OSGViewport.h"
27 #include "OSGCamera.h"
28 #include "OSGWindow.h"
29 #include "OSGCocoaWindow.h"
30 #include "OSGCamera.h"
31 #include "OSGPerspectiveCamera.h"
32 #include "OSGSolidBackground.h"
34 #include "OSGTrackball.h"
36 // This prevents warnings that "NSApplication might not
37 // respond to setAppleMenu" on OS X 10.4
38 @interface NSApplication(OpenSG)
39 - (void)setAppleMenu:(NSMenu *)menu;
40 @end
42 using namespace OSG;
44 CocoaWindowUnrecPtr    win;
46 RenderActionRefPtr   ract;
47 NodeRecPtr           root;
48 NodeRecPtr           file;
49 ViewportRecPtr   vp;
50 TransformRecPtr  cam_trans;
51 Trackball     tball;
52 PerspectiveCameraRecPtr cam;
54 bool          stopIt = false;
55 int           lastx=0, lasty=0;
57 void redraw ( void )
59     fprintf(stderr, "redraw\n");
60     Matrix m1, m2, m3;
61     Quaternion q1;
63     tball.getRotation().getValue(m3);
64     q1.setValue(m3);
65     m1.setRotate(q1);
66     m2.setTranslate( tball.getPosition() );
67     m1.mult( m2 );
68     cam_trans->editSFMatrix()->setValue( m1 );
70     Thread::getCurrentChangeList()->commitChanges();
72     win->render(ract);
75 @interface MyOpenGLView: NSOpenGLView
78 - (BOOL) acceptsFirstResponder;
80 - (void) handleMouseEvent: (NSEvent*) event;
82 - (void) mouseDown: (NSEvent*) event;
83 - (void) mouseDragged: (NSEvent*) event;
84 - (void) mouseUp: (NSEvent*) event;
85 - (void) rightMouseDown: (NSEvent*) event;
86 - (void) rightMouseDragged: (NSEvent*) event;
87 - (void) rightMouseUp: (NSEvent*) event;
88 - (void) otherMouseDown: (NSEvent*) event;
89 - (void) otherMouseDragged: (NSEvent*) event;
90 - (void) otherMouseUp: (NSEvent*) event;
92 - (void) keyDown: (NSEvent*) event;
94 - (void) reshape;
95 - (void) drawRect: (NSRect) bounds;
96 @end
98 @implementation MyOpenGLView
100 - (BOOL) acceptsFirstResponder
102     return YES;
105 - (void) handleMouseEvent: (NSEvent*) event
107     Real32 w,h,a,b,c,d;
109     int buttonNumber = [event buttonNumber];
110     unsigned int modifierFlags = [event modifierFlags];
112     // Traditionally, Apple mice just have one button. It is common practice to simulate
113     // the middle and the right button by pressing the option or the control key.
114     if (buttonNumber == 0)
115     {
116         if (modifierFlags & NSAlternateKeyMask)
117             buttonNumber = 2;
118         if (modifierFlags & NSControlKeyMask)
119             buttonNumber = 1;
120     }
122     NSPoint location = [event locationInWindow];
124     switch ([event type])
125     {
126     case NSLeftMouseDown:
127     case NSRightMouseDown:
128     case NSOtherMouseDown:
129         lastx = static_cast<int>(location.x);
130         lasty = static_cast<int>(location.y);
131         switch (buttonNumber)
132         {
133         case 0: // left button
134             break;
135         case 1: // right button
136             tball.setAutoPositionNeg(true);
137             break;
138         case 2: // middle button
139             tball.setAutoPosition(true);
140             break;
141         }
142         break;
144     case NSLeftMouseUp:
145     case NSRightMouseUp:
146     case NSOtherMouseUp:
147         switch (buttonNumber)
148         {
149         case 0: // left button
150             break;
151         case 1: // right button
152             tball.setAutoPositionNeg(false);
153             break;
154         case 2: // middle button
155             tball.setAutoPosition(false);
156             break;
157         }
158         break;
160     case NSLeftMouseDragged:
161     case NSRightMouseDragged:
162     case NSOtherMouseDragged:
163         w = win->getWidth();
164         h = win->getHeight();
165         a = -2. * ( lastx / w - .5 );
166         b = -2. * ( lasty / h - .5);
167         c = -2. * ( location.x / w - .5 );
168         d = -2. * ( location.y / h - .5 );
169         switch (buttonNumber)
170         {
171         case 0: // left button
172             tball.updateRotation( a, b, c, d );
173             break;
174         case 1: // right button
175             tball.updatePositionNeg( a, b, c, d );
176             break;
177         case 2: // middle button
178             tball.updatePosition( a, b, c, d );
179             break;
180         }
181         lastx = static_cast<int>(location.x);
182         lasty = static_cast<int>(location.y);
183         redraw();
184         break;
186     default:
187         break;
188     }
191 - (void) mouseDown: (NSEvent*) event
193     [self handleMouseEvent: event];
196 - (void) mouseDragged: (NSEvent*) event
198     [self handleMouseEvent: event];
201 - (void) mouseUp: (NSEvent*) event
203     [self handleMouseEvent: event];
206 - (void) rightMouseDown: (NSEvent*) event
208     [self handleMouseEvent: event];
211 - (void) rightMouseDragged: (NSEvent*) event
213     [self handleMouseEvent: event];
216 - (void) rightMouseUp: (NSEvent*) event
218     [self handleMouseEvent: event];
221 - (void) otherMouseDown: (NSEvent*) event
223     [self handleMouseEvent: event];
226 - (void) otherMouseDragged: (NSEvent*) event
228     [self handleMouseEvent: event];
231 - (void) otherMouseUp: (NSEvent*) event
233     [self handleMouseEvent: event];
236 - (void) keyDown: (NSEvent*) event
238     if ([[event characters] length] != 1)
239         return;
240     switch ([[event characters] characterAtIndex: 0])
241     {
242     case 27:
243 //        [NSApp terminate:nil];
244         [NSApp stop:nil];
245         break;
246     case 'a':
247         glDisable( GL_LIGHTING );
248         redraw();
249         break;
250     case 's':
251         glEnable( GL_LIGHTING );
252         redraw();
253         break;
254     case 'z':
255         glPolygonMode( GL_FRONT_AND_BACK, GL_POINT);
256         redraw();
257         break;
258     case 'x':
259         glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
260         redraw();
261         break;
262     case 'c':
263         glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
264         redraw();
265         break;
266     default:
267         break;
268     }
271 - (void) reshape
273     [self update];
274     NSRect frame = [self bounds];
275     win->resize(static_cast<int>(frame.size.width), static_cast<int>(frame.size.height));
278 - (void) drawRect: (NSRect) bounds
280     redraw();
283 @end
285 @interface MyDelegate : NSObject
288     NSWindow *window;
289     MyOpenGLView *glView;
292 - (void) applicationWillFinishLaunching: (NSNotification*) notification;
294 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) application;
296 - (void) performer: (id) userInfo;
298 @end
300 @implementation MyDelegate
302 - (void) performer: (id) userInfo
304     fprintf(stderr, "perform\n");
308 - (void) dealloc
310     [window release];
311     [super dealloc];
314 - (void) applicationWillFinishLaunching: (NSNotification*) notification
316     /* Set up the menubar */
317     [NSApp setMainMenu:[[NSMenu alloc] init]];
319     NSString *appName = @"testWindowCocoa";
320     NSMenu *appleMenu = [[NSMenu alloc] initWithTitle:@""];
322     /* Add menu items */
324     NSMenu *servicesMenu = [[NSMenu alloc] initWithTitle:@""];
325     NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:@"Services" action:nil keyEquivalent:@""];
326     [menuItem setSubmenu:servicesMenu];
327     [appleMenu addItem:menuItem];
328     [NSApp setServicesMenu: servicesMenu];
330     [appleMenu addItem:[NSMenuItem separatorItem]];
332     NSString *title = [@"Hide " stringByAppendingString:appName];
333     [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
335     menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
336     [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
338     [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
340     [appleMenu addItem:[NSMenuItem separatorItem]];
342     title = [@"Quit " stringByAppendingString:appName];
343     [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
345     /* Put menu into the menubar */
346     menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
347     [menuItem setSubmenu:appleMenu];
348     [[NSApp mainMenu] addItem:menuItem];
350     /* Tell the application object that this is now the application menu */
351     [NSApp setAppleMenu:appleMenu];
353     /* Finally give up our references to the objects */
354     [appleMenu release];
355     [menuItem release];
357     // Create the window
358     window = [NSWindow alloc];
359     NSRect rect = { { 0, 0 }, { 300, 300 } };
360     [window initWithContentRect: rect styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask) backing: NSBackingStoreBuffered defer: YES];
361     [window setTitle: @"testWindowCocoa"];
362     [window setReleasedWhenClosed: NO];
364     glView = [[MyOpenGLView alloc] autorelease];
365     [glView initWithFrame: rect];
366     [glView setAutoresizingMask: NSViewMaxXMargin | NSViewWidthSizable | NSViewMaxYMargin | NSViewHeightSizable];
367     [[window contentView] addSubview: glView];
369     NSOpenGLPixelFormatAttribute attrs[] =
370     {
371         NSOpenGLPFAWindow,
372         NSOpenGLPFADoubleBuffer,
373         NSOpenGLPFADepthSize, NSOpenGLPixelFormatAttribute(16),
374         NSOpenGLPixelFormatAttribute(0)
375     };
376     NSOpenGLPixelFormat *pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: attrs];
377     [glView setPixelFormat: pixFmt];
379     // Create OpenSG window
380     win = CocoaWindow::create();
381     win->addPort( vp );
382     win->setContext ( [glView openGLContext] );
383     win->init();
384     win->resize( 300, 300 );
386     win->activate();
388     // do some OpenGL init. Will move into State Chunks later.
390     glEnable( GL_DEPTH_TEST );
391     glEnable( GL_LIGHTING );
392     glEnable( GL_LIGHT0 );
394         // Show the window
395     [window makeKeyAndOrderFront: nil];
396     [window makeFirstResponder:glView];
399 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) application
401     return YES;
404 @end
406 void doPerform(id userInfo)
408     fprintf(stderr, "perform\n");
411 // A magic method that allows applications to react to events even
412 // when they are not organized in a bundle
413 void osx_AllowForeground()
415     ProcessSerialNumber psn = { 0, kCurrentProcess };
416     TransformProcessType(&psn, kProcessTransformToForegroundApplication);
417     SetFrontProcess(&psn);
420 int doMain(int argc, char *argv[])
422     osx_AllowForeground();
424     // OSG init
425     osgInit(argc, argv);
427     // create the graph
429     // beacon for camera and light
430     NodeUnrecPtr b1n = Node::create();
431     GroupUnrecPtr b1 = Group::create();
432     b1n->setCore( b1 );
434     // transformation
435     NodeUnrecPtr t1n = Node::create();
436     TransformUnrecPtr t1 = Transform::create();
437     t1n->setCore( t1 );
438     t1n->addChild( b1n );
440     cam_trans = t1;
442     // light
444     NodeUnrecPtr dlight = Node::create();
445     DirectionalLightUnrecPtr dl = DirectionalLight::create();
447     dlight->setCore( dl );
449     dl->setAmbient( .3, .3, .3, 1 );
450     dl->setDiffuse( 1, 1, 1, 1 );
451     dl->setDirection(0,0,1);
452     dl->setBeacon( b1n);
454     // root
455     root = Node::create();
456     GroupUnrecPtr gr1 = Group::create();
458     root->setCore( gr1 );
459     root->addChild( t1n );
460     root->addChild( dlight );
462     // Load the file
464     NodeUnrecPtr file = NULL;
466     if ( argc > 1 )
467         file = SceneFileHandler::the()->read(argv[1]);
469     if ( file == NULL )
470     {
471         std::cerr << "Couldn't load file, ignoring" << std::endl;
472         file = makeTorus( .5, 2, 16, 16 );
473     }
475     Thread::getCurrentChangeList()->commitChanges();
476     file->updateVolume();
478     Vec3f min,max;
479     file->getVolume().getBounds( min, max );
481     std::cout << "Volume: from " << min << " to " << max << std::endl;
483     dlight->addChild( file );
485     std::cerr << "Tree: " << std::endl;
486     //root->dump();
488     // Camera
489     cam = PerspectiveCamera::create();
491     cam->setBeacon( b1n );
492     cam->setFov( osgDegree2Rad( 90 ) );
493     cam->setNear( 0.1 );
494     cam->setFar( 100000 );
496     // Background
497     SolidBackgroundUnrecPtr bkgnd = SolidBackground::create();
499     bkgnd->setColor(Color3f(0,0,1));
501     // Viewport
503     vp = Viewport::create();
504     vp->setCamera( cam );
505     vp->setBackground( bkgnd );
506     vp->setRoot( root );
507     vp->setSize( 0,0, 1,1 );
509     // Action
511     ract = RenderAction::create();
513     // tball
515     Vec3f pos;
516     pos.setValues(min[0] + ((max[0] - min[0]) * 0.5), 
517                   min[1] + ((max[1] - min[1]) * 0.5), 
518                   max[2] + ( max[2] - min[2] ) * 1.5 );
519     
520     float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;
522     Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
523                   min[1] + (max[1] - min[1]) / 2,
524                   min[2] + (max[2] - min[2]) / 2);
526     tball.setMode( Trackball::OSGObject );
527     tball.setStartPosition( pos, true );
528     tball.setSum( true );
529     tball.setTranslationMode( Trackball::OSGFree );
530     tball.setTranslationScale(scale);
531     tball.setRotationCenter(tCenter);
533     // Create application
534     [NSApplication sharedApplication];
536     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
538     MyDelegate *delegate =  [[MyDelegate new] autorelease];
540     [NSApp setDelegate: delegate];
542     [[NSRunLoop currentRunLoop] performSelector: @selector(performer:) target:delegate argument:nil order:0 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
544 //    NSTimer *timer = [NSTimer timerWithTimeInterval: 0.0f
545 //                     target: delegate
546 //                     selector: @selector( performer: )
547 //                     userInfo: nil
548 //                     repeats: YES];
550 //    [[NSRunLoop currentRunLoop] addTimer: timer
551 //                                forMode: NSDefaultRunLoopMode];
553     // Run the message loop
554     [NSApp run];
556     fprintf(stderr, "exit\n");
558     ract      = NULL;
559     win       = NULL;
560     root      = NULL;
561     file      = NULL;
562     vp        = NULL;
563     cam_trans = NULL;
564     cam       = NULL;
566     [pool release];
568     return EXIT_SUCCESS;
571 int main(int argc, char *argv[])
573     doMain(argc, argv);
575     osgExit();
577     return EXIT_SUCCESS;