5 #import <Cocoa/Cocoa.h>
7 #include "OSGFieldContainerFactory.h"
9 #include "OSGQuaternion.h"
10 #include "OSGMatrix.h"
11 #include "OSGMatrixUtility.h"
12 #include "OSGBoxVolume.h"
15 #include "OSGTransform.h"
16 #include "OSGSimpleGeometry.h"
17 #include "OSGAction.h"
18 #include "OSGRenderAction.h"
19 #include "OSGSceneFileHandler.h"
20 #include "OSGDirectionalLight.h"
22 #include "OSGViewport.h"
23 #include "OSGCamera.h"
24 #include "OSGWindow.h"
25 #include "OSGCocoaWindow.h"
26 #include "OSGCamera.h"
27 #include "OSGPerspectiveCamera.h"
28 #include "OSGSolidBackground.h"
30 #include "OSGTrackball.h"
32 // This prevents warnings that "NSApplication might not
33 // respond to setAppleMenu" on OS X 10.4
34 @interface NSApplication(OpenSG)
35 - (void)setAppleMenu:(NSMenu *)menu;
40 CocoaWindowUnrecPtr win;
46 TransformRecPtr cam_trans;
48 PerspectiveCameraRecPtr cam;
55 fprintf(stderr, "redraw\n");
59 tball.getRotation().getValue(m3);
62 m2.setTranslate( tball.getPosition() );
64 cam_trans->editSFMatrix()->setValue( m1 );
66 Thread::getCurrentChangeList()->commitChanges();
71 @interface MyOpenGLView: NSOpenGLView
74 - (BOOL) acceptsFirstResponder;
76 - (void) handleMouseEvent: (NSEvent*) event;
78 - (void) mouseDown: (NSEvent*) event;
79 - (void) mouseDragged: (NSEvent*) event;
80 - (void) mouseUp: (NSEvent*) event;
81 - (void) rightMouseDown: (NSEvent*) event;
82 - (void) rightMouseDragged: (NSEvent*) event;
83 - (void) rightMouseUp: (NSEvent*) event;
84 - (void) otherMouseDown: (NSEvent*) event;
85 - (void) otherMouseDragged: (NSEvent*) event;
86 - (void) otherMouseUp: (NSEvent*) event;
88 - (void) keyDown: (NSEvent*) event;
91 - (void) drawRect: (NSRect) bounds;
94 @implementation MyOpenGLView
96 - (BOOL) acceptsFirstResponder
101 - (void) handleMouseEvent: (NSEvent*) event
105 int buttonNumber = [event buttonNumber];
106 unsigned int modifierFlags = [event modifierFlags];
108 // Traditionally, Apple mice just have one button. It is common practice to simulate
109 // the middle and the right button by pressing the option or the control key.
110 if (buttonNumber == 0)
112 if (modifierFlags & NSAlternateKeyMask)
114 if (modifierFlags & NSControlKeyMask)
118 NSPoint location = [event locationInWindow];
120 switch ([event type])
122 case NSLeftMouseDown:
123 case NSRightMouseDown:
124 case NSOtherMouseDown:
125 lastx = static_cast<int>(location.x);
126 lasty = static_cast<int>(location.y);
127 switch (buttonNumber)
129 case 0: // left button
131 case 1: // right button
132 tball.setAutoPositionNeg(true);
134 case 2: // middle button
135 tball.setAutoPosition(true);
143 switch (buttonNumber)
145 case 0: // left button
147 case 1: // right button
148 tball.setAutoPositionNeg(false);
150 case 2: // middle button
151 tball.setAutoPosition(false);
156 case NSLeftMouseDragged:
157 case NSRightMouseDragged:
158 case NSOtherMouseDragged:
160 h = win->getHeight();
161 a = -2. * ( lastx / w - .5 );
162 b = -2. * ( lasty / h - .5);
163 c = -2. * ( location.x / w - .5 );
164 d = -2. * ( location.y / h - .5 );
165 switch (buttonNumber)
167 case 0: // left button
168 tball.updateRotation( a, b, c, d );
170 case 1: // right button
171 tball.updatePositionNeg( a, b, c, d );
173 case 2: // middle button
174 tball.updatePosition( a, b, c, d );
177 lastx = static_cast<int>(location.x);
178 lasty = static_cast<int>(location.y);
187 - (void) mouseDown: (NSEvent*) event
189 [self handleMouseEvent: event];
192 - (void) mouseDragged: (NSEvent*) event
194 [self handleMouseEvent: event];
197 - (void) mouseUp: (NSEvent*) event
199 [self handleMouseEvent: event];
202 - (void) rightMouseDown: (NSEvent*) event
204 [self handleMouseEvent: event];
207 - (void) rightMouseDragged: (NSEvent*) event
209 [self handleMouseEvent: event];
212 - (void) rightMouseUp: (NSEvent*) event
214 [self handleMouseEvent: event];
217 - (void) otherMouseDown: (NSEvent*) event
219 [self handleMouseEvent: event];
222 - (void) otherMouseDragged: (NSEvent*) event
224 [self handleMouseEvent: event];
227 - (void) otherMouseUp: (NSEvent*) event
229 [self handleMouseEvent: event];
232 - (void) keyDown: (NSEvent*) event
234 if ([[event characters] length] != 1)
236 switch ([[event characters] characterAtIndex: 0])
239 // [NSApp terminate:nil];
243 glDisable( GL_LIGHTING );
247 glEnable( GL_LIGHTING );
251 glPolygonMode( GL_FRONT_AND_BACK, GL_POINT);
255 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
259 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
270 NSRect frame = [self bounds];
271 win->resize(static_cast<int>(frame.size.width), static_cast<int>(frame.size.height));
274 - (void) drawRect: (NSRect) bounds
281 @interface MyDelegate : NSObject
285 MyOpenGLView *glView;
288 - (void) applicationWillFinishLaunching: (NSNotification*) notification;
290 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) application;
292 - (void) performer: (id) userInfo;
296 @implementation MyDelegate
298 - (void) performer: (id) userInfo
300 fprintf(stderr, "perform\n");
310 - (void) applicationWillFinishLaunching: (NSNotification*) notification
312 /* Set up the menubar */
313 [NSApp setMainMenu:[[NSMenu alloc] init]];
315 NSString *appName = @"testWindowCocoa";
316 NSMenu *appleMenu = [[NSMenu alloc] initWithTitle:@""];
320 NSMenu *servicesMenu = [[NSMenu alloc] initWithTitle:@""];
321 NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:@"Services" action:nil keyEquivalent:@""];
322 [menuItem setSubmenu:servicesMenu];
323 [appleMenu addItem:menuItem];
324 [NSApp setServicesMenu: servicesMenu];
326 [appleMenu addItem:[NSMenuItem separatorItem]];
328 NSString *title = [@"Hide " stringByAppendingString:appName];
329 [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
331 menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
332 [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
334 [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
336 [appleMenu addItem:[NSMenuItem separatorItem]];
338 title = [@"Quit " stringByAppendingString:appName];
339 [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
341 /* Put menu into the menubar */
342 menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
343 [menuItem setSubmenu:appleMenu];
344 [[NSApp mainMenu] addItem:menuItem];
346 /* Tell the application object that this is now the application menu */
347 [NSApp setAppleMenu:appleMenu];
349 /* Finally give up our references to the objects */
354 window = [NSWindow alloc];
355 NSRect rect = { { 0, 0 }, { 300, 300 } };
356 [window initWithContentRect: rect styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask) backing: NSBackingStoreBuffered defer: YES];
357 [window setTitle: @"testWindowCocoa"];
358 [window setReleasedWhenClosed: NO];
360 glView = [[MyOpenGLView alloc] autorelease];
361 [glView initWithFrame: rect];
362 [glView setAutoresizingMask: NSViewMaxXMargin | NSViewWidthSizable | NSViewMaxYMargin | NSViewHeightSizable];
363 [[window contentView] addSubview: glView];
365 NSOpenGLPixelFormatAttribute attrs[] =
368 NSOpenGLPFADoubleBuffer,
369 NSOpenGLPFADepthSize, NSOpenGLPixelFormatAttribute(16),
370 NSOpenGLPixelFormatAttribute(0)
372 NSOpenGLPixelFormat *pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: attrs];
373 [glView setPixelFormat: pixFmt];
375 // Create OpenSG window
376 win = CocoaWindow::create();
378 win->setContext ( [glView openGLContext] );
380 win->resize( 300, 300 );
384 // do some OpenGL init. Will move into State Chunks later.
386 glEnable( GL_DEPTH_TEST );
387 glEnable( GL_LIGHTING );
388 glEnable( GL_LIGHT0 );
391 [window makeKeyAndOrderFront: nil];
392 [window makeFirstResponder:glView];
395 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) application
402 void doPerform(id userInfo)
404 fprintf(stderr, "perform\n");
407 // A magic method that allows applications to react to events even
408 // when they are not organized in a bundle
409 void osx_AllowForeground()
411 ProcessSerialNumber psn = { 0, kCurrentProcess };
412 TransformProcessType(&psn, kProcessTransformToForegroundApplication);
413 SetFrontProcess(&psn);
416 int doMain(int argc, char *argv[])
418 osx_AllowForeground();
425 // beacon for camera and light
426 NodeUnrecPtr b1n = Node::create();
427 GroupUnrecPtr b1 = Group::create();
431 NodeUnrecPtr t1n = Node::create();
432 TransformUnrecPtr t1 = Transform::create();
434 t1n->addChild( b1n );
440 NodeUnrecPtr dlight = Node::create();
441 DirectionalLightUnrecPtr dl = DirectionalLight::create();
443 dlight->setCore( dl );
445 dl->setAmbient( .3, .3, .3, 1 );
446 dl->setDiffuse( 1, 1, 1, 1 );
447 dl->setDirection(0,0,1);
451 root = Node::create();
452 GroupUnrecPtr gr1 = Group::create();
454 root->setCore( gr1 );
455 root->addChild( t1n );
456 root->addChild( dlight );
460 NodeUnrecPtr file = NULL;
463 file = SceneFileHandler::the()->read(argv[1]);
467 std::cerr << "Couldn't load file, ignoring" << std::endl;
468 file = makeTorus( .5, 2, 16, 16 );
471 Thread::getCurrentChangeList()->commitChanges();
472 file->updateVolume();
475 file->getVolume().getBounds( min, max );
477 std::cout << "Volume: from " << min << " to " << max << std::endl;
479 dlight->addChild( file );
481 std::cerr << "Tree: " << std::endl;
485 cam = PerspectiveCamera::create();
487 cam->setBeacon( b1n );
488 cam->setFov( osgDegree2Rad( 90 ) );
490 cam->setFar( 100000 );
493 SolidBackgroundUnrecPtr bkgnd = SolidBackground::create();
495 bkgnd->setColor(Color3f(0,0,1));
499 vp = Viewport::create();
500 vp->setCamera( cam );
501 vp->setBackground( bkgnd );
503 vp->setSize( 0,0, 1,1 );
507 ract = RenderAction::create();
512 pos.setValues(min[0] + ((max[0] - min[0]) * 0.5),
513 min[1] + ((max[1] - min[1]) * 0.5),
514 max[2] + ( max[2] - min[2] ) * 1.5 );
516 float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;
518 Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
519 min[1] + (max[1] - min[1]) / 2,
520 min[2] + (max[2] - min[2]) / 2);
522 tball.setMode( Trackball::OSGObject );
523 tball.setStartPosition( pos, true );
524 tball.setSum( true );
525 tball.setTranslationMode( Trackball::OSGFree );
526 tball.setTranslationScale(scale);
527 tball.setRotationCenter(tCenter);
529 // Create application
530 [NSApplication sharedApplication];
532 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
534 MyDelegate *delegate = [[MyDelegate new] autorelease];
536 [NSApp setDelegate: delegate];
538 [[NSRunLoop currentRunLoop] performSelector: @selector(performer:) target:delegate argument:nil order:0 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
540 // NSTimer *timer = [NSTimer timerWithTimeInterval: 0.0f
542 // selector: @selector( performer: )
546 // [[NSRunLoop currentRunLoop] addTimer: timer
547 // forMode: NSDefaultRunLoopMode];
549 // Run the message loop
552 fprintf(stderr, "exit\n");
568 int main(int argc, char *argv[])