/
Steering.cs
166 lines (134 loc) · 5.04 KB
/
Steering.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.DirectX;
namespace AIcore
{
class Seek : KinematicMovement
{
// Holds the maximum acceleration of the character
float maxAcceleration;
// Returns the desired steering output
public SteeringOutput getSteering()
{
// create the structure to hold our output
SteeringOutput steering = new SteeringOutput();
// get the direction to the target
steering.linear = target.position - character.position;
// give full aceleration is along this direction
steering.linear.Normalize();
steering.linear *= maxAcceleration;
// output the steering
steering.angular = 0;
return steering;
}
}
class Arive : KinematicMovement
{
// Holds the maximum acceleration and speed at the target
float maxAcceleration;
float maxSpeed;
// Holds the radius for arriving at the target
float targetRadius;
// Holds the radius for slowing the movement down
float slowRadius;
// Holds the time over which to achive target speed
float timeToTarget = 0.1f;
public override SteeringOutput getSteering()
{
// Create the structure to hold our output
SteeringOutput steering = new SteeringOutput();
// Get the direction to the target
Vector2 direction = target.position - character.position;
float distance = direction.Length();
// Check if we are there return no steering
if (distance < targetRadius)
return null;
// If we are outside the slowRadius,the go max speed
if (distance > slowRadius)
{
targetSpeed = maxSpeed;
}
else
{
targetSpeed = maxSpeed * distance / slowRadius;
}
// The target velocity combines speed and direction
Vector2 targetVelocity = direction;
targetVelocity.Normalize();
targetVelocity *= targetSpeed;
// Acceleration tries to get to target velocity
steering.linear = targetVelocity - character.velocity;
steering.linear /= timeToTarget;
// Check if the acceleration is too fast
if (steering.linear.Length() > maxAcceleration)
{
steering.linear.Normalize();
steering.linear *= maxAcceleration;
}
// Output the steering
steering.angular = 0.f;
return steering;
}
}
class Align : KinematicMovement
{
// Holds the max angular acceleration and rotation
// of the character
float maxAngularAcceleration;
float maxRotation;
// Holds the radius for arriving at the target
float targetRadius;
// Holds the radius for slowing down
float slowRadius;
// Holds the time over which to achive target speed
float timeToTarget = 0.1f;
public override SteeringOutput getSteering()
{
base.getSteering();
// Create the structure to hold the output
SteeringOutput steering = new SteeringOutput();
// Get the naive direction to target
float rotation = target.orientation - character.orientation;
// Map the result to the (-pi,pi) interval
rotation = mapToRange(rotation);
float rotationAngle = Math.Abs(rotationDirection);
// Check if we are there, return no steering
if (rotationAngle < targetRadius)
return null;
// If we are outside the slowRadius, then use
// maximum rotation
if (rotationAngle > slowRadius)
{
targetRotation = maxRotation;
}
else
{
targetRotation = maxRotation * rotationAngle / slowRadius;
}
// The final target rotation combines
// speed (already in the variable) and direction
targetRotation *= rotation / rotationAngle;
// Acceleration tries to get to the target rotation
steering.angular = targetRotation - character.rotation;
steering.angular /= timeToTarget;
// Check if the acceleration is too great
float angularAcceleration = Math.Abs(steering.angular);
if (angularAcceleration > maxAngularAcceleration)
{
steering.angular /= angularAcceleration;
steering.angular *= maxAngularAcceleration;
}
// Output the steering
steering.linear = new Vector2(0.f,0.f);
return steering;
}
}
/// <summary>
/// This class tries to match the velocity of
/// the target object.
/// </summary>
class VelocityMatch : KinematicMovement
{
}
}