/
AlignmentBehaviour.java
110 lines (94 loc) · 4.16 KB
/
AlignmentBehaviour.java
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
//Copyright (c) 2014, Jesús Martín Berlanga. All rights reserved. Distributed under the BSD licence. Read "com/jme3/ai/license.txt".
package com.jme3.ai.agents.behaviours.npc.steering;
import com.jme3.ai.agents.Agent;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import java.util.ArrayList;
import java.util.List;
/**
* Craig W. Reynolds: "Alignment steering behavior gives an character the ability
* to align itself with (that is, head in the same direction as) other nearby
* characters. Steering for alignment can be computed by finding all characters
* in the local neighborhood, averaging the unit forward vector of the nearby
* characters. This average is the “desired velocity,” and so the steering vector
* is the difference between the average and our character’s forward vector. This
* steering will tend to turn our character so it is aligned with its neighbors."
*
* @author Jesús Martín Berlanga
* @version 1.0
*/
public class AlignmentBehaviour extends AbstractStrengthSteeringBehaviour {
private List<Agent> neighbours = new ArrayList<Agent>();
public List<Agent> getNeighbours(){return this.neighbours;}
private float maxDistance = Float.POSITIVE_INFINITY;
private float maxAngle = FastMath.PI / 2;
/**
* maxAngle is setted to PI / 2 by default and maxDistance to infinite.
*
* @param agent To whom behaviour belongs.
* @param neighbours Neighbours, this agent is moving toward the center of this neighbours.
*/
public AlignmentBehaviour(Agent agent, List<Agent> neighbours){
super(agent);
this.neighbours = neighbours;
}
/**
* @param maxDistance In order to consider a neihbour inside the neighbourhood
* @param maxAngle In order to consider a neihbour inside the neighbourhood
* @see Agent#inBoidNeighborhoodMaxAngle(com.jme3.ai.agents.Agent, float, float, float)
* @see AlignmentBehaviour#AlignmentBehaviour(com.jme3.ai.agents.Agent, java.util.List)
*/
public AlignmentBehaviour(Agent agent, List<Agent> neighbours, float maxDistance, float maxAngle){
super(agent);
this.neighbours = neighbours;
this.maxDistance = maxDistance;
this.maxAngle = maxAngle;
}
/**
* @param spatial active spatial during excecution of behaviour
* @see AlignmentBehaviour#AlignmentBehaviour(com.jme3.ai.agents.Agent, java.util.List)
*/
public AlignmentBehaviour(Agent agent, Spatial spatial, List<Agent> neighbours) {
super(agent, spatial);
this.neighbours = neighbours;
}
/**
* @see AlignmentBehaviour#AlignmentBehaviour(com.jme3.ai.agents.Agent, java.util.List)
* @see AlignmentBehaviour#AlignmentBehaviour(com.jme3.ai.agents.Agent, java.util.List, float, float)
*/
public AlignmentBehaviour(Agent agent, Spatial spatial, List<Agent> neighbours, float maxDistance, float maxAngle) {
super(agent, spatial);
this.neighbours = neighbours;
this.maxDistance = maxDistance;
this.maxAngle = maxAngle;
}
@Override
Vector3f calculateFullSteering()
{
// steering accumulator and count of neighbors, both initially zero
Vector3f steering = new Vector3f();
int realNeighbors = 0;
// for each of the other vehicles...
for (Agent agentO : this.neighbours)
{
if (this.agent.inBoidNeighborhood(agentO, this.agent.getRadius()*3, this.maxDistance, this.maxAngle))
{
// accumulate sum of neighbor's positions
steering = steering.add(agentO.fordwardVector());
realNeighbors++;
}
}
// divide by neighbors, subtract off current position to get error-correcting direction
if(realNeighbors > 0)
{
steering = steering.divide(realNeighbors);
steering = this.agent.offset(steering);
}
return steering;
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) { }
}