mrpas 2.0.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,11 +17,17 @@ Or grab the code from the [repository](https://bitbucket.org/umbraprojekt/mrpas)
17
17
  Instantiate a `Mrpas` object by passing it the map dimensions and a callback for determining map cell transparency:
18
18
 
19
19
  ```
20
- const Mrpas = require("mrpas").Mrpas;
20
+ const { Mrpas } = require("mrpas");
21
21
 
22
22
  const fov = new Mrpas(20, 20, (x, y) => map[x][y].transparent);
23
23
  ```
24
24
 
25
+ ES modules can import the same named export:
26
+
27
+ ```
28
+ import { Mrpas } from "mrpas";
29
+ ```
30
+
25
31
  ### Compute FOV
26
32
 
27
33
  Compute the field of view for any set of coordinates by calling the `Mrpas#compute()` method and passing it the origin coordinates, FOV calculation radius and two callbacks: one for determining whether a call has been marked as visible, and the othe for marking it as visible:
@@ -0,0 +1,245 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Mrpas = void 0;
4
+ class Mrpas {
5
+ mapWidth;
6
+ mapHeight;
7
+ isTransparent;
8
+ constructor(mapWidth, mapHeight, isTransparent) {
9
+ this.mapWidth = mapWidth;
10
+ this.mapHeight = mapHeight;
11
+ this.isTransparent = isTransparent;
12
+ }
13
+ computeOctantY(deltaX, deltaY, data) {
14
+ const startSlopes = [];
15
+ const endSlopes = [];
16
+ const minX = data.minX;
17
+ const maxX = data.maxX;
18
+ const minY = data.minY;
19
+ const maxY = data.maxY;
20
+ const originX = data.originX;
21
+ const originY = data.originY;
22
+ const isTransparent = this.isTransparent;
23
+ const isVisible = data.isVisible;
24
+ const setVisible = data.setVisible;
25
+ let iteration = 1;
26
+ let totalObstacles = 0;
27
+ let obstaclesInLastLine = 0;
28
+ let minSlope = 0;
29
+ let x;
30
+ let y;
31
+ let halfSlope;
32
+ let processedCell;
33
+ let visible;
34
+ let extended;
35
+ let centreSlope;
36
+ let startSlope;
37
+ let endSlope;
38
+ let previousEndSlope;
39
+ let cellTransparent = false;
40
+ let transparencyChecked;
41
+ let firstCell;
42
+ let behindOpen = false;
43
+ let diagonalOpen;
44
+ for (y = originY + deltaY; y >= minY && y <= maxY; y += deltaY, obstaclesInLastLine = totalObstacles, ++iteration) {
45
+ halfSlope = 0.5 / iteration;
46
+ previousEndSlope = -1;
47
+ for (firstCell = processedCell = Math.floor(minSlope * iteration + 0.5), x = originX + (processedCell * deltaX); processedCell <= iteration && x >= minX && x <= maxX; x += deltaX, ++processedCell, previousEndSlope = endSlope) {
48
+ visible = true;
49
+ extended = false;
50
+ centreSlope = processedCell / iteration;
51
+ startSlope = previousEndSlope;
52
+ endSlope = centreSlope + halfSlope;
53
+ transparencyChecked = false;
54
+ if (obstaclesInLastLine > 0) {
55
+ diagonalOpen = behindOpen;
56
+ behindOpen = isVisible(x, y - deltaY) && isTransparent(x, y - deltaY);
57
+ if (!behindOpen &&
58
+ !(processedCell > firstCell
59
+ ? diagonalOpen
60
+ : isVisible(x - deltaX, y - deltaY) && isTransparent(x - deltaX, y - deltaY))) {
61
+ visible = false;
62
+ }
63
+ else {
64
+ for (var idx = 0; idx < obstaclesInLastLine && visible; ++idx) {
65
+ if (startSlope <= endSlopes[idx] && endSlope >= startSlopes[idx]) {
66
+ if (!transparencyChecked) {
67
+ cellTransparent = isTransparent(x, y);
68
+ transparencyChecked = true;
69
+ }
70
+ if (cellTransparent) {
71
+ if (centreSlope > startSlopes[idx] && centreSlope < endSlopes[idx]) {
72
+ visible = false;
73
+ break;
74
+ }
75
+ }
76
+ else {
77
+ if (startSlope >= startSlopes[idx] && endSlope <= endSlopes[idx]) {
78
+ visible = false;
79
+ break;
80
+ }
81
+ else {
82
+ if (startSlope < startSlopes[idx]) {
83
+ startSlopes[idx] = startSlope;
84
+ }
85
+ if (endSlope > endSlopes[idx]) {
86
+ endSlopes[idx] = endSlope;
87
+ }
88
+ extended = true;
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ if (visible) {
96
+ setVisible(x, y);
97
+ if (!transparencyChecked) {
98
+ cellTransparent = isTransparent(x, y);
99
+ }
100
+ if (!cellTransparent) {
101
+ if (minSlope >= startSlope) {
102
+ minSlope = endSlope;
103
+ }
104
+ else if (!extended) {
105
+ startSlopes[totalObstacles] = startSlope;
106
+ endSlopes[totalObstacles++] = endSlope;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ if (minSlope > 1) {
112
+ break;
113
+ }
114
+ }
115
+ }
116
+ computeOctantX(deltaX, deltaY, data) {
117
+ const startSlopes = [];
118
+ const endSlopes = [];
119
+ const minX = data.minX;
120
+ const maxX = data.maxX;
121
+ const minY = data.minY;
122
+ const maxY = data.maxY;
123
+ const originX = data.originX;
124
+ const originY = data.originY;
125
+ const isTransparent = this.isTransparent;
126
+ const isVisible = data.isVisible;
127
+ const setVisible = data.setVisible;
128
+ let iteration = 1;
129
+ let totalObstacles = 0;
130
+ let obstaclesInLastLine = 0;
131
+ let minSlope = 0;
132
+ let x;
133
+ let y;
134
+ let halfSlope;
135
+ let processedCell;
136
+ let visible;
137
+ let extended;
138
+ let centreSlope;
139
+ let startSlope;
140
+ let endSlope;
141
+ let previousEndSlope;
142
+ let cellTransparent = false;
143
+ let transparencyChecked;
144
+ let firstCell;
145
+ let behindOpen = false;
146
+ let diagonalOpen;
147
+ for (x = originX + deltaX; x >= minX && x <= maxX; x += deltaX, obstaclesInLastLine = totalObstacles, ++iteration) {
148
+ halfSlope = 0.5 / iteration;
149
+ previousEndSlope = -1;
150
+ for (firstCell = processedCell = Math.floor(minSlope * iteration + 0.5), y = originY + (processedCell * deltaY); processedCell <= iteration && y >= minY && y <= maxY; y += deltaY, ++processedCell, previousEndSlope = endSlope) {
151
+ visible = true;
152
+ extended = false;
153
+ centreSlope = processedCell / iteration;
154
+ startSlope = previousEndSlope;
155
+ endSlope = centreSlope + halfSlope;
156
+ transparencyChecked = false;
157
+ if (obstaclesInLastLine > 0) {
158
+ diagonalOpen = behindOpen;
159
+ behindOpen = isVisible(x - deltaX, y) && isTransparent(x - deltaX, y);
160
+ if (!behindOpen &&
161
+ !(processedCell > firstCell
162
+ ? diagonalOpen
163
+ : isVisible(x - deltaX, y - deltaY) && isTransparent(x - deltaX, y - deltaY))) {
164
+ visible = false;
165
+ }
166
+ else {
167
+ for (var idx = 0; idx < obstaclesInLastLine && visible; ++idx) {
168
+ if (startSlope <= endSlopes[idx] && endSlope >= startSlopes[idx]) {
169
+ if (!transparencyChecked) {
170
+ cellTransparent = isTransparent(x, y);
171
+ transparencyChecked = true;
172
+ }
173
+ if (cellTransparent) {
174
+ if (centreSlope > startSlopes[idx] && centreSlope < endSlopes[idx]) {
175
+ visible = false;
176
+ break;
177
+ }
178
+ }
179
+ else {
180
+ if (startSlope >= startSlopes[idx] && endSlope <= endSlopes[idx]) {
181
+ visible = false;
182
+ break;
183
+ }
184
+ else {
185
+ if (startSlope < startSlopes[idx]) {
186
+ startSlopes[idx] = startSlope;
187
+ }
188
+ if (endSlope > endSlopes[idx]) {
189
+ endSlopes[idx] = endSlope;
190
+ }
191
+ extended = true;
192
+ }
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
+ if (visible) {
199
+ setVisible(x, y);
200
+ if (!transparencyChecked) {
201
+ cellTransparent = isTransparent(x, y);
202
+ }
203
+ if (!cellTransparent) {
204
+ if (minSlope >= startSlope) {
205
+ minSlope = endSlope;
206
+ }
207
+ else if (!extended) {
208
+ startSlopes[totalObstacles] = startSlope;
209
+ endSlopes[totalObstacles++] = endSlope;
210
+ }
211
+ }
212
+ }
213
+ }
214
+ if (minSlope > 1) {
215
+ break;
216
+ }
217
+ }
218
+ }
219
+ setMapDimensions(mapWidth, mapHeight) {
220
+ this.mapWidth = mapWidth;
221
+ this.mapHeight = mapHeight;
222
+ }
223
+ compute(originX, originY, radius, isVisible, setVisible) {
224
+ setVisible(originX, originY);
225
+ const data = {
226
+ minX: Math.max(0, originX - radius),
227
+ minY: Math.max(0, originY - radius),
228
+ maxX: Math.min(this.mapWidth - 1, originX + radius),
229
+ maxY: Math.min(this.mapHeight - 1, originY + radius),
230
+ originX: originX,
231
+ originY: originY,
232
+ isVisible: isVisible,
233
+ setVisible: setVisible
234
+ };
235
+ this.computeOctantY(1, 1, data);
236
+ this.computeOctantX(1, 1, data);
237
+ this.computeOctantY(1, -1, data);
238
+ this.computeOctantX(1, -1, data);
239
+ this.computeOctantY(-1, 1, data);
240
+ this.computeOctantX(-1, 1, data);
241
+ this.computeOctantY(-1, -1, data);
242
+ this.computeOctantX(-1, -1, data);
243
+ }
244
+ }
245
+ exports.Mrpas = Mrpas;
@@ -1,6 +1,6 @@
1
- export declare type IsTransparentFunc = (x: number, y: number) => boolean;
2
- export declare type IsVisibleFunc = (x: number, y: number) => boolean;
3
- export declare type SetVisibleFunc = (x: number, y: number) => void;
1
+ export type IsTransparentFunc = (x: number, y: number) => boolean;
2
+ export type IsVisibleFunc = (x: number, y: number) => boolean;
3
+ export type SetVisibleFunc = (x: number, y: number) => void;
4
4
  export declare class Mrpas {
5
5
  private mapWidth;
6
6
  private mapHeight;
@@ -0,0 +1,241 @@
1
+ export class Mrpas {
2
+ mapWidth;
3
+ mapHeight;
4
+ isTransparent;
5
+ constructor(mapWidth, mapHeight, isTransparent) {
6
+ this.mapWidth = mapWidth;
7
+ this.mapHeight = mapHeight;
8
+ this.isTransparent = isTransparent;
9
+ }
10
+ computeOctantY(deltaX, deltaY, data) {
11
+ const startSlopes = [];
12
+ const endSlopes = [];
13
+ const minX = data.minX;
14
+ const maxX = data.maxX;
15
+ const minY = data.minY;
16
+ const maxY = data.maxY;
17
+ const originX = data.originX;
18
+ const originY = data.originY;
19
+ const isTransparent = this.isTransparent;
20
+ const isVisible = data.isVisible;
21
+ const setVisible = data.setVisible;
22
+ let iteration = 1;
23
+ let totalObstacles = 0;
24
+ let obstaclesInLastLine = 0;
25
+ let minSlope = 0;
26
+ let x;
27
+ let y;
28
+ let halfSlope;
29
+ let processedCell;
30
+ let visible;
31
+ let extended;
32
+ let centreSlope;
33
+ let startSlope;
34
+ let endSlope;
35
+ let previousEndSlope;
36
+ let cellTransparent = false;
37
+ let transparencyChecked;
38
+ let firstCell;
39
+ let behindOpen = false;
40
+ let diagonalOpen;
41
+ for (y = originY + deltaY; y >= minY && y <= maxY; y += deltaY, obstaclesInLastLine = totalObstacles, ++iteration) {
42
+ halfSlope = 0.5 / iteration;
43
+ previousEndSlope = -1;
44
+ for (firstCell = processedCell = Math.floor(minSlope * iteration + 0.5), x = originX + (processedCell * deltaX); processedCell <= iteration && x >= minX && x <= maxX; x += deltaX, ++processedCell, previousEndSlope = endSlope) {
45
+ visible = true;
46
+ extended = false;
47
+ centreSlope = processedCell / iteration;
48
+ startSlope = previousEndSlope;
49
+ endSlope = centreSlope + halfSlope;
50
+ transparencyChecked = false;
51
+ if (obstaclesInLastLine > 0) {
52
+ diagonalOpen = behindOpen;
53
+ behindOpen = isVisible(x, y - deltaY) && isTransparent(x, y - deltaY);
54
+ if (!behindOpen &&
55
+ !(processedCell > firstCell
56
+ ? diagonalOpen
57
+ : isVisible(x - deltaX, y - deltaY) && isTransparent(x - deltaX, y - deltaY))) {
58
+ visible = false;
59
+ }
60
+ else {
61
+ for (var idx = 0; idx < obstaclesInLastLine && visible; ++idx) {
62
+ if (startSlope <= endSlopes[idx] && endSlope >= startSlopes[idx]) {
63
+ if (!transparencyChecked) {
64
+ cellTransparent = isTransparent(x, y);
65
+ transparencyChecked = true;
66
+ }
67
+ if (cellTransparent) {
68
+ if (centreSlope > startSlopes[idx] && centreSlope < endSlopes[idx]) {
69
+ visible = false;
70
+ break;
71
+ }
72
+ }
73
+ else {
74
+ if (startSlope >= startSlopes[idx] && endSlope <= endSlopes[idx]) {
75
+ visible = false;
76
+ break;
77
+ }
78
+ else {
79
+ if (startSlope < startSlopes[idx]) {
80
+ startSlopes[idx] = startSlope;
81
+ }
82
+ if (endSlope > endSlopes[idx]) {
83
+ endSlopes[idx] = endSlope;
84
+ }
85
+ extended = true;
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ if (visible) {
93
+ setVisible(x, y);
94
+ if (!transparencyChecked) {
95
+ cellTransparent = isTransparent(x, y);
96
+ }
97
+ if (!cellTransparent) {
98
+ if (minSlope >= startSlope) {
99
+ minSlope = endSlope;
100
+ }
101
+ else if (!extended) {
102
+ startSlopes[totalObstacles] = startSlope;
103
+ endSlopes[totalObstacles++] = endSlope;
104
+ }
105
+ }
106
+ }
107
+ }
108
+ if (minSlope > 1) {
109
+ break;
110
+ }
111
+ }
112
+ }
113
+ computeOctantX(deltaX, deltaY, data) {
114
+ const startSlopes = [];
115
+ const endSlopes = [];
116
+ const minX = data.minX;
117
+ const maxX = data.maxX;
118
+ const minY = data.minY;
119
+ const maxY = data.maxY;
120
+ const originX = data.originX;
121
+ const originY = data.originY;
122
+ const isTransparent = this.isTransparent;
123
+ const isVisible = data.isVisible;
124
+ const setVisible = data.setVisible;
125
+ let iteration = 1;
126
+ let totalObstacles = 0;
127
+ let obstaclesInLastLine = 0;
128
+ let minSlope = 0;
129
+ let x;
130
+ let y;
131
+ let halfSlope;
132
+ let processedCell;
133
+ let visible;
134
+ let extended;
135
+ let centreSlope;
136
+ let startSlope;
137
+ let endSlope;
138
+ let previousEndSlope;
139
+ let cellTransparent = false;
140
+ let transparencyChecked;
141
+ let firstCell;
142
+ let behindOpen = false;
143
+ let diagonalOpen;
144
+ for (x = originX + deltaX; x >= minX && x <= maxX; x += deltaX, obstaclesInLastLine = totalObstacles, ++iteration) {
145
+ halfSlope = 0.5 / iteration;
146
+ previousEndSlope = -1;
147
+ for (firstCell = processedCell = Math.floor(minSlope * iteration + 0.5), y = originY + (processedCell * deltaY); processedCell <= iteration && y >= minY && y <= maxY; y += deltaY, ++processedCell, previousEndSlope = endSlope) {
148
+ visible = true;
149
+ extended = false;
150
+ centreSlope = processedCell / iteration;
151
+ startSlope = previousEndSlope;
152
+ endSlope = centreSlope + halfSlope;
153
+ transparencyChecked = false;
154
+ if (obstaclesInLastLine > 0) {
155
+ diagonalOpen = behindOpen;
156
+ behindOpen = isVisible(x - deltaX, y) && isTransparent(x - deltaX, y);
157
+ if (!behindOpen &&
158
+ !(processedCell > firstCell
159
+ ? diagonalOpen
160
+ : isVisible(x - deltaX, y - deltaY) && isTransparent(x - deltaX, y - deltaY))) {
161
+ visible = false;
162
+ }
163
+ else {
164
+ for (var idx = 0; idx < obstaclesInLastLine && visible; ++idx) {
165
+ if (startSlope <= endSlopes[idx] && endSlope >= startSlopes[idx]) {
166
+ if (!transparencyChecked) {
167
+ cellTransparent = isTransparent(x, y);
168
+ transparencyChecked = true;
169
+ }
170
+ if (cellTransparent) {
171
+ if (centreSlope > startSlopes[idx] && centreSlope < endSlopes[idx]) {
172
+ visible = false;
173
+ break;
174
+ }
175
+ }
176
+ else {
177
+ if (startSlope >= startSlopes[idx] && endSlope <= endSlopes[idx]) {
178
+ visible = false;
179
+ break;
180
+ }
181
+ else {
182
+ if (startSlope < startSlopes[idx]) {
183
+ startSlopes[idx] = startSlope;
184
+ }
185
+ if (endSlope > endSlopes[idx]) {
186
+ endSlopes[idx] = endSlope;
187
+ }
188
+ extended = true;
189
+ }
190
+ }
191
+ }
192
+ }
193
+ }
194
+ }
195
+ if (visible) {
196
+ setVisible(x, y);
197
+ if (!transparencyChecked) {
198
+ cellTransparent = isTransparent(x, y);
199
+ }
200
+ if (!cellTransparent) {
201
+ if (minSlope >= startSlope) {
202
+ minSlope = endSlope;
203
+ }
204
+ else if (!extended) {
205
+ startSlopes[totalObstacles] = startSlope;
206
+ endSlopes[totalObstacles++] = endSlope;
207
+ }
208
+ }
209
+ }
210
+ }
211
+ if (minSlope > 1) {
212
+ break;
213
+ }
214
+ }
215
+ }
216
+ setMapDimensions(mapWidth, mapHeight) {
217
+ this.mapWidth = mapWidth;
218
+ this.mapHeight = mapHeight;
219
+ }
220
+ compute(originX, originY, radius, isVisible, setVisible) {
221
+ setVisible(originX, originY);
222
+ const data = {
223
+ minX: Math.max(0, originX - radius),
224
+ minY: Math.max(0, originY - radius),
225
+ maxX: Math.min(this.mapWidth - 1, originX + radius),
226
+ maxY: Math.min(this.mapHeight - 1, originY + radius),
227
+ originX: originX,
228
+ originY: originY,
229
+ isVisible: isVisible,
230
+ setVisible: setVisible
231
+ };
232
+ this.computeOctantY(1, 1, data);
233
+ this.computeOctantX(1, 1, data);
234
+ this.computeOctantY(1, -1, data);
235
+ this.computeOctantX(1, -1, data);
236
+ this.computeOctantY(-1, 1, data);
237
+ this.computeOctantX(-1, 1, data);
238
+ this.computeOctantY(-1, -1, data);
239
+ this.computeOctantX(-1, -1, data);
240
+ }
241
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/package.json CHANGED
@@ -1,25 +1,41 @@
1
1
  {
2
2
  "name": "mrpas",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "A Field of View (FOV) computation algorithm.",
5
- "main": "src/index.js",
5
+ "main": "dist/cjs/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/esm/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/esm/index.d.ts",
11
+ "import": "./dist/esm/index.js",
12
+ "require": "./dist/cjs/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
6
18
  "scripts": {
7
- "watch": "tsc --watch",
8
- "build": "tsc"
19
+ "build": "npm run build:esm && npm run build:cjs",
20
+ "build:esm": "tsc -p tsconfig.esm.json",
21
+ "build:cjs": "tsc -p tsconfig.cjs.json",
22
+ "watch": "tsc --watch -p tsconfig.esm.json"
9
23
  },
10
- "typings": "src/index.d.ts",
11
24
  "repository": {
12
25
  "type": "git",
13
- "url": "https://bitbucket.org/umbraprojekt/mrpas.git"
26
+ "url": "git+https://github.com/mingos777/mrpas.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/mingos777/mrpas/issues"
14
30
  },
15
31
  "keywords": [
16
32
  "fov",
17
33
  "roguelike"
18
34
  ],
19
- "author": "Dominik Marczuk <mingos.nospam@gmail.com> (http://dominikmarczuk.pl)",
35
+ "author": "Dominik Marczuk <mingos.nospam@gmail.com> (https://dominikmarczuk.pl)",
20
36
  "license": "BSD-2-Clause",
21
- "homepage": "https://bitbucket.org/mingos/mrpas",
37
+ "homepage": "https://github.com/mingos777/mrpas",
22
38
  "devDependencies": {
23
- "typescript": "^3.2.2"
39
+ "typescript": "^7.0.2"
24
40
  }
25
41
  }
package/CHANGELOG.md DELETED
@@ -1,20 +0,0 @@
1
- # Changelog
2
-
3
- ## 2.0.0
4
- ### Bugfixes
5
- * fixed iterator increment again
6
- * fixed floating point logic in determining initial processed cell per octant row/column
7
- ### Modified features
8
- * refactored code for brevity and readability
9
- ### New features
10
- * ported to TypeScript
11
- ### API break
12
- * exported module is now named. Call `require("mrpas").Mrpas` to import.
13
-
14
- ## 1.2.1 (2017-02-20)
15
- ### Bugfixes
16
- * fixed iterator being incremented twice, causing incorrect FOV shape in ES5 version
17
-
18
- ## 1.2.0 (2017-02-18)
19
- * Initial release, based on C code available in [libtcod](https://bitbucket.org/libtcod/libtcod).
20
- * Created ES5 and ES6 versions.
package/src/index.js DELETED
@@ -1,181 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var Mrpas = (function () {
4
- function Mrpas(mapWidth, mapHeight, isTransparent) {
5
- this.mapWidth = mapWidth;
6
- this.mapHeight = mapHeight;
7
- this.isTransparent = isTransparent;
8
- }
9
- Mrpas.prototype.computeOctantY = function (deltaX, deltaY, data) {
10
- var startSlopes = [];
11
- var endSlopes = [];
12
- var iteration = 1;
13
- var totalObstacles = 0;
14
- var obstaclesInLastLine = 0;
15
- var minSlope = 0;
16
- var x;
17
- var y;
18
- var halfSlope;
19
- var processedCell;
20
- var visible;
21
- var extended;
22
- var centreSlope;
23
- var startSlope;
24
- var endSlope;
25
- var previousEndSlope;
26
- for (y = data.originY + deltaY; y >= data.minY && y <= data.maxY; y += deltaY, obstaclesInLastLine = totalObstacles, ++iteration) {
27
- halfSlope = 0.5 / iteration;
28
- previousEndSlope = -1;
29
- for (processedCell = Math.floor(minSlope * iteration + 0.5), x = data.originX + (processedCell * deltaX); processedCell <= iteration && x >= data.minX && x <= data.maxX; x += deltaX, ++processedCell, previousEndSlope = endSlope) {
30
- visible = true;
31
- extended = false;
32
- centreSlope = processedCell / iteration;
33
- startSlope = previousEndSlope;
34
- endSlope = centreSlope + halfSlope;
35
- if (obstaclesInLastLine > 0) {
36
- if (!(data.isVisible(x, y - deltaY) &&
37
- this.isTransparent(x, y - deltaY)) &&
38
- !(data.isVisible(x - deltaX, y - deltaY) &&
39
- this.isTransparent(x - deltaX, y - deltaY))) {
40
- visible = false;
41
- }
42
- else {
43
- for (var idx = 0; idx < obstaclesInLastLine && visible; ++idx) {
44
- if (startSlope <= endSlopes[idx] && endSlope >= startSlopes[idx]) {
45
- if (this.isTransparent(x, y)) {
46
- if (centreSlope > startSlopes[idx] && centreSlope < endSlopes[idx]) {
47
- visible = false;
48
- break;
49
- }
50
- }
51
- else {
52
- if (startSlope >= startSlopes[idx] && endSlope <= endSlopes[idx]) {
53
- visible = false;
54
- break;
55
- }
56
- else {
57
- startSlopes[idx] = Math.min(startSlopes[idx], startSlope);
58
- endSlopes[idx] = Math.max(endSlopes[idx], endSlope);
59
- extended = true;
60
- }
61
- }
62
- }
63
- }
64
- }
65
- }
66
- if (visible) {
67
- data.setVisible(x, y);
68
- if (!this.isTransparent(x, y)) {
69
- if (minSlope >= startSlope) {
70
- minSlope = endSlope;
71
- }
72
- else if (!extended) {
73
- startSlopes[totalObstacles] = startSlope;
74
- endSlopes[totalObstacles++] = endSlope;
75
- }
76
- }
77
- }
78
- }
79
- }
80
- };
81
- Mrpas.prototype.computeOctantX = function (deltaX, deltaY, data) {
82
- var startSlopes = [];
83
- var endSlopes = [];
84
- var iteration = 1;
85
- var totalObstacles = 0;
86
- var obstaclesInLastLine = 0;
87
- var minSlope = 0;
88
- var x;
89
- var y;
90
- var halfSlope;
91
- var processedCell;
92
- var visible;
93
- var extended;
94
- var centreSlope;
95
- var startSlope;
96
- var endSlope;
97
- var previousEndSlope;
98
- for (x = data.originX + deltaX; x >= data.minX && x <= data.maxX; x += deltaX, obstaclesInLastLine = totalObstacles, ++iteration) {
99
- halfSlope = 0.5 / iteration;
100
- previousEndSlope = -1;
101
- for (processedCell = Math.floor(minSlope * iteration + 0.5), y = data.originY + (processedCell * deltaY); processedCell <= iteration && y >= data.minY && y <= data.maxY; y += deltaY, ++processedCell, previousEndSlope = endSlope) {
102
- visible = true;
103
- extended = false;
104
- centreSlope = processedCell / iteration;
105
- startSlope = previousEndSlope;
106
- endSlope = centreSlope + halfSlope;
107
- if (obstaclesInLastLine > 0) {
108
- if (!(data.isVisible(x - deltaX, y) &&
109
- this.isTransparent(x - deltaX, y)) &&
110
- !(data.isVisible(x - deltaX, y - deltaY) &&
111
- this.isTransparent(x - deltaX, y - deltaY))) {
112
- visible = false;
113
- }
114
- else {
115
- for (var idx = 0; idx < obstaclesInLastLine && visible; ++idx) {
116
- if (startSlope <= endSlopes[idx] && endSlope >= startSlopes[idx]) {
117
- if (this.isTransparent(x, y)) {
118
- if (centreSlope > startSlopes[idx] && centreSlope < endSlopes[idx]) {
119
- visible = false;
120
- break;
121
- }
122
- }
123
- else {
124
- if (startSlope >= startSlopes[idx] && endSlope <= endSlopes[idx]) {
125
- visible = false;
126
- break;
127
- }
128
- else {
129
- startSlopes[idx] = Math.min(startSlopes[idx], startSlope);
130
- endSlopes[idx] = Math.max(endSlopes[idx], endSlope);
131
- extended = true;
132
- }
133
- }
134
- }
135
- }
136
- }
137
- }
138
- if (visible) {
139
- data.setVisible(x, y);
140
- if (!this.isTransparent(x, y)) {
141
- if (minSlope >= startSlope) {
142
- minSlope = endSlope;
143
- }
144
- else if (!extended) {
145
- startSlopes[totalObstacles] = startSlope;
146
- endSlopes[totalObstacles++] = endSlope;
147
- }
148
- }
149
- }
150
- }
151
- }
152
- };
153
- Mrpas.prototype.setMapDimensions = function (mapWidth, mapHeight) {
154
- this.mapWidth = mapWidth;
155
- this.mapHeight = mapHeight;
156
- };
157
- Mrpas.prototype.compute = function (originX, originY, radius, isVisible, setVisible) {
158
- setVisible(originX, originY);
159
- var data = {
160
- minX: Math.max(0, originX - radius),
161
- minY: Math.max(0, originY - radius),
162
- maxX: Math.min(this.mapWidth - 1, originX + radius),
163
- maxY: Math.min(this.mapHeight - 1, originY + radius),
164
- originX: originX,
165
- originY: originY,
166
- radius: radius,
167
- isVisible: isVisible,
168
- setVisible: setVisible
169
- };
170
- this.computeOctantY(1, 1, data);
171
- this.computeOctantX(1, 1, data);
172
- this.computeOctantY(1, -1, data);
173
- this.computeOctantX(1, -1, data);
174
- this.computeOctantY(-1, 1, data);
175
- this.computeOctantX(-1, 1, data);
176
- this.computeOctantY(-1, -1, data);
177
- this.computeOctantX(-1, -1, data);
178
- };
179
- return Mrpas;
180
- }());
181
- exports.Mrpas = Mrpas;
File without changes