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