38 public static void advance(TurbulenceParams params) {
40 if (params.propagationAmount > 1f) params.propagationAmount = 1f;
42 Vector2f[][] f = params.field.getField();
43 float s = params.field.getCellSize();
45 float effectWidth = params.effectWidth;
46 float effectLength = params.effectLength;
48 Vector2f[][] delta =
new Vector2f[f.length][f[0].length];
49 for (
int i = 0; i < f.length; i++) {
50 for (
int j = 0; j < f[0].length; j++) {
51 delta[i][j] =
new Vector2f();
57 for (
int i = 0; i < f.length; i++) {
58 for (
int j = 0; j < f[0].length; j++) {
64 Vector2f dir = Misc.normalise(
new Vector2f(v));
66 Vector2f p1 =
new Vector2f(dir);
67 p1.scale(-effectLength * 0.5f);
71 Vector2f p2 =
new Vector2f(dir);
72 p2.scale(effectLength * 0.5f);
77 float minX = Math.min(p1.x - effectWidth * 0.5f, p2.x - effectWidth * 0.5f);
78 float maxX = Math.max(p1.x + effectWidth * 0.5f, p2.x + effectWidth * 0.5f);
79 float minY = Math.min(p1.y - effectLength * 0.5f, p2.y - effectLength * 0.5f);
80 float maxY = Math.max(p1.y + effectLength * 0.5f, p2.y + effectLength * 0.5f);
82 int cellX1 = (int) (minX / s);
83 int cellY1 = (int) (minY / s);
84 if (minX < 0) cellX1 = (int) (-1f * Math.abs(minX) / s) - 1;
85 if (minY < 0) cellY1 = (int) (-1f * Math.abs(minY) / s) - 1;
87 int cellX2 = (int) (maxX / s);
88 int cellY2 = (int) (maxY / s);
89 if (maxX < 0) cellX2 = (int) (-1f * Math.abs(maxX) / s) - 1;
90 if (maxY < 0) cellY2 = (int) (-1f * Math.abs(maxY) / s) - 1;
94 float velDir = Misc.getAngleInDegrees(dir);
95 velDir = Misc.normalizeAngle(velDir);
103 for (
int a = cellX1; a <= cellX2; a++) {
104 for (
int b = cellY1; b <= cellY2; b++) {
105 if (a == i && b == j)
continue;
107 Vector2f p3 =
new Vector2f(a * s, b * s);
109 float u = (p3.x - p1.x) * (p2.x - p1.x) + (p3.y - p1.y) * (p2.y - p1.y);
110 float denom = Vector2f.sub(p2, p1,
new Vector2f()).length();
112 if (denom == 0)
continue;
115 if (u >= 0 && u <= 1) {
116 Vector2f intersect =
new Vector2f();
117 intersect.x = p1.x + u * (p2.x - p1.x);
118 intersect.y = p1.y + u * (p2.y - p1.y);
119 float distFromLine = Vector2f.sub(intersect, p3,
new Vector2f()).length();
120 float distAlongLine = Math.abs((u - 0.5f) * effectLength);
121 if (distFromLine > effectWidth * 0.5f)
continue;
122 if (distAlongLine > effectLength * 0.5f)
continue;
124 float rateMult = (0.5f * (1f - distFromLine / (effectWidth * 0.5f))) +
125 (0.5f * (1f - distAlongLine / (effectLength * 0.5f)));
129 float offsetMult = (distFromLine / (effectWidth * 0.5f)) *
130 (0.5f + 0.5f * distAlongLine / (effectLength * 0.5f));
131 float deltaAngleOffset = offsetMult * params.maxDispersionAngle;
134 float offsetDir = 0f;
135 float diff = Misc.normalizeAngle(Misc.getAngleInDegrees(p1, p3)) - velDir;
137 if (diff < 0) diff += 360;
138 if (diff == 0 || diff == 360f) {
140 }
else if (diff > 180) {
152 Vector2f dv = Misc.getUnitVectorAtDegreeAngle(velDir + deltaAngleOffset * offsetDir);
153 Vector2f d =
getCell(delta, a, b);
154 Vector2f destVel =
getCell(f, a, b);
156 DeltaData data =
new DeltaData(d, destVel, dv, rateMult);
162 float totalWeight = 0f;
163 for (DeltaData data : deltaData) {
164 totalWeight += data.weight;
167 float speed = v.length();
168 float energy = 0.5f * speed * speed;
169 float energyToTransfer = energy * params.propagationAmount;
171 if (totalWeight > 0) {
172 for (DeltaData data : deltaData) {
173 float mult = data.weight / totalWeight;
174 float energyToAdd = energyToTransfer * mult;
178 float speedOther = data.velocity.length();
179 float speedOtherNew = (float) Math.sqrt(speedOther * speedOther + params.energyTransferMult * energyToAdd);
180 float speedAdd = speedOtherNew - speedOther;
181 data.delta.x += data.dir.x * speedAdd;
182 data.delta.y += data.dir.y * speedAdd;
187 float speedNew = (float) Math.sqrt(speed * speed - 2f * energyToTransfer);
188 float speedAdd = speedNew - speed;
189 Vector2f deltaForCurrCell =
getCell(delta, i, j);
190 deltaForCurrCell.x += dir.x * speedAdd;
191 deltaForCurrCell.y += dir.y * speedAdd;
196 float maxVel = params.maxVelocity;
197 for (
int i = 0; i < f.length; i++) {
198 for (
int j = 0; j < f[0].length; j++) {
199 Vector2f.add(f[i][j], delta[i][j], f[i][j]);
200 float len = f[i][j].length();
202 f[i][j].scale(maxVel/len);
208 float dampenFraction = params.dampenFactor;
210 if (dampenFraction > 0) {
211 for (
int i = 0; i < f.length; i++) {
212 for (
int j = 0; j < f[0].length; j++) {
213 Vector2f v = f[i][j];
216 float speed = v.length();
217 float dampen = speed * params.propagationAmount * dampenFraction;
219 v.scale((speed - dampen) / speed);