home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char sccsid[] = "@(#)autopilot.c 1.1 92/05/28 SMI" ;
- /* from autopilot.c 1.3 92/05/28 SMI */
- #endif
-
- /*
- * Copyright (c) 1986 by Sun Microsystems, Inc.
- */
-
- /*
- * this is the autopilot function.
- *
- * Go through the list of objects, select the closest object within view.
- * If that object is closer than AUTO_RANGE:
- * place cursor on that object.
- * If object is closer than LASER_RANGE, fire lasers.
- *
- * If no objects closer than AUTO_THRESH:
- * Set delta to (0.1,0.0) or (0.0,0.1) depending on time.
- *
- *
- */
-
-
-
-
- #include <stdio.h>
- #include <math.h>
- #include "parameters.h"
- #include "dstar.h"
- #include "object_types.h"
-
-
-
-
- #define MAX_TURN_ERROR2 (MAX_TURN_ERROR*MAX_TURN_ERROR)
-
- extern int debug_level ;
-
-
-
- auto_control(object, auto_range, max_turn, max_slew)
- Object *object ;
- float auto_range, max_turn, max_slew ;
- {
- int i,j ;
- Pt3d v1, v2 ;
- float d ;
- Object *obj2 = &objects[0] ;
- Object *closest = NULL ;
- Mat3d xform ;
- float dist ;
-
- object->flags &= ~LASER_FLAG ;
-
- if(object->target != NULL)
- {
- v1.x = object->target->Posn.x - object->Posn.x ;
- v1.y = object->target->Posn.y - object->Posn.y ;
- v1.z = object->target->Posn.z - object->Posn.z ;
- dist = v1.x*v1.x + v1.y*v1.y + v1.z*v1.z ;
-
- /* we've got a victim, find delta to take us there:
- *
- * Build vector to victim in world coords.
- * transform to ship coords, ignore z.
- * normalize (we already have distance), multiply by feedback gain
- * limit to max turn rate.
- */
-
- v2.x = v1.x*object->Right.x +
- v1.y*object->Right.y +
- v1.z*object->Right.z ;
- v2.y = v1.x*object->Up.x +
- v1.y*object->Up.y +
- v1.z*object->Up.z ;
-
- if(auto_fire && dist < LASER_RANGE*LASER_RANGE*2.0)
- object->flags |= LASER_FLAG ;
-
- if(dist < LASER_RANGE*LASER_RANGE)
- dist = 1.0 / sqrt(dist) ;
- else
- dist = FEEDBACK_GAIN / sqrt(dist) ;
-
- v2.x *= dist ;
- v2.y *= dist ;
-
- if(v2.x > max_turn) v2.x = max_turn ;
- if(v2.x < -max_turn) v2.x = -max_turn ;
- if(v2.y > max_turn) v2.y = max_turn ;
- if(v2.y < -max_turn) v2.y = -max_turn ;
- }
- else
- {
- v2.x = SCAN_TURN ;
- v2.y = 0.0 ;
- }
- set_delta(object, &v2, max_slew) ;
- adjust_vector(object,&object->Delta) ;
- #ifdef COMMENT
- for(i=0; i<MAX_OBJECTS; ++i)
- {
- if(obj2 != object &&
- (obj2->class == OBJ_ACTIVE ||
- obj2->class == OBJ_MISSILE) )
- {
- dist =
- (obj2->Posn.x - object->Posn.x)*(obj2->Posn.x - object->Posn.x) +
- (obj2->Posn.y - object->Posn.y)*(obj2->Posn.y - object->Posn.y) +
- (obj2->Posn.z - object->Posn.z)*(obj2->Posn.z - object->Posn.z);
- if(dist < mindist)
- {
- v1.x = obj2->Posn.x - object->Posn.x ;
- v1.y = obj2->Posn.y - object->Posn.y ;
- v1.z = obj2->Posn.z - object->Posn.z ;
- d = v1.x * object->Pointing.x +
- v1.y * object->Pointing.y +
- v1.z * object->Pointing.z ;
- if(d > 0.0 && d*d > dist * 0.5) /* cos(45)**2 */
- {
- closest = obj2 ;
- mindist = dist ;
- }
- }
- }
- ++obj2 ;
- }
-
-
- if(closest != NULL)
- {
- if(auto_fire && mindist < LASER_RANGE*LASER_RANGE*2.0)
- object->flags |= LASER_FLAG ;
-
- /* we've got a victim, find delta to take us there:
- *
- * Build vector to victim in world coords.
- * transform to ship coords, ignore z.
- * normalize (we already have distance), multiply by feedback gain
- * limit to max turn rate.
- */
-
- v1.x = closest->Posn.x - object->Posn.x ;
- v1.y = closest->Posn.y - object->Posn.y ;
- v1.z = closest->Posn.z - object->Posn.z ;
-
- v2.x = v1.x*object->Right.x +
- v1.y*object->Right.y +
- v1.z*object->Right.z ;
- v2.y = v1.x*object->Up.x +
- v1.y*object->Up.y +
- v1.z*object->Up.z ;
-
- if(mindist < LASER_RANGE*LASER_RANGE)
- mindist = 1.0 / sqrt(mindist) ;
- else
- mindist = FEEDBACK_GAIN / sqrt(mindist) ;
-
- v2.x *= mindist ;
- v2.y *= mindist ;
-
- if(v2.x > max_turn) v2.x = max_turn ;
- if(v2.x < -max_turn) v2.x = -max_turn ;
- if(v2.y > max_turn) v2.y = max_turn ;
- if(v2.y < -max_turn) v2.y = -max_turn ;
- }
- else
- {
- v2.x = SCAN_TURN ;
- v2.y = 0.0 ;
- }
- set_delta(object, &v2, max_slew) ;
- adjust_vector(object,&object->Delta) ;
- #endif COMMENT
- }
-
-
-
- set_delta(object, vector, max_slew)
- Object *object ;
- Pt3d *vector ;
- float max_slew ;
- {
- Pt3d v1 ;
- register float d1, max_turn ;
-
- v1.x = vector->x - object->Delta.x ;
- v1.y = vector->y - object->Delta.y ;
- d1 = v1.x*v1.x + v1.y*v1.y ;
- if(d1 > MAX_TURN_ERROR2)
- {
- d1 = sqrt(d1) ;
- max_turn = Dtime * max_slew ;
- if(d1 > max_turn)
- d1 = max_turn/d1 ;
- else
- d1 = 1.0 ;
- object->Delta.x += d1*v1.x ;
- object->Delta.y += d1*v1.y ;
- }
- }
-