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 }