Annotation of Examples/3Dkit/Simple/SimpleCamera.m, revision 1.1

1.1     ! root        1: #import <appkit/appkit.h>
        !             2: #import "SimpleCamera.h"
        !             3: #import "SimpleShape.h"
        !             4: 
        !             5: /* SimpleCamera -- by Bill Bumgarner 6/1/92
        !             6:  *                                with assistance from Dave Springer.
        !             7:  *
        !             8:  * SimpleCamera demonstrates the creation of a very simple 3Dkit scene 
        !             9:  * that has mouse control via the N3DRotator class, supports dumping RIB 
        !            10:  * code to a file, contains light sources (ambient light and a point light), 
        !            11:  * has a surface shader, supports both WireFrame and SmoothSolid rendering, 
        !            12:  * and has a single custom N3DShape that generates a Torus (or teapot).
        !            13:  *
        !            14:  * Simple.app was created as an example of using the 3Dkit.  Parts of it
        !            15:  * come from Teapot.app by Dave Springer (see SimpleShape.m).
        !            16:  *
        !            17:  *  You may freely copy, distribute and reuse the code in this example.
        !            18:  *  NeXT disclaims any warranty of any kind, expressed or implied,
        !            19:  *  as to its fitness for any particular use.
        !            20:  */
        !            21: 
        !            22: @implementation SimpleCamera
        !            23: - initFrame:(const NXRect *) theRect
        !            24: {
        !            25:   // camera position points
        !            26:   // Note that the camera vector is in a left-handed coordinate system; this
        !            27:   // is the default for RenderMan.  In order to look at the front of the
        !            28:   // scene, you have to step backwards along the z-axis; in other words, you
        !            29:   // have to move the eye point negatively in z.  
        !            30:   RtPoint fromP = {0,0,-5.0}, toP = {0,0,0};
        !            31: 
        !            32:   // light position point
        !            33:   // Notice the "-0.75" z-coordinate.  This is because of the left-handed
        !            34:   // coordinate system.
        !            35:   RtPoint lFromP = {0.5,0.5,-0.75};
        !            36: 
        !            37:   // the various 3Dkit object id''s that we will initialize here
        !            38:   id ambientLight;
        !            39:   id aLight;
        !            40:   id aShader;
        !            41:   id aShape;
        !            42: 
        !            43:   // initialize camera and put it at (0,0,-5.0) looking at the origin (0,0,0)
        !            44:   // roll specifies the roll angle of the camera...
        !            45:   [super initFrame:theRect];
        !            46:   [self setEyeAt:fromP toward:toP roll:0.0];
        !            47:   
        !            48:   // create a shader that will shade surfaces with a simple matte surface.
        !            49:   aShader=[[N3DShader alloc] init];
        !            50:   // Generate a blue matte surface.
        !            51:   // This is slow on a monochrome system.
        !            52:   [aShader setUseColor:YES];
        !            53:   [aShader setColor:NX_COLORBLUE];
        !            54:   [(N3DShader *)aShader setShader:"matte"];
        !            55:   // Comment the previous line and uncomment the following lines to generate
        !            56:   // a texture-mapped surface.  The N3DShader object does all the necessary
        !            57:   // things to make a shader work properly: it sends all the Declare commands
        !            58:   // and a complete parameter string.  All you need to do is change the
        !            59:   // parameters you want with the -setShaderArg:fooValue: family of methods.
        !            60:   // When you compile your own shader, all the information about the arguments
        !            61:   // and their default values are stored in the .slo file, and the N3DShader
        !            62:   // object knows how to read them.
        !            63:   //[(N3DShader *)aShader setShader:"texmap"];
        !            64:   //[aShader setShaderArg:"texname"
        !            65:   //   stringValue:"/NextLibrary/Textures/pebbles.tx"];
        !            66: 
        !            67:   // initialize the world shape and set its shader to be aShader
        !            68:   aShape=[[SimpleShape alloc] init];
        !            69:   [(N3DShape *) aShape  setShader:aShader];
        !            70:   [[self setWorldShape:aShape] free]; // free the default world shape
        !            71: 
        !            72:   // create an ambientlight source.
        !            73:   ambientLight=[[N3DLight alloc] init];
        !            74:   [ambientLight makeAmbientWithIntensity:0.1];
        !            75:   [self addLight:ambientLight];
        !            76:   
        !            77:   // create a Point light and put it at (0.5, 0.5, -0.75) at 
        !            78:   // full intensity (1.0).
        !            79:   aLight=[[N3DLight alloc] init];
        !            80:   [aLight makePointFrom:lFromP intensity:1.0];
        !            81:   [self addLight:aLight];
        !            82: 
        !            83:   // create another Point light and put it at (-0.5, -0.5, -0.75) at 
        !            84:   // full intensity (1.0).
        !            85:   N3D_XComp( lFromP ) = -0.5;
        !            86:   N3D_YComp( lFromP ) = -0.5;
        !            87:   aLight=[[N3DLight alloc] init];
        !            88:   [aLight makePointFrom:lFromP intensity:1.0];
        !            89:   [self addLight:aLight];
        !            90: 
        !            91:   // set the surface type to generate smooth solids.  The mouseDown:
        !            92:   // method automatically drops to N3D_WireFrame whenever the user manipulates
        !            93:   // the scene via the mouse (see the mouseDown: implementation below).
        !            94:   // This must be done after the setWorldShape: method (or after any new shape
        !            95:   // is added to the hierarchy).
        !            96:   [self setSurfaceTypeForAll:N3D_SmoothSolids chooseHider:YES];
        !            97: 
        !            98:   // allocate and initialize the N3DRotator object that governs
        !            99:   // rotational control via the mouseDown: method
        !           100:   theRotator=[[N3DRotator alloc] initWithCamera:self];
        !           101: 
        !           102:   return self;
        !           103: }
        !           104: 
        !           105: - dumpRib:sender
        !           106: {
        !           107:   static id savePanel=nil;
        !           108:   NXStream *ts;
        !           109:   char buf[MAXPATHLEN+1];
        !           110: 
        !           111:   // initialize the savePanel, if it hasn''t been done so previously
        !           112:   if (!savePanel) {
        !           113:     savePanel=[SavePanel new];
        !           114:     [savePanel setRequiredFileType:"rib"];
        !           115:   }
        !           116: 
        !           117:   // run the savepanel.  
        !           118:   if([savePanel runModal]){
        !           119:     // returned w/pathname, open a stream and
        !           120:     ts=NXOpenMemory(NULL, 0, NX_WRITEONLY);
        !           121:     // process the file name for a custom display line such that
        !           122:     // "prman <<filename>>.rib" will put the resulting image somewhere
        !           123:     // predictably useful.
        !           124:     strcpy(buf, [savePanel filename]);
        !           125:     // remove the .rib extension from the path returned by the SavePanel
        !           126:     strrchr(buf,'.')[0]='\0';
        !           127:     // feed to NXPrintf to put in the custom Display command
        !           128:     NXPrintf(ts, "Display \"%s.tiff\" \"file\" \"rgba\"\n", buf);
        !           129:     // then feed the rib code to the stream and
        !           130:     [self copyRIBCode:ts];
        !           131:     // save the stream to the file selected in the savepanel
        !           132:     NXSaveToFile(ts, [savePanel filename]);
        !           133:     // and close the stream (which also flushes it), also making sure
        !           134:     // that the allocated memory is freed.
        !           135:     NXCloseMemory(ts,NX_FREEBUFFER);
        !           136:   }
        !           137:   return self;
        !           138: }
        !           139: 
        !           140: #define ACTIVEBUTTONMASK (NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK)
        !           141: - mouseDown:(NXEvent *)theEvent
        !           142: {
        !           143:   int                  oldMask;
        !           144:   NXPoint              oldMouse, newMouse, dMouse;
        !           145:   RtMatrix             rmat, irmat;
        !           146: 
        !           147:   // find out what axis of rotation the rotator should be constrained to
        !           148:   switch([rotoMatrix selectedRow]){
        !           149:   case 0: [theRotator setRotationAxis:N3D_AllAxes]; break;
        !           150:   case 1: [theRotator setRotationAxis:N3D_XAxis]; break;
        !           151:   case 2: [theRotator setRotationAxis:N3D_YAxis]; break;
        !           152:   case 3: [theRotator setRotationAxis:N3D_ZAxis]; break;
        !           153:   case 4: [theRotator setRotationAxis:N3D_XYAxes]; break;
        !           154:   case 5: [theRotator setRotationAxis:N3D_XZAxes]; break;
        !           155:   case 6: [theRotator setRotationAxis:N3D_YZAxes]; break;
        !           156:   }
        !           157: 
        !           158:   // track the mouse until a mouseUp event occurs, updating the display
        !           159:   // as tracking happens.
        !           160:   [self lockFocus];
        !           161:   oldMask = [window addToEventMask:ACTIVEBUTTONMASK];
        !           162:   
        !           163:   // switch to the N3D_WireFrame surface type
        !           164:   [self setSurfaceTypeForAll:N3D_WireFrame chooseHider:YES];
        !           165:   
        !           166:   oldMouse = theEvent->location;
        !           167:   [self convertPoint:&oldMouse fromView:nil];
        !           168:   while (1)
        !           169:   {
        !           170:     newMouse = theEvent->location;
        !           171:     [self convertPoint:&newMouse fromView:nil];
        !           172:     dMouse.x = newMouse.x - oldMouse.x;
        !           173:     dMouse.y = newMouse.y - oldMouse.y;
        !           174:     if (dMouse.x != 0.0 || dMouse.y != 0.0) {
        !           175:       [theRotator trackMouseFrom:&oldMouse to:&newMouse
        !           176:        rotationMatrix:rmat andInverse:irmat];
        !           177:       [worldShape concatTransformMatrix:rmat premultiply:NO];
        !           178:       [self display];
        !           179:     }
        !           180:     theEvent = [NXApp getNextEvent:ACTIVEBUTTONMASK];
        !           181:     if (theEvent->type == NX_MOUSEUP)
        !           182:       break;
        !           183:     oldMouse = newMouse;
        !           184:   }
        !           185:   // switch back to the N3D_SmoothSolids surface type
        !           186:   [self setSurfaceTypeForAll:N3D_SmoothSolids chooseHider:YES];        
        !           187:   [self display];
        !           188:   [self unlockFocus];
        !           189: 
        !           190:   [window setEventMask:oldMask];
        !           191:   return self;
        !           192: }
        !           193: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.