This is AzimuthMat.m in view mode; [Download] [Up]
#import "AzimuthMat.h" #import "math.h" #import <string.h> @implementation AzimuthMat +new { self = [super new]; limits[0] = limits[1] = limits[2] = 0.; limits[3] = limits[4] = limits[5] = 1.; [self reset]; phi = s_phi = 0.; c_phi = 1.0; dist = 2.0; [self setTheta:0.]; } +newLimits:(float *)newlimits { register short int n = 6; register float *lim; self = [super new]; lim = limits; while(n--) *lim++ = *newlimits++; [self reset]; phi = s_phi = 0.; c_phi = 1.0; dist = 2.0; [self setTheta:0.]; } -reset { [super reset]; [self translate :-(limits[0] + limits[3]) / 2 :-(limits[1] + limits[4]) / 2 :-(limits[2] + limits[5]) / 2]; [self scale :1. / (limits[3] - limits[0]) :1. / (limits[4] - limits[1]) :1. / (limits[5] - limits[2])]; [self x_rotation_cs :0. :-1.]; memmove(to_theta_cache, mat, 16*sizeof(float)); is_cached_to_theta = YES; } -setlimits:(float *)newlimits { register short int n = 6; register float *lim; lim = limits; while(n--) *lim++ = *newlimits++; [self reset]; } -setTheta:(float)radians { if (is_cached_to_theta) memmove(mat, to_theta_cache, 16*sizeof(float)); else { [self reset]; memmove(to_theta_cache, mat, 16*sizeof(float)); is_cached_to_theta = YES; } is_cached_to_phi = is_cached_to_dist = NO; theta = radians; [self y_rotation_cs:(c_theta = cos(radians)) :(s_theta = sin(radians))]; [self x_rotation_cs:c_phi :s_phi]; [self perspective:dist]; } -setPhi:(float)radians { if (is_cached_to_phi) memmove(mat, to_phi_cache, 16*sizeof(float)); else { if (is_cached_to_theta) memmove(mat, to_theta_cache, 16*sizeof(float)); else [self reset]; [self y_rotation_cs:c_theta:s_theta]; memmove(to_phi_cache, mat, 16*sizeof(float)); is_cached_to_phi = YES; } is_cached_to_dist = NO; phi = radians; [self x_rotation_cs:(c_phi = cos(radians)) :(s_phi = sin(radians))]; [self perspective:dist]; } -setdist:(float)distance { if (is_cached_to_dist) memmove(mat, to_dist_cache, 16*sizeof(float)); else { if (is_cached_to_theta) memmove(mat, to_theta_cache, 16*sizeof(float)); else [self reset]; [self y_rotation_cs:c_theta:s_theta]; [self x_rotation_cs:c_phi:s_phi]; memmove(to_dist_cache, mat, 16*sizeof(float)); is_cached_to_dist = YES; } dist = distance; [self perspective:dist]; } -setinvdist:(float)invdistance { if (is_cached_to_dist) memmove(mat, to_dist_cache, 16*sizeof(float)); else { if (is_cached_to_theta) memmove(mat, to_theta_cache, 16*sizeof(float)); else [self reset]; [self y_rotation_cs:c_theta:s_theta]; [self x_rotation_cs:c_phi:s_phi]; memmove(to_dist_cache, mat, 16*sizeof(float)); is_cached_to_dist = YES; } if (invdistance == 0.) dist = HUGE; else dist = 1./invdistance; [self perspective_inv:invdistance]; } -(float)getTheta:sender; { return theta; } -(float)getPhi:sender; { return phi; } -(float)getdist:sender; { return dist; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.