annotate steer.d @ 9:5b61327b5a7c

update steer
author zzzzrrr <mason.green@gmail.com>
date Sat, 21 Mar 2009 20:19:18 -0400
parents a40d066ebbd1
children d998bf1b0654
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
1 // ----------------------------------------------------------------------------
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
2 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
3 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
4 // OpenSteer -- Steering Behaviors for Autonomous Characters
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
5 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
6 // Copyright (c) 2002-2003, Sony Computer Entertainment America
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
7 // Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
8 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
9 // Permission is hereby granted, free of charge, to any person obtaining a
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
10 // copy of this software and associated documentation files (the "Software"),
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
11 // to deal in the Software without restriction, including without limitation
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
12 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
13 // and/or sell copies of the Software, and to permit persons to whom the
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
14 // Software is furnished to do so, subject to the following conditions:
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
15 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
16 // The above copyright notice and this permission notice shall be included in
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
17 // all copies or substantial portions of the Software.
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
18 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
22 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
24 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
25 // DEALINGS IN THE SOFTWARE.
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
26 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
27 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
28 // ----------------------------------------------------------------------------
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
29 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
30 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
31 // SteerLibraryMixin
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
32 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
33 // This mixin (class with templated superclass) adds the "steering library"
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
34 // functionality to a given base class. SteerLibraryMixin assumes its base
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
35 // class supports the Ship interface.
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
36 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
37 // 10-04-04 bk: put everything into the OpenSteer namespace
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
38 // 02-06-03 cwr: create mixin (from "SteerMass")
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
39 // 06-03-02 cwr: removed TS dependencies
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
40 // 11-21-01 cwr: created
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
41 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
42 //
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
43 // ----------------------------------------------------------------------------
2
a40d066ebbd1 implemented zoom
Zzzzrrr <mason.green@gmail.com>
parents: 0
diff changeset
44 module openmelee.steer;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
45
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
46 class Steer
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
47 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
48 // Constructor: initializes state
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
49 this ()
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
50 {
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
51 // set inital state
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
52 reset ();
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
53 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
54
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
55 // reset state
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
56 void reset () {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
57 // initial state of wander behavior
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
58 wanderSide = 0;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
59 wanderUp = 0;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
60 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
61
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
62 void update(bzBody rBody) {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
63
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
64 m_position = rBody.position;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
65 m_velocity = rBody.linearVelocity;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
66 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
67
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
68 // -------------------------------------------------- steering behaviors
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
69
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
70 // Wander behavior
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
71 float wanderSide;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
72 float wanderUp;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
73
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
74 bzVec2 steerForWander (float dt) {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
75 // random walk wanderSide and wanderUp between -1 and +1
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
76 float speed = 12 * dt; // maybe this (12) should be an argument?
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
77 wanderSide = scalarRandomWalk (wanderSide, speed, -1, +1);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
78 wanderUp = scalarRandomWalk (wanderUp, speed, -1, +1);
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
79
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
80 // return a pure lateral steering vector: (+/-Side) + (+/-Up)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
81 return (side() * wanderSide) + (up() * wanderUp);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
82 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
83
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
84 // Seek behavior
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
85 bzVec2 steerForSeek (bzVec2 target) {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
86 bzVec2 desiredVelocity = target - m_position;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
87 return desiredVelocity - m_velocity;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
88 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
89
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
90 // Flee behavior
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
91 bzVec2 steerForFlee (bzVec2 target) {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
92 bzVec2 desiredVelocity = m_position - target;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
93 return desiredVelocity - m_velocity;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
94 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
95
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
96 // xxx proposed, experimental new seek/flee [cwr 9-16-02]
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
97 bzVec2 xxxsteerForFlee (bzVec2 target) {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
98 bzVec2 offset = m_position - target;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
99 bzVec2 desiredVelocity = offset.truncateLength (maxSpeed ());
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
100 return desiredVelocity - m_velocity;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
101 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
102
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
103 bzVec2 xxxsteerForSeek (bzVec2 target) {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
104 // bzVec2 offset = target - position;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
105 bzVec2 offset = target - m_position;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
106 bzVec2 desiredVelocity = offset.truncateLength (maxSpeed ()); //xxxnew
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
107 return desiredVelocity - m_velocity;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
108 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
109
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
110 // ------------------------------------------------------------------------
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
111 // Obstacle Avoidance behavior
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
112 //
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
113 // Returns a steering force to avoid a given obstacle. The purely
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
114 // lateral steering force will turn our vehicle towards a silhouette edge
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
115 // of the obstacle. Avoidance is required when (1) the obstacle
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
116 // intersects the vehicle's current path, (2) it is in front of the
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
117 // vehicle, and (3) is within minTimeToCollision seconds of travel at the
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
118 // vehicle's current velocity. Returns a zero vector value (bzVec2::zero)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
119 // when no avoidance is required.
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
120 bzVec2 steerToAvoidObstacle (float minTimeToCollision, Obstacle obstacle) {
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
121
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
122 bzVec2 avoidance = obstacle.steerToAvoid (this, minTimeToCollision);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
123 return avoidance;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
124 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
125
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
126 // avoids all obstacles in an ObstacleGroup
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
127
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
128 bzVec2 steerToAvoidObstacles (float minTimeToCollision,
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
129 ObstacleGroup obstacles) {
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
130
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
131 bzVec2 avoidance;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
132 PathIntersection nearest, next;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
133 float minDistanceToCollision = minTimeToCollision * speed();
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
134
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
135 next.intersect = false;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
136 nearest.intersect = false;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
137
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
138 // test all obstacles for intersection with my forward axis,
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
139 // select the one whose point of intersection is nearest
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
140 for (ObstacleIterator o = obstacles.begin(); o != obstacles.end(); o++)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
141 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
142 // xxx this should be a generic call on Obstacle, rather than
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
143 // xxx this code which presumes the obstacle is spherical
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
144 findNextIntersectionWithSphere ((SphericalObstacle)**o, next);
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
145
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
146 if ((nearest.intersect == false) ||
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
147 ((next.intersect != false)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
148 (next.distance < nearest.distance)))
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
149 nearest = next;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
150 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
151
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
152 // when a nearest intersection was found
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
153 if ((nearest.intersect != false)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
154 (nearest.distance < minDistanceToCollision))
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
155 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
156 // show the corridor that was checked for collisions
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
157 annotateAvoidObstacle (minDistanceToCollision);
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
158
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
159 // compute avoidance steering force: take offset from obstacle to me,
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
160 // take the component of that which is lateral (perpendicular to my
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
161 // forward direction), set length to maxForce, add a bit of forward
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
162 // component (in capture the flag, we never want to slow down)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
163 bzVec2 offset = m_position - nearest.obstacle.center;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
164 avoidance = offset.perpendicularComponent (forward());
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
165 avoidance = avoidance.normalize ();
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
166 avoidance *= maxForce ();
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
167 avoidance += forward() * maxForce () * 0.75;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
168 }
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
169
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
170 return avoidance;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
171 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
172
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
173 // ------------------------------------------------------------------------
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
174 // Unaligned collision avoidance behavior: avoid colliding with other
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
175 // nearby vehicles moving in unconstrained directions. Determine which
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
176 // (if any) other other vehicle we would collide with first, then steers
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
177 // to avoid the site of that potential collision. Returns a steering
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
178 // force vector, which is zero length if there is no impending collision.
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
179
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
180 bzVec2 steerToAvoidNeighbors (float minTimeToCollision, AVGroup others) {
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
181
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
182 // first priority is to prevent immediate interpenetration
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
183 bzVec2 separation = steerToAvoidCloseNeighbors (0, others);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
184 if (separation != bzVec2::zero) return separation;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
185
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
186 // otherwise, go on to consider potential future collisions
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
187 float steer = 0;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
188 Ship* threat = NULL;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
189
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
190 // Time (in seconds) until the most immediate collision threat found
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
191 // so far. Initial value is a threshold: don't look more than this
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
192 // many frames into the future.
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
193 float minTime = minTimeToCollision;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
194
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
195 // xxx solely for annotation
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
196 bzVec2 xxxThreatPositionAtNearestApproach;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
197 bzVec2 xxxOurPositionAtNearestApproach;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
198
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
199 // for each of the other vehicles, determine which (if any)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
200 // pose the most immediate threat of collision.
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
201 for (AVIterator i = others.begin(); i != others.end(); i++)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
202 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
203 Ship other = **i;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
204 if (other != this)
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
205 {
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
206 // avoid when future positions are this close (or less)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
207 float collisionDangerThreshold = radius() * 2;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
208
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
209 // predicted time until nearest approach of "this" and "other"
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
210 float time = predictNearestApproachTime (other);
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
211
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
212 // If the time is in the future, sooner than any other
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
213 // threatened collision...
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
214 if ((time >= 0) (time < minTime))
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
215 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
216 // if the two will be close enough to collide,
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
217 // make a note of it
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
218 if (computeNearestApproachPositions (other, time)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
219 < collisionDangerThreshold)
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
220 {
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
221 minTime = time;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
222 threat = other;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
223 xxxThreatPositionAtNearestApproach
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
224 = hisPositionAtNearestApproach;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
225 xxxOurPositionAtNearestApproach
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
226 = ourPositionAtNearestApproach;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
227 }
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
228 }
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
229 }
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
230 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
231
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
232 // if a potential collision was found, compute steering to avoid
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
233 if (threat)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
234 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
235 // parallel: +1, perpendicular: 0, anti-parallel: -1
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
236 float parallelness = forward.dot(threat.forward);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
237 float angle = 0.707f;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
238
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
239 if (parallelness < -angle)
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
240 {
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
241 // anti-parallel "head on" paths:
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
242 // steer away from future threat position
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
243 bzVec2 offset = xxxThreatPositionAtNearestApproach - m_position;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
244 float sideDot = offset.dot(side());
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
245 steer = (sideDot > 0) ? -1.0f : 1.0f;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
246 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
247 else
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
248 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
249 if (parallelness > angle)
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
250 {
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
251 // parallel paths: steer away from threat
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
252 bzVec2 offset = threat.position - m_position;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
253 float sideDot = offset.dot(side());
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
254 steer = (sideDot > 0) ? -1.0f : 1.0f;
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
255 }
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
256 else
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
257 {
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
258 // perpendicular paths: steer behind threat
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
259 // (only the slower of the two does this)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
260 if (threat.speed() <= speed())
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
261 {
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
262 float sideDot = side().dot(threat.velocity);
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
263 steer = (sideDot > 0) ? -1.0f : 1.0f;
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
264 }
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
265 }
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
266 }
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
267 }
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
268
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
269 return side() * steer;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
270 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
271
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
272 // Given two vehicles, based on their current positions and velocities,
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
273 // determine the time until nearest approach
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
274 float predictNearestApproachTime (Ship other) {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
275
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
276 // imagine we are at the origin with no velocity,
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
277 // compute the relative velocity of the other vehicle
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
278 bzVec2 myVelocity = m_velocity;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
279 bzVec2 otherVelocity = other.velocity;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
280 bzVec2 relVelocity = otherVelocity - myVelocity;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
281 float relSpeed = relVelocity.length;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
282
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
283 // for parallel paths, the vehicles will always be at the same distance,
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
284 // so return 0 (aka "now") since "there is no time like the present"
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
285 if (relSpeed == 0) return 0;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
286
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
287 // Now consider the path of the other vehicle in this relative
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
288 // space, a line defined by the relative position and velocity.
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
289 // The distance from the origin (our vehicle) to that line is
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
290 // the nearest approach.
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
291
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
292 // Take the unit tangent along the other vehicle's path
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
293 bzVec2 relTangent = relVelocity / relSpeed;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
294
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
295 // find distance from its path to origin (compute offset from
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
296 // other to us, find length of projection onto path)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
297 bzVec2 relPosition = m_position - other.position;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
298 float projection = relTangent.dot(relPosition);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
299
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
300 return projection / relSpeed;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
301 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
302
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
303 // Given the time until nearest approach (predictNearestApproachTime)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
304 // determine position of each vehicle at that time, and the distance
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
305 // between them
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
306 float computeNearestApproachPositions (Ship other, float time) {
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
307
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
308 bzVec2 myTravel = forward * speed * time;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
309 bzVec2 otherTravel = other.forward * other.speed * time;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
310
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
311 bzVec2 myFinal = m_position + myTravel;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
312 bzVec2 otherFinal = other.position + otherTravel;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
313
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
314 // xxx for annotation
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
315 ourPositionAtNearestApproach = myFinal;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
316 hisPositionAtNearestApproach = otherFinal;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
317
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
318 return bzVec2::distance (myFinal, otherFinal);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
319 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
320
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
321 // otherwise return zero
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
322 return bzVec2.zeroVect;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
323 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
324
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
325 // ------------------------------------------------------------------------
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
326 // pursuit of another vehicle ( version with ceiling on prediction time)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
327
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
328 bzVec2 steerForPursuit (Ship quarry) {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
329 return steerForPursuit (quarry, FLT_MAX);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
330 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
331
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
332 bzVec2 steerForPursuit (Ship quarry, float maxPredictionTime) {
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
333
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
334 // offset from this to quarry, that distance, unit vector toward quarry
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
335 bzVec2 offset = quarry.position - m_position;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
336 float distance = offset.length ();
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
337 bzVec2 unitOffset = offset / distance;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
338
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
339 // how parallel are the paths of "this" and the quarry
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
340 // (1 means parallel, 0 is pependicular, -1 is anti-parallel)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
341 float parallelness = forward.dot(quarry.forward());
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
342
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
343 // how "forward" is the direction to the quarry
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
344 // (1 means dead ahead, 0 is directly to the side, -1 is straight back)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
345 float forwardness = forward.dot(unitOffset);
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
346
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
347 float directTravelTime = distance / speed;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
348 int f = intervalComparison (forwardness, -0.707f, 0.707f);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
349 int p = intervalComparison (parallelness, -0.707f, 0.707f);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
350
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
351 float timeFactor = 0; // to be filled in below
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
352
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
353 // Break the pursuit into nine cases, the cross product of the
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
354 // quarry being [ahead, aside, or behind] us and heading
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
355 // [parallel, perpendicular, or anti-parallel] to us.
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
356 switch (f)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
357 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
358 case +1:
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
359 switch (p)
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
360 {
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
361 case +1: // ahead, parallel
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
362 timeFactor = 4;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
363 color = gBlack;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
364 break;
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
365 case 0: // ahead, perpendicular
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
366 timeFactor = 1.8f;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
367 break;
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
368 case -1: // ahead, anti-parallel
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
369 timeFactor = 0.85f;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
370 break;
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
371 }
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
372 break;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
373 case 0:
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
374 switch (p)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
375 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
376 case +1: // aside, parallel
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
377 timeFactor = 1;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
378 break;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
379 case 0: // aside, perpendicular
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
380 timeFactor = 0.8f;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
381 break;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
382 case -1: // aside, anti-parallel
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
383 timeFactor = 4;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
384 break;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
385 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
386 break;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
387 case -1:
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
388 switch (p)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
389 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
390 case +1: // behind, parallel
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
391 timeFactor = 0.5f;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
392 break;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
393 case 0: // behind, perpendicular
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
394 timeFactor = 2;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
395 break;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
396 case -1: // behind, anti-parallel
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
397 timeFactor = 2;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
398 break;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
399 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
400 break;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
401 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
402
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
403 // estimated time until intercept of quarry
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
404 float et = directTravelTime * timeFactor;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
405
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
406 // xxx experiment, if kept, this limit should be an argument
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
407 float etl = (et > maxPredictionTime) ? maxPredictionTime : et;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
408
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
409 // estimated position of quarry at intercept
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
410 bzVec2 target = quarry.predictFuturePosition (etl);
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
411
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
412 return steerForSeek (target);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
413 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
414
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
415 // ------------------------------------------------------------------------
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
416 // evasion of another vehicle
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
417 bzVec2 steerForEvasion (Ship menace, float maxPredictionTime) {
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
418
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
419 // offset from this to menace, that distance, unit vector toward menace
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
420 bzVec2 offset = menace.position - m_position;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
421 float distance = offset.length;
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
422
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
423 float roughTime = distance / menace.speed;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
424 float predictionTime = ((roughTime > maxPredictionTime) ? maxPredictionTime : roughTime);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
425 bzVec2 target = menace.predictFuturePosition (predictionTime);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
426
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
427 return steerForFlee (target);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
428 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
429
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
430
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
431 // ------------------------------------------------------------------------
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
432 // tries to maintain a given speed, returns a maxForce-clipped steering
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
433 // force along the forward/backward axis
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
434 bzVec2 steerForTargetSpeed (float targetSpeed) {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
435 float mf = maxForce();
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
436 float speedError = targetSpeed - speed ();
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
437 return forward () * clip (speedError, -mf, +mf);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
438 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
439
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
440
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
441 // ----------------------------------------------------------- utilities
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
442 bool isAhead (bzVec2 target) {return isAhead (target, 0.707f);};
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
443 bool isAside (bzVec2 target) {return isAside (target, 0.707f);};
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
444 bool isBehind (bzVec2 target) {return isBehind (target, -0.707f);};
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
445
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
446 bool isAhead (bzVec2 target, float cosThreshold)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
447 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
448 bzVec2 targetDirection = (target - m_position ()).normalize ();
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
449 return forward().dot(targetDirection) > cosThreshold;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
450 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
451
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
452 bool isAside (bzVec2 target, float cosThreshold)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
453 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
454 bzVec2 targetDirection = (target - m_position ()).normalize ();
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
455 float dp = forward().dot(targetDirection);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
456 return (dp < cosThreshold) (dp > -cosThreshold);
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
457 }
0
c10bc63824e7 Initial commit!
zzzzrrr <mason.green@gmail.com>
parents:
diff changeset
458
9
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
459 bool isBehind (bzVec2 target, float cosThreshold)
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
460 {
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
461 bzVec2 targetDirection = (target - m_position).normalize ();
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
462 return forward().dot(targetDirection) < cosThreshold;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
463 }
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
464
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
465 private:
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
466
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
467 bzVec2 m_position;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
468 bzVec2 m_velocity;
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
469
5b61327b5a7c update steer
zzzzrrr <mason.green@gmail.com>
parents: 2
diff changeset
470 }