|
|
1.1 ! root 1: ! 2: /* ! 3: ThreeDPanel.m ! 4: ! 5: ThreeDPanel is a very simple panel for controlling a few attributes of the ! 6: 3D graphs. A real app would have a much better UI for controlling 3D ! 7: presentation. ! 8: ! 9: There is only one instance of the panel, which tracks the ! 10: setting of the main window. When a document's window becomes main, it ! 11: sends the setCamera: method to the panel, thus keeping it up to date. ! 12: ! 13: You may freely copy, distribute, and reuse the code in this example. ! 14: NeXT disclaims any warranty of any kind, expressed or implied, as to its ! 15: fitness for any particular use. ! 16: */ ! 17: ! 18: #import "Graph.h" ! 19: ! 20: /* declare methods private to this class's implementation */ ! 21: @interface ThreeDPanel(Private) ! 22: - (void)_sendNotification; ! 23: @end ! 24: ! 25: @implementation ThreeDPanel ! 26: ! 27: /* called when the surface color well changes */ ! 28: - changeSurfaceColor:sender { ! 29: [[camera worldShape] setColor:[sender color]]; ! 30: [camera display]; ! 31: [self _sendNotification]; ! 32: return self; ! 33: } ! 34: ! 35: /* called when the background color well changes */ ! 36: - changeBackgroundColor:sender { ! 37: [camera setBackgroundColor:[sender color]]; ! 38: [camera display]; ! 39: [self _sendNotification]; ! 40: return self; ! 41: } ! 42: ! 43: /* called when shading buttons are changed */ ! 44: - changeShading:sender { ! 45: static shadeTable[4] = {N3D_PointCloud, N3D_WireFrame, N3D_FacetedSolids, N3D_SmoothSolids}; ! 46: ! 47: /* ! 48: * This message gets the right hidden-surface algorithm for the new type ! 49: * of shading. If you just set the surface type of the individual shapes, ! 50: * you can end of with the sides of the objects drawn out of order because ! 51: * the correct hider was not chosen. ! 52: */ ! 53: [camera setSurfaceTypeForAll:shadeTable[[shadingButtons selectedRow]] chooseHider:YES]; ! 54: [camera display]; ! 55: [self _sendNotification]; ! 56: return self; ! 57: } ! 58: ! 59: /* ! 60: * Called when the zoom slider is changed. We just move the eye point along ! 61: * its current vector, at a distance given by the slider's value. ! 62: */ ! 63: - changeZoom:sender { ! 64: RtPoint from, to; ! 65: float distance; ! 66: float angle; ! 67: float newDistance; ! 68: ! 69: [camera getEyeAt:&from toward:&to roll:&angle]; ! 70: distance = sqrt(from[0]*from[0] + from[1]*from[1] + from[2]*from[2]); ! 71: newDistance = [sender floatValue]; ! 72: if (newDistance < 0.01) ! 73: newDistance = 0.01; ! 74: from[0] *= newDistance / distance; ! 75: from[1] *= newDistance / distance; ! 76: from[2] *= newDistance / distance; ! 77: [camera setEyeAt:from toward:to roll:angle]; ! 78: ! 79: [camera display]; ! 80: [self _sendNotification]; ! 81: return self; ! 82: } ! 83: ! 84: /* ! 85: * Associates the panel with a new camera view. Causes the panel's controls ! 86: * to adjust to reflect the current settings of the camera and its world shape ! 87: * (top level shape). ! 88: */ ! 89: - setCamera:obj { ! 90: RtPoint fromPoint; ! 91: RtPoint toPoint; ! 92: float aRollAngle; ! 93: ! 94: camera = obj; ! 95: [surfaceColorWell setEnabled:obj != nil]; ! 96: [backgroundColorWell setEnabled:obj != nil]; ! 97: [shadingButtons setEnabled:obj != nil]; ! 98: [zoomSlider setEnabled:obj != nil]; ! 99: if (camera) { ! 100: [surfaceColorWell setColor:[[camera worldShape] color]]; ! 101: [backgroundColorWell setColor:[camera backgroundColor]]; ! 102: switch ([[camera worldShape] surfaceType]) { ! 103: case N3D_PointCloud: ! 104: [shadingButtons selectCellAt:0 :0]; ! 105: break; ! 106: case N3D_WireFrame: ! 107: [shadingButtons selectCellAt:1 :0]; ! 108: break; ! 109: case N3D_FacetedSolids: ! 110: [shadingButtons selectCellAt:2 :0]; ! 111: break; ! 112: case N3D_SmoothSolids: ! 113: [shadingButtons selectCellAt:3 :0]; ! 114: break; ! 115: default: ! 116: NX_ASSERT(NO, "Unexpected shading type in setCamera:"); ! 117: } ! 118: [camera getEyeAt:&fromPoint toward:&toPoint roll:&aRollAngle]; ! 119: [zoomSlider setFloatValue:sqrt(fromPoint[0]*fromPoint[0] + fromPoint[1]*fromPoint[1] + fromPoint[2]*fromPoint[2])]; ! 120: } ! 121: return self; ! 122: } ! 123: ! 124: - (void)_sendNotification { ! 125: id docDelegate = [[camera window] delegate]; ! 126: ! 127: if ([docDelegate respondsTo:@selector(threeDPanelDidChangeDoc:)]) { ! 128: [docDelegate threeDPanelDidChangeDoc:self]; ! 129: } ! 130: } ! 131: ! 132: @end ! 133:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.