Mercurial > projects > openmelee
comparison ai/steer.d @ 22:4fce5596d1f6
ai work
author | zzzzrrr <mason.green@gmail.com> |
---|---|
date | Thu, 26 Mar 2009 16:56:30 -0400 |
parents | cad384ad349e |
children | e79347dd38a3 |
comparison
equal
deleted
inserted
replaced
21:cad384ad349e | 22:4fce5596d1f6 |
---|---|
47 // Constructor: initializes state | 47 // Constructor: initializes state |
48 this (Ship ship) | 48 this (Ship ship) |
49 { | 49 { |
50 m_ship = ship; | 50 m_ship = ship; |
51 m_body = ship.rBody; | 51 m_body = ship.rBody; |
52 m_radius = 0.0f; | |
53 | |
54 // Find radius of body | |
55 for (bzShape s = m_body.shapeList; s; s = s.next) { | |
56 if(s.sweepRadius > m_radius) { | |
57 m_radius = s.sweepRadius; | |
58 } | |
59 } | |
60 } | 52 } |
61 | 53 |
62 struct PathIntersection | 54 struct PathIntersection |
63 { | 55 { |
64 bool intersect; | 56 bool intersect; |
79 m_position = m_ship.state.position; | 71 m_position = m_ship.state.position; |
80 m_velocity = m_ship.state.velocity; | 72 m_velocity = m_ship.state.velocity; |
81 m_speed = m_ship.state.speed; | 73 m_speed = m_ship.state.speed; |
82 m_maxForce = m_ship.state.maxForce; | 74 m_maxForce = m_ship.state.maxForce; |
83 m_forward = m_ship.state.forward; | 75 m_forward = m_ship.state.forward; |
76 m_radius = m_ship.state.radius; | |
84 } | 77 } |
85 | 78 |
86 // -------------------------------------------------- steering behaviors | 79 // -------------------------------------------------- steering behaviors |
87 | 80 |
88 bzVec2 steerForWander (float dt) { | 81 bzVec2 steerForWander (float dt) { |
145 | 138 |
146 bzVec2 steerToAvoidObstacles (float minTimeToCollision, bzBody obstacles) { | 139 bzVec2 steerToAvoidObstacles (float minTimeToCollision, bzBody obstacles) { |
147 | 140 |
148 bzVec2 avoidance; | 141 bzVec2 avoidance; |
149 PathIntersection nearest, next; | 142 PathIntersection nearest, next; |
150 float minDistanceToCollision = minTimeToCollision * m_speed; | 143 float minDistanceToCollision = 10; //minTimeToCollision * m_speed; |
151 | 144 |
152 next.intersect = false; | 145 next.intersect = false; |
153 nearest.intersect = false; | 146 nearest.intersect = false; |
154 | 147 |
155 // test all obstacles for intersection with my forward axis, | 148 // test all obstacles for intersection with my forward axis, |
157 for (bzBody o = obstacles; o; o = o.next) { | 150 for (bzBody o = obstacles; o; o = o.next) { |
158 | 151 |
159 if(o is m_body) continue; | 152 if(o is m_body) continue; |
160 | 153 |
161 // This code which presumes the obstacle is spherical | 154 // This code which presumes the obstacle is spherical |
162 findNextIntersectionWithSphere(o, next, minDistanceToCollision); | 155 findNextIntersectionWithSphere(o, next); |
163 | 156 |
164 if (!nearest.intersect || (next.intersect && next.distance < nearest.distance)) { | 157 if (!nearest.intersect || (next.intersect && next.distance < nearest.distance)) { |
165 nearest = next; | 158 nearest = next; |
166 } | 159 } |
167 } | 160 } |
168 | 161 |
169 // when a nearest intersection was found | 162 // when a nearest intersection was found |
170 if (nearest.intersect && (nearest.distance < minDistanceToCollision)) { | 163 if (nearest.intersect && (nearest.distance < minDistanceToCollision)) { |
171 Stdout("Distance: ")(nearest.distance).newline; | |
172 // compute avoidance steering force: take offset from obstacle to me, | 164 // compute avoidance steering force: take offset from obstacle to me, |
173 // take the component of that which is lateral (perpendicular to my | 165 // take the component of that which is lateral (perpendicular to my |
174 // forward direction), set length to maxForce, add a bit of forward | 166 // forward direction), set length to maxForce, add a bit of forward |
175 // component (in capture the flag, we never want to slow down) | 167 // component (in capture the flag, we never want to slow down) |
176 bzVec2 offset = m_position - nearest.obstacle.position; | 168 bzVec2 offset = m_position - nearest.obstacle.position; |
177 avoidance = perpendicularComponent(offset, m_forward); | 169 avoidance = perpendicularComponent(offset, m_forward); |
178 avoidance.normalize; | 170 avoidance.normalize; |
179 //avoidance *= m_maxForce; | 171 avoidance = m_body.localPoint(avoidance); |
172 ///avoidance *= m_maxForce; | |
180 //avoidance += m_forward * m_maxForce * 0.75f; | 173 //avoidance += m_forward * m_maxForce * 0.75f; |
181 } | 174 } |
182 | 175 |
176 auto state = cast(State) m_body.userData; | |
177 state.avoid = avoidance; | |
183 return avoidance; | 178 return avoidance; |
184 } | 179 } |
185 | 180 |
186 bzVec2 avoid(float minTimeToCollision, bzBody obstacles) { | 181 bzVec2 avoid(float minTimeToCollision, bzBody obstacles) { |
187 | 182 |
199 bzVec2 movementNormal = m_velocity; | 194 bzVec2 movementNormal = m_velocity; |
200 movementNormal.normalize(); | 195 movementNormal.normalize(); |
201 bzVec2 characterToObstacle = o.position - m_position; | 196 bzVec2 characterToObstacle = o.position - m_position; |
202 | 197 |
203 real distanceSquared = bzDot(characterToObstacle, movementNormal); | 198 real distanceSquared = bzDot(characterToObstacle, movementNormal); |
204 distanceSquared = characterToObstacle.length - | 199 distanceSquared = characterToObstacle.lengthSquared - distanceSquared*distanceSquared; |
205 distanceSquared*distanceSquared; | |
206 | 200 |
207 // Check for collision | 201 // Check for collision |
208 // Find radius of obstacle | |
209 float oRad = 0; | 202 float oRad = 0; |
210 for (bzShape shape = o.shapeList; shape; shape = shape.next) { | 203 for (bzShape s = o.shapeList; s; s = s.next) { |
211 if(shape.sweepRadius > oRad) { | 204 if(s.sweepRadius > oRad) { |
212 oRad = shape.sweepRadius; | 205 oRad = s.sweepRadius; |
213 } | 206 } |
214 } | 207 } |
215 | 208 |
216 real radius = oRad + avoidMargin; | 209 real radius = oRad + avoidMargin; |
217 if (distanceSquared < radius*radius) | 210 if (distanceSquared < radius*radius) |
221 | 214 |
222 // Make sure this isn't behind us and is closer than our lookahead. | 215 // Make sure this isn't behind us and is closer than our lookahead. |
223 if (distanceToClosest > 0 && distanceToClosest < maxLookahead) | 216 if (distanceToClosest > 0 && distanceToClosest < maxLookahead) |
224 { | 217 { |
225 // Find the closest point | 218 // Find the closest point |
226 bzVec2 closestPoint = | 219 bzVec2 closestPoint = o.position + movementNormal * distanceToClosest; |
227 o.position + movementNormal*distanceToClosest; | |
228 | 220 |
229 // Find the point of avoidance | 221 // Find the point of avoidance |
230 bzVec2 target = | 222 bzVec2 target = o.position + (closestPoint - o.position).length * radius; |
231 o.position + | 223 |
232 (closestPoint - o.position).length * | 224 auto state = cast(State) m_body.userData; |
233 (oRad + avoidMargin); | 225 state.avoid = target; |
234 | 226 |
235 return target; | 227 return target; |
236 } | 228 } |
237 } | 229 } |
238 } | 230 } |
239 } | 231 } |
232 | |
233 auto state = cast(State) m_body.userData; | |
234 state.avoid = bzVec2.zeroVect; | |
235 | |
240 return bzVec2.zeroVect; | 236 return bzVec2.zeroVect; |
241 | 237 |
242 } | 238 } |
243 | 239 |
244 void findNextIntersectionWithSphere(bzBody obs, | 240 void findNextIntersectionWithSphere(bzBody obs, |
245 inout PathIntersection intersection, float mdc) { | 241 inout PathIntersection intersection) { |
246 | 242 |
247 // This routine is based on the Paul Bourke's derivation in: | 243 // This routine is based on the Paul Bourke's derivation in: |
248 // Intersection of a Line and a Sphere (or circle) | 244 // Intersection of a Line and a Sphere (or circle) |
249 // http://www.swin.edu.au/astronomy/pbourke/geometry/sphereline/ | 245 // http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/raysphere.c |
250 | 246 |
251 float b, c, d, p, q, s; | 247 float b, c, d, p, q, s; |
252 bzVec2 lc; | 248 bzVec2 lc; |
253 | 249 |
254 // initialize pathIntersection object | 250 // initialize pathIntersection object |
255 intersection.intersect = false; | 251 intersection.intersect = false; |
256 intersection.obstacle = obs; | 252 intersection.obstacle = obs; |
257 | 253 |
258 // find "local center" (lc) of sphere in boid's coordinate space | 254 // find "local center" (lc) of sphere in coordinate space |
259 lc = m_body.localPoint(obs.position); | 255 lc = m_body.localPoint(obs.position); |
260 | 256 |
261 // computer line-sphere intersection parameters | 257 // computer line-sphere intersection parameters |
262 b = 0; | 258 b = 0; |
263 | 259 |
267 if(shape.sweepRadius > obsRadius) { | 263 if(shape.sweepRadius > obsRadius) { |
268 obsRadius = shape.sweepRadius; | 264 obsRadius = shape.sweepRadius; |
269 } | 265 } |
270 } | 266 } |
271 | 267 |
272 c = square(lc.x) + square(lc.y) - square(obsRadius + m_radius+mdc); | 268 c = square(lc.x) + square(lc.y) - square(obsRadius + m_radius); |
273 d = (b * b) - (4 * c); | 269 d = (b * b) - (4 * c); |
274 | 270 |
275 // when the path does not intersect the sphere | 271 // when the path does not intersect the sphere |
276 if (d < 0) return; | 272 if (d < 0) return; |
277 | 273 |