Mercurial > projects > openmelee
comparison ai/steer.d @ 23:e79347dd38a3
steering
author | zzzzrrr <mason.green@gmail.com> |
---|---|
date | Thu, 26 Mar 2009 20:35:58 -0400 |
parents | 4fce5596d1f6 |
children | 441eb7672404 |
comparison
equal
deleted
inserted
replaced
22:4fce5596d1f6 | 23:e79347dd38a3 |
---|---|
176 auto state = cast(State) m_body.userData; | 176 auto state = cast(State) m_body.userData; |
177 state.avoid = avoidance; | 177 state.avoid = avoidance; |
178 return avoidance; | 178 return avoidance; |
179 } | 179 } |
180 | 180 |
181 bzVec2 avoid(float minTimeToCollision, bzBody obstacles) { | 181 bzVec2 getSteering(bzBody obstacles) { |
182 | |
183 // 1. Find the target that’s closest to collision | |
184 | |
185 float radius = m_radius; | |
186 float rad; | |
187 // Store the first collision time | |
188 float shortestTime = 0.5; | |
189 | |
190 // Store the target that collides then, and other data | |
191 // that we will need and can avoid recalculating | |
192 bzBody firstTarget = null; | |
193 float firstMinSeparation = 0; | |
194 float firstDistance = 0; | |
195 bzVec2 firstRelativePos; | |
196 bzVec2 firstRelativeVel; | |
197 bzVec2 relativePos; | |
198 | |
199 // Loop through each target | |
200 for (bzBody target = obstacles; target; target = target.next) { | |
201 | |
202 if(target is m_body) continue; | |
203 | |
204 // Calculate the time to collision | |
205 relativePos = m_body.localPoint(target.position); // - m_position; | |
206 bzVec2 relativeVel = target.linearVelocity - m_velocity; | |
207 float relativeSpeed = relativeVel.length; | |
208 float timeToCollision = bzDot(relativePos, relativeVel) / | |
209 (relativeSpeed * relativeSpeed); | |
210 | |
211 // Check if it is going to be a collision at all | |
212 float distance = relativePos.length; | |
213 float minSeparation = distance - relativeSpeed * shortestTime; | |
214 | |
215 float eRad; | |
216 for (bzShape s = target.shapeList; s; s = s.next) { | |
217 if(s.sweepRadius > eRad) { | |
218 eRad = s.sweepRadius; | |
219 } | |
220 } | |
221 | |
222 if (minSeparation > radius + eRad) continue; | |
223 | |
224 // Check if it is the shortest | |
225 if (timeToCollision > 0 && timeToCollision < shortestTime) { | |
226 | |
227 // Store the time, target and other data | |
228 shortestTime = timeToCollision; | |
229 firstTarget = target; | |
230 firstMinSeparation = minSeparation; | |
231 firstDistance = distance; | |
232 firstRelativePos = relativePos; | |
233 firstRelativeVel = relativeVel; | |
234 rad = eRad; | |
235 } | |
236 } | |
237 | |
238 // 2. Calculate the steering | |
239 | |
240 // If we have no target, then exit | |
241 if(!firstTarget) return bzVec2.zeroVect; | |
242 | |
243 Stdout(shortestTime).newline; | |
244 | |
245 // If we’re going to hit exactly, or if we’re already | |
246 // colliding, then do the steering based on current | |
247 // position. | |
248 if(firstMinSeparation <= 0 || firstDistance < radius + rad) { | |
249 relativePos = firstTarget.position - m_position; | |
250 } else { | |
251 // Otherwise calculate the future relative position: | |
252 relativePos = firstRelativePos + | |
253 firstRelativeVel * shortestTime; | |
254 } | |
255 | |
256 // Avoid the target | |
257 bzVec2 steering = relativePos; | |
258 steering.normalize(); | |
259 //steering.linear = relativePos * maxAcceleration | |
260 | |
261 return steering; | |
262 } | |
263 | |
264 bzVec2 avoid(float maxLookAhead, bzBody obstacles) { | |
182 | 265 |
183 float avoidMargin = 1.0f; | 266 float avoidMargin = 1.0f; |
184 float maxLookahead = minTimeToCollision * m_speed; | 267 float maxLookahead = maxLookAhead * m_speed; |
185 | 268 |
186 // Make sure we're moving | 269 // Make sure we're moving |
187 if (m_velocity.length > 0) | 270 if (m_velocity.length > 0) |
188 { | 271 { |
189 for (bzBody o = obstacles; o; o = o.next) { | 272 for (bzBody o = obstacles; o; o = o.next) { |
219 bzVec2 closestPoint = o.position + movementNormal * distanceToClosest; | 302 bzVec2 closestPoint = o.position + movementNormal * distanceToClosest; |
220 | 303 |
221 // Find the point of avoidance | 304 // Find the point of avoidance |
222 bzVec2 target = o.position + (closestPoint - o.position).length * radius; | 305 bzVec2 target = o.position + (closestPoint - o.position).length * radius; |
223 | 306 |
307 target -= m_position; | |
308 | |
224 auto state = cast(State) m_body.userData; | 309 auto state = cast(State) m_body.userData; |
225 state.avoid = target; | 310 state.avoid = m_body.localPoint(target); |
226 | 311 |
227 return target; | 312 return target; |
228 } | 313 } |
229 } | 314 } |
230 } | 315 } |
231 } | 316 } |