5 #import <Cocoa/Cocoa.h>
11 #include "OSGFieldContainerFactory.h"
12 #include "OSGVector.h"
13 #include "OSGQuaternion.h"
14 #include "OSGMatrix.h"
15 #include "OSGMatrixUtility.h"
16 #include "OSGBoxVolume.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;
44 CocoaWindowUnrecPtr win;
46 RenderActionRefPtr ract;
50 TransformRecPtr cam_trans;
52 PerspectiveCameraRecPtr cam;
59 fprintf(stderr, "redraw\n");
63 tball.getRotation().getValue(m3);
66 m2.setTranslate( tball.getPosition() );
68 cam_trans->editSFMatrix()->setValue( m1 );
70 Thread::getCurrentChangeList()->commitChanges();
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;
95 - (void) drawRect: (NSRect) bounds;
98 @implementation MyOpenGLView
100 - (BOOL) acceptsFirstResponder
105 - (void) handleMouseEvent: (NSEvent*) event
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)
116 if (modifierFlags & NSAlternateKeyMask)
118 if (modifierFlags & NSControlKeyMask)
122 NSPoint location = [event locationInWindow];
124 switch ([event type])
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)
133 case 0: // left button
135 case 1: // right button
136 tball.setAutoPositionNeg(true);
138 case 2: // middle button
139 tball.setAutoPosition(true);
147 switch (buttonNumber)
149 case 0: // left button
151 case 1: // right button
152 tball.setAutoPositionNeg(false);
154 case 2: // middle button
155 tball.setAutoPosition(false);
160 case NSLeftMouseDragged:
161 case NSRightMouseDragged:
162 case NSOtherMouseDragged:
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)
171 case 0: // left button
172 tball.updateRotation( a, b, c, d );
174 case 1: // right button
175 tball.updatePositionNeg( a, b, c, d );
177 case 2: // middle button
178 tball.updatePosition( a, b, c, d );
181 lastx = static_cast<int>(location.x);
182 lasty = static_cast<int>(location.y);
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)
240 switch ([[event characters] characterAtIndex: 0])
243 // [NSApp terminate:nil];
247 glDisable( GL_LIGHTING );
251 glEnable( GL_LIGHTING );
255 glPolygonMode( GL_FRONT_AND_BACK, GL_POINT);
259 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
263 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
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
285 @interface MyDelegate : NSObject
289 MyOpenGLView *glView;
292 - (void) applicationWillFinishLaunching: (NSNotification*) notification;
294 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) application;
296 - (void) performer: (id) userInfo;
300 @implementation MyDelegate
302 - (void) performer: (id) userInfo
304 fprintf(stderr, "perform\n");
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:@""];
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 */
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[] =
372 NSOpenGLPFADoubleBuffer,
373 NSOpenGLPFADepthSize, NSOpenGLPixelFormatAttribute(16),
374 NSOpenGLPixelFormatAttribute(0)
376 NSOpenGLPixelFormat *pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: attrs];
377 [glView setPixelFormat: pixFmt];
379 // Create OpenSG window
380 win = CocoaWindow::create();
382 win->setContext ( [glView openGLContext] );
384 win->resize( 300, 300 );
388 // do some OpenGL init. Will move into State Chunks later.
390 glEnable( GL_DEPTH_TEST );
391 glEnable( GL_LIGHTING );
392 glEnable( GL_LIGHT0 );
395 [window makeKeyAndOrderFront: nil];
396 [window makeFirstResponder:glView];
399 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) application
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();
429 // beacon for camera and light
430 NodeUnrecPtr b1n = Node::create();
431 GroupUnrecPtr b1 = Group::create();
435 NodeUnrecPtr t1n = Node::create();
436 TransformUnrecPtr t1 = Transform::create();
438 t1n->addChild( b1n );
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);
455 root = Node::create();
456 GroupUnrecPtr gr1 = Group::create();
458 root->setCore( gr1 );
459 root->addChild( t1n );
460 root->addChild( dlight );
464 NodeUnrecPtr file = NULL;
467 file = SceneFileHandler::the()->read(argv[1]);
471 std::cerr << "Couldn't load file, ignoring" << std::endl;
472 file = makeTorus( .5, 2, 16, 16 );
475 Thread::getCurrentChangeList()->commitChanges();
476 file->updateVolume();
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;
489 cam = PerspectiveCamera::create();
491 cam->setBeacon( b1n );
492 cam->setFov( osgDegree2Rad( 90 ) );
494 cam->setFar( 100000 );
497 SolidBackgroundUnrecPtr bkgnd = SolidBackground::create();
499 bkgnd->setColor(Color3f(0,0,1));
503 vp = Viewport::create();
504 vp->setCamera( cam );
505 vp->setBackground( bkgnd );
507 vp->setSize( 0,0, 1,1 );
511 ract = RenderAction::create();
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 );
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
546 // selector: @selector( performer: )
550 // [[NSRunLoop currentRunLoop] addTimer: timer
551 // forMode: NSDefaultRunLoopMode];
553 // Run the message loop
556 fprintf(stderr, "exit\n");
571 int main(int argc, char *argv[])