@equinor/esv-intersection 3.0.1 → 3.0.4
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/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2241 -1938
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/package.json +21 -22
- package/dist/components/axis.d.ts +0 -47
- package/dist/components/index.d.ts +0 -1
- package/dist/control/ExtendedCurveInterpolator.d.ts +0 -58
- package/dist/control/IntersectionReferenceSystem.d.ts +0 -96
- package/dist/control/LayerManager.d.ts +0 -76
- package/dist/control/MainController.d.ts +0 -154
- package/dist/control/ZoomPanHandler.d.ts +0 -158
- package/dist/control/index.d.ts +0 -5
- package/dist/control/interfaces.d.ts +0 -37
- package/dist/control/overlay.d.ts +0 -20
- package/dist/datautils/colortable.d.ts +0 -1
- package/dist/datautils/findsample.d.ts +0 -2
- package/dist/datautils/index.d.ts +0 -6
- package/dist/datautils/interfaces.d.ts +0 -63
- package/dist/datautils/picks.d.ts +0 -74
- package/dist/datautils/schematicShapeGenerator.d.ts +0 -59
- package/dist/datautils/seismicimage.d.ts +0 -45
- package/dist/datautils/surfacedata.d.ts +0 -10
- package/dist/datautils/trajectory.d.ts +0 -14
- package/dist/layers/CalloutCanvasLayer.d.ts +0 -60
- package/dist/layers/CustomDisplayObjects/ComplexRope.d.ts +0 -22
- package/dist/layers/CustomDisplayObjects/ComplexRopeGeometry.d.ts +0 -27
- package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRope.d.ts +0 -20
- package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.d.ts +0 -26
- package/dist/layers/CustomDisplayObjects/UniformTextureStretchRope.d.ts +0 -17
- package/dist/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.d.ts +0 -24
- package/dist/layers/GeomodelCanvasLayer.d.ts +0 -28
- package/dist/layers/GeomodelLabelsLayer.d.ts +0 -49
- package/dist/layers/GeomodelLayerV2.d.ts +0 -12
- package/dist/layers/GridLayer.d.ts +0 -29
- package/dist/layers/ImageCanvasLayer.d.ts +0 -20
- package/dist/layers/ReferenceLineLayer.d.ts +0 -29
- package/dist/layers/SchematicLayer.d.ts +0 -113
- package/dist/layers/SeismicCanvasLayer.d.ts +0 -18
- package/dist/layers/WellborePathLayer.d.ts +0 -17
- package/dist/layers/base/CanvasLayer.d.ts +0 -19
- package/dist/layers/base/HTMLLayer.d.ts +0 -13
- package/dist/layers/base/Layer.d.ts +0 -69
- package/dist/layers/base/PixiLayer.d.ts +0 -32
- package/dist/layers/base/SVGLayer.d.ts +0 -13
- package/dist/layers/base/index.d.ts +0 -5
- package/dist/layers/index.d.ts +0 -16
- package/dist/layers/schematicInterfaces.d.ts +0 -208
- package/dist/utils/arc-length.d.ts +0 -23
- package/dist/utils/binary-search.d.ts +0 -8
- package/dist/utils/color.d.ts +0 -5
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/root-finder.d.ts +0 -34
- package/dist/utils/text.d.ts +0 -14
- package/dist/utils/vectorUtils.d.ts +0 -15
- package/dist/vendor/pixi-dashed-line/index.d.ts +0 -57
- package/src/components/axis.ts +0 -247
- package/src/components/index.ts +0 -1
- package/src/control/ExtendedCurveInterpolator.ts +0 -155
- package/src/control/IntersectionReferenceSystem.ts +0 -391
- package/src/control/LayerManager.ts +0 -294
- package/src/control/MainController.ts +0 -296
- package/src/control/ZoomPanHandler.ts +0 -436
- package/src/control/index.ts +0 -5
- package/src/control/interfaces.ts +0 -42
- package/src/control/overlay.ts +0 -118
- package/src/datautils/colortable.ts +0 -14
- package/src/datautils/findsample.ts +0 -64
- package/src/datautils/index.ts +0 -6
- package/src/datautils/interfaces.ts +0 -68
- package/src/datautils/picks.ts +0 -328
- package/src/datautils/schematicShapeGenerator.ts +0 -1007
- package/src/datautils/seismicimage.ts +0 -180
- package/src/datautils/surfacedata.ts +0 -318
- package/src/datautils/trajectory.ts +0 -206
- package/src/layers/CalloutCanvasLayer.ts +0 -338
- package/src/layers/CustomDisplayObjects/ComplexRope.ts +0 -45
- package/src/layers/CustomDisplayObjects/ComplexRopeGeometry.ts +0 -190
- package/src/layers/CustomDisplayObjects/FixedWidthSimpleRope.ts +0 -41
- package/src/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.ts +0 -149
- package/src/layers/CustomDisplayObjects/UniformTextureStretchRope.ts +0 -39
- package/src/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.ts +0 -174
- package/src/layers/GeomodelCanvasLayer.ts +0 -176
- package/src/layers/GeomodelLabelsLayer.ts +0 -619
- package/src/layers/GeomodelLayerV2.ts +0 -110
- package/src/layers/GridLayer.ts +0 -145
- package/src/layers/ImageCanvasLayer.ts +0 -55
- package/src/layers/ReferenceLineLayer.ts +0 -185
- package/src/layers/SchematicLayer.ts +0 -871
- package/src/layers/SeismicCanvasLayer.ts +0 -46
- package/src/layers/WellborePathLayer.ts +0 -129
- package/src/layers/base/CanvasLayer.ts +0 -102
- package/src/layers/base/HTMLLayer.ts +0 -70
- package/src/layers/base/Layer.ts +0 -217
- package/src/layers/base/PixiLayer.ts +0 -190
- package/src/layers/base/SVGLayer.ts +0 -63
- package/src/layers/base/index.ts +0 -5
- package/src/layers/index.ts +0 -16
- package/src/layers/schematicInterfaces.ts +0 -470
- package/src/utils/arc-length.ts +0 -66
- package/src/utils/binary-search.ts +0 -26
- package/src/utils/color.ts +0 -22
- package/src/utils/index.ts +0 -1
- package/src/utils/root-finder.ts +0 -78
- package/src/utils/text.ts +0 -88
- package/src/utils/vectorUtils.ts +0 -67
- package/src/vendor/pixi-dashed-line/index.ts +0 -394
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
import { ScaleLinear } from 'd3-scale';
|
|
2
|
-
|
|
3
|
-
import { CanvasLayer } from './base/CanvasLayer';
|
|
4
|
-
import { OnUpdateEvent, Annotation, OnRescaleEvent, BoundingBox } from '../interfaces';
|
|
5
|
-
import { calcSize, isOverlapping, getOverlapOffset } from '../utils';
|
|
6
|
-
import { LayerOptions } from './base/Layer';
|
|
7
|
-
|
|
8
|
-
const DEFAULT_MIN_FONT_SIZE = 7;
|
|
9
|
-
const DEFAULT_MAX_FONT_SIZE = 11;
|
|
10
|
-
const DEFAULT_FONT_SIZE_FACTOR = 7;
|
|
11
|
-
|
|
12
|
-
const DEFAULT_OFFSET_MIN = 20;
|
|
13
|
-
const DEFAULT_OFFSET_MAX = 120;
|
|
14
|
-
const DEFAULT_OFFSET_FACTOR = 19;
|
|
15
|
-
|
|
16
|
-
const Location = {
|
|
17
|
-
topleft: 'topleft',
|
|
18
|
-
topright: 'topright',
|
|
19
|
-
bottomleft: 'bottomleft',
|
|
20
|
-
bottomright: 'bottomright',
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export type Point = {
|
|
24
|
-
x: number;
|
|
25
|
-
y: number;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export type Callout = {
|
|
29
|
-
title: string;
|
|
30
|
-
label: string;
|
|
31
|
-
color: string;
|
|
32
|
-
pos: Point;
|
|
33
|
-
group: string;
|
|
34
|
-
alignment: string;
|
|
35
|
-
boundingBox: BoundingBox;
|
|
36
|
-
dx: number;
|
|
37
|
-
dy: number;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export interface CalloutOptions<T extends Annotation[]> extends LayerOptions<T> {
|
|
41
|
-
minFontSize?: number;
|
|
42
|
-
maxFontSize?: number;
|
|
43
|
-
fontSizeFactor?: number;
|
|
44
|
-
offsetMin?: number;
|
|
45
|
-
offsetMax?: number;
|
|
46
|
-
offsetFactor?: number;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export class CalloutCanvasLayer<T extends Annotation[]> extends CanvasLayer<T> {
|
|
50
|
-
rescaleEvent: OnRescaleEvent;
|
|
51
|
-
xRatio: number;
|
|
52
|
-
callouts: Callout[];
|
|
53
|
-
groupFilter: string[] = null;
|
|
54
|
-
minFontSize: number;
|
|
55
|
-
maxFontSize: number;
|
|
56
|
-
fontSizeFactor: number;
|
|
57
|
-
offsetMin: number;
|
|
58
|
-
offsetMax: number;
|
|
59
|
-
offsetFactor: number;
|
|
60
|
-
|
|
61
|
-
constructor(id?: string, options?: CalloutOptions<T>) {
|
|
62
|
-
super(id, options);
|
|
63
|
-
this.minFontSize = options.minFontSize || DEFAULT_MIN_FONT_SIZE;
|
|
64
|
-
this.maxFontSize = options.maxFontSize || DEFAULT_MAX_FONT_SIZE;
|
|
65
|
-
this.fontSizeFactor = options.fontSizeFactor || DEFAULT_FONT_SIZE_FACTOR;
|
|
66
|
-
this.offsetMin = options.offsetMin || DEFAULT_OFFSET_MIN;
|
|
67
|
-
this.offsetMax = options.offsetMax || DEFAULT_OFFSET_MAX;
|
|
68
|
-
this.offsetFactor = options.offsetFactor || DEFAULT_OFFSET_FACTOR;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
setGroupFilter(filter: string[]): void {
|
|
72
|
-
this.groupFilter = filter;
|
|
73
|
-
this.callouts = undefined;
|
|
74
|
-
this.render();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
onUpdate(event: OnUpdateEvent<T>): void {
|
|
78
|
-
super.onUpdate(event);
|
|
79
|
-
|
|
80
|
-
this.callouts = undefined;
|
|
81
|
-
|
|
82
|
-
this.render();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
onRescale(event: OnRescaleEvent): void {
|
|
86
|
-
super.onRescale(event);
|
|
87
|
-
const isPanning = this.rescaleEvent && this.rescaleEvent.xRatio === event.xRatio;
|
|
88
|
-
this.rescaleEvent = event;
|
|
89
|
-
|
|
90
|
-
this.render(isPanning);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
render(isPanning = false): void {
|
|
94
|
-
requestAnimationFrame(() => {
|
|
95
|
-
this.clearCanvas();
|
|
96
|
-
|
|
97
|
-
if (!this.data || !this.rescaleEvent || !this.referenceSystem) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const { xScale, yScale, xBounds } = this.rescaleEvent;
|
|
102
|
-
|
|
103
|
-
const fontSize = calcSize(this.fontSizeFactor, this.minFontSize, this.maxFontSize, xScale);
|
|
104
|
-
|
|
105
|
-
if (!isPanning || !this.callouts) {
|
|
106
|
-
const { data, ctx, groupFilter } = this;
|
|
107
|
-
const { calculateDisplacementFromBottom } = this.referenceSystem.options;
|
|
108
|
-
const isLeftToRight = calculateDisplacementFromBottom ? xBounds[0] < xBounds[1] : xBounds[0] > xBounds[1];
|
|
109
|
-
const scale = 0;
|
|
110
|
-
|
|
111
|
-
ctx.font = `bold ${fontSize}px arial`;
|
|
112
|
-
const filtered = data.filter((d: Annotation) => !groupFilter || groupFilter.includes(d.group));
|
|
113
|
-
const offset = calcSize(this.offsetFactor, this.offsetMin, this.offsetMax, xScale);
|
|
114
|
-
this.callouts = this.positionCallouts(filtered, isLeftToRight, xScale, yScale, scale, fontSize, offset);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
this.callouts.forEach((callout) => {
|
|
118
|
-
const { pos, title, color } = callout;
|
|
119
|
-
const x = xScale(pos.x);
|
|
120
|
-
const y = yScale(pos.y);
|
|
121
|
-
|
|
122
|
-
const calloutBB = {
|
|
123
|
-
x,
|
|
124
|
-
y,
|
|
125
|
-
width: callout.boundingBox.width,
|
|
126
|
-
height: fontSize,
|
|
127
|
-
offsetX: callout.dx,
|
|
128
|
-
offsetY: callout.dy,
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
this.renderCallout(title, callout.label, calloutBB, color, callout.alignment);
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
private renderAnnotation = (title: string, label: string, x: number, y: number, fontSize: number, color: string): void => {
|
|
137
|
-
this.renderText(title, x, y - fontSize, fontSize, color, 'arial', 'bold');
|
|
138
|
-
this.renderText(label, x, y, fontSize, color);
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
private renderText(
|
|
142
|
-
title: string,
|
|
143
|
-
x: number,
|
|
144
|
-
y: number,
|
|
145
|
-
fontSize: number,
|
|
146
|
-
color: string,
|
|
147
|
-
font: string = 'arial',
|
|
148
|
-
fontStyle: string = 'normal',
|
|
149
|
-
): void {
|
|
150
|
-
const { ctx } = this;
|
|
151
|
-
ctx.font = `${fontStyle} ${fontSize}px ${font}`;
|
|
152
|
-
ctx.fillStyle = color;
|
|
153
|
-
ctx.fillText(title, x, y);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private renderPoint(x: number, y: number, radius: number = 3): void {
|
|
157
|
-
const { ctx } = this;
|
|
158
|
-
ctx.beginPath();
|
|
159
|
-
ctx.moveTo(x, y);
|
|
160
|
-
ctx.arc(x, y, radius, 0, Math.PI * 2);
|
|
161
|
-
ctx.fill();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
private renderCallout(title: string, label: string, boundingBox: BoundingBox, color: string, location: string): void {
|
|
165
|
-
const pos = this.getPosition(boundingBox, location);
|
|
166
|
-
const { x, y } = pos;
|
|
167
|
-
const { height, width, x: dotX, y: dotY } = boundingBox;
|
|
168
|
-
|
|
169
|
-
const placeLeft = location === Location.topright || location === Location.bottomright;
|
|
170
|
-
this.renderAnnotation(title, label, x, y, height, color);
|
|
171
|
-
this.renderPoint(dotX, dotY);
|
|
172
|
-
this.renderLine(x, y, width, dotX, dotY, color, placeLeft);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
private renderLine = (x: number, y: number, width: number, dotX: number, dotY: number, color: string, placeLeft: boolean = true): void => {
|
|
176
|
-
const { ctx } = this;
|
|
177
|
-
const textX = placeLeft ? x : x + width;
|
|
178
|
-
const inverseTextX = placeLeft ? x + width : x;
|
|
179
|
-
const textY = y + 2;
|
|
180
|
-
|
|
181
|
-
ctx.strokeStyle = color;
|
|
182
|
-
ctx.lineWidth = 1;
|
|
183
|
-
|
|
184
|
-
ctx.beginPath();
|
|
185
|
-
ctx.moveTo(dotX, dotY);
|
|
186
|
-
ctx.lineTo(textX, textY);
|
|
187
|
-
ctx.lineTo(inverseTextX, textY);
|
|
188
|
-
|
|
189
|
-
ctx.stroke();
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
private getPosition(boundingBox: BoundingBox, location: string): Point {
|
|
193
|
-
const { x, y, offsetX, offsetY, width } = boundingBox;
|
|
194
|
-
switch (location) {
|
|
195
|
-
case Location.topleft:
|
|
196
|
-
return {
|
|
197
|
-
x: x - width - offsetX,
|
|
198
|
-
y: y - offsetY,
|
|
199
|
-
};
|
|
200
|
-
case Location.topright:
|
|
201
|
-
return {
|
|
202
|
-
x: x + offsetX,
|
|
203
|
-
y: y - offsetY,
|
|
204
|
-
};
|
|
205
|
-
case Location.bottomleft:
|
|
206
|
-
return {
|
|
207
|
-
x: x - width - offsetX,
|
|
208
|
-
y: y + offsetY,
|
|
209
|
-
};
|
|
210
|
-
case Location.bottomright:
|
|
211
|
-
return {
|
|
212
|
-
x: x + offsetX,
|
|
213
|
-
y: y + offsetY,
|
|
214
|
-
};
|
|
215
|
-
default:
|
|
216
|
-
return {
|
|
217
|
-
x,
|
|
218
|
-
y,
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Calculates position of a list of annotations
|
|
224
|
-
positionCallouts(
|
|
225
|
-
annotations: Annotation[],
|
|
226
|
-
isLeftToRight: boolean,
|
|
227
|
-
xScale: ScaleLinear<number, number>,
|
|
228
|
-
yScale: ScaleLinear<number, number>,
|
|
229
|
-
_scale: number,
|
|
230
|
-
fontSize: number,
|
|
231
|
-
offset: number = 20,
|
|
232
|
-
): Callout[] {
|
|
233
|
-
if (annotations.length === 0) {
|
|
234
|
-
return [];
|
|
235
|
-
}
|
|
236
|
-
const alignment = isLeftToRight ? Location.topleft : Location.topright;
|
|
237
|
-
|
|
238
|
-
const nodes = annotations.map((a) => {
|
|
239
|
-
const pos = a.pos ? a.pos : this.referenceSystem.project(a.md);
|
|
240
|
-
return {
|
|
241
|
-
title: a.title,
|
|
242
|
-
label: a.label,
|
|
243
|
-
color: a.color,
|
|
244
|
-
pos: { x: pos[0], y: pos[1] },
|
|
245
|
-
group: a.group,
|
|
246
|
-
alignment,
|
|
247
|
-
boundingBox: this.getAnnotationBoundingBox(a.title, a.label, pos, xScale, yScale, fontSize),
|
|
248
|
-
dx: offset,
|
|
249
|
-
dy: offset,
|
|
250
|
-
};
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
const top = [nodes[nodes.length - 1]];
|
|
254
|
-
const bottom: Callout[] = [];
|
|
255
|
-
|
|
256
|
-
// Initial best effort
|
|
257
|
-
this.chooseTopOrBottomPosition(nodes, bottom, top);
|
|
258
|
-
|
|
259
|
-
// Adjust position for top set
|
|
260
|
-
this.adjustTopPositions(top);
|
|
261
|
-
|
|
262
|
-
// Adjust position for bottom set
|
|
263
|
-
this.adjustBottomPositions(bottom);
|
|
264
|
-
|
|
265
|
-
return nodes;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
getAnnotationBoundingBox(
|
|
269
|
-
title: string,
|
|
270
|
-
label: string,
|
|
271
|
-
pos: number[],
|
|
272
|
-
xScale: ScaleLinear<number, number>,
|
|
273
|
-
yScale: ScaleLinear<number, number>,
|
|
274
|
-
height: number,
|
|
275
|
-
): { x: number; y: number; width: number; height: number } {
|
|
276
|
-
const { ctx } = this;
|
|
277
|
-
const ax1 = xScale(pos[0]);
|
|
278
|
-
const ay1 = yScale(pos[1]);
|
|
279
|
-
|
|
280
|
-
const labelWidth = ctx.measureText(label).width;
|
|
281
|
-
const titleWidth = ctx.measureText(title).width;
|
|
282
|
-
const width = Math.max(labelWidth, titleWidth);
|
|
283
|
-
|
|
284
|
-
const bbox = {
|
|
285
|
-
x: ax1,
|
|
286
|
-
y: ay1,
|
|
287
|
-
width,
|
|
288
|
-
height: height * 2 + 4,
|
|
289
|
-
};
|
|
290
|
-
return bbox;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
chooseTopOrBottomPosition(nodes: Callout[], bottom: Callout[], top: Callout[]): void {
|
|
294
|
-
for (let i = nodes.length - 2; i >= 0; --i) {
|
|
295
|
-
const node = nodes[i];
|
|
296
|
-
const prevNode = top[0];
|
|
297
|
-
|
|
298
|
-
const overlap = isOverlapping(node.boundingBox, prevNode.boundingBox);
|
|
299
|
-
if (overlap) {
|
|
300
|
-
node.alignment = node.alignment === Location.topleft ? Location.bottomright : Location.bottomleft;
|
|
301
|
-
bottom.push(node);
|
|
302
|
-
if (i > 0) {
|
|
303
|
-
top.unshift(nodes[--i]);
|
|
304
|
-
}
|
|
305
|
-
} else {
|
|
306
|
-
top.unshift(node);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
adjustTopPositions(top: Callout[]): void {
|
|
312
|
-
for (let i = top.length - 2; i >= 0; --i) {
|
|
313
|
-
const currentNode = top[i];
|
|
314
|
-
for (let j = top.length - 1; j > i; --j) {
|
|
315
|
-
const prevNode = top[j];
|
|
316
|
-
const overlap = getOverlapOffset(currentNode.boundingBox, prevNode.boundingBox);
|
|
317
|
-
if (overlap) {
|
|
318
|
-
currentNode.dy += overlap.dy;
|
|
319
|
-
currentNode.boundingBox.y -= overlap.dy;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
adjustBottomPositions(bottom: Callout[]): void {
|
|
326
|
-
for (let i = bottom.length - 2; i >= 0; --i) {
|
|
327
|
-
const currentNode = bottom[i];
|
|
328
|
-
for (let j = bottom.length - 1; j > i; --j) {
|
|
329
|
-
const prevNode = bottom[j];
|
|
330
|
-
const overlap = getOverlapOffset(prevNode.boundingBox, currentNode.boundingBox);
|
|
331
|
-
if (overlap) {
|
|
332
|
-
currentNode.dy += overlap.dy;
|
|
333
|
-
currentNode.boundingBox.y += overlap.dy;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { Mesh, MeshMaterial, IPoint, Renderer, Texture, WRAP_MODES } from 'pixi.js';
|
|
2
|
-
import { ComplexRopeGeometry } from './ComplexRopeGeometry';
|
|
3
|
-
|
|
4
|
-
export type ComplexRopeSegment = {
|
|
5
|
-
points: IPoint[];
|
|
6
|
-
diameter: number;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* The ComplexRope allows you to draw a texture across several segments of points and then manipulate these points
|
|
11
|
-
*/
|
|
12
|
-
export class ComplexRope extends Mesh {
|
|
13
|
-
/**
|
|
14
|
-
* re-calculate vertices by rope segment-points each frame
|
|
15
|
-
* @member {boolean}
|
|
16
|
-
*/
|
|
17
|
-
public autoUpdate: boolean;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @param texture - The texture to use on the rope.
|
|
21
|
-
* @param segments - An array of segments with points and diaeter to construct this rope.
|
|
22
|
-
* @param {number} textureScale - Optional. Adjust interval of repeated texture
|
|
23
|
-
*/
|
|
24
|
-
constructor(texture: Texture, segments: ComplexRopeSegment[], textureScale = 0) {
|
|
25
|
-
const ropeGeometry = new ComplexRopeGeometry(segments, textureScale);
|
|
26
|
-
const meshMaterial = new MeshMaterial(texture);
|
|
27
|
-
|
|
28
|
-
// attempt to set UV wrapping, will fail on non-power of two textures
|
|
29
|
-
texture.baseTexture.wrapMode = WRAP_MODES.REPEAT;
|
|
30
|
-
|
|
31
|
-
super(ropeGeometry, meshMaterial);
|
|
32
|
-
|
|
33
|
-
this.autoUpdate = true;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
_render(renderer: Renderer): void {
|
|
37
|
-
const geometry: ComplexRopeGeometry = this.geometry as ComplexRopeGeometry;
|
|
38
|
-
|
|
39
|
-
if (this.autoUpdate) {
|
|
40
|
-
geometry.update();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
super._render(renderer);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import { MeshGeometry } from 'pixi.js';
|
|
2
|
-
import { sum, max } from 'd3-array';
|
|
3
|
-
import { ComplexRopeSegment } from './ComplexRope';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* RopeGeometry allows you to draw a geometry across several several segments of points and then manipulate these points.
|
|
7
|
-
*/
|
|
8
|
-
export class ComplexRopeGeometry extends MeshGeometry {
|
|
9
|
-
/** An array of segments with points and diameter that determine the rope. */
|
|
10
|
-
private segments: ComplexRopeSegment[];
|
|
11
|
-
|
|
12
|
-
/** Rope texture scale. */
|
|
13
|
-
private readonly textureScale: number; // TODO unused?
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @param segments - An array of segments with points and diameter to construct this rope.
|
|
17
|
-
* @param textureScale - scaling factor for repeated texture. To create a tiling rope
|
|
18
|
-
* set baseTexture.wrapMode to PIXI.WRAP_MODES.REPEAT and use a power of two texture.
|
|
19
|
-
*/
|
|
20
|
-
constructor(segments: ComplexRopeSegment[], textureScale = 0) {
|
|
21
|
-
const pointCount = sum(segments, (segment) => segment.points.length);
|
|
22
|
-
|
|
23
|
-
// eslint-disable-next-line no-magic-numbers
|
|
24
|
-
super(new Float32Array(pointCount * 4), new Float32Array(pointCount * 4), new Uint16Array((pointCount - 1) * 6));
|
|
25
|
-
|
|
26
|
-
this.segments = segments;
|
|
27
|
-
this.textureScale = textureScale;
|
|
28
|
-
|
|
29
|
-
this.build();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* The max width (i.e., thickness) of the rope.
|
|
34
|
-
* @readonly
|
|
35
|
-
*/
|
|
36
|
-
get width(): number {
|
|
37
|
-
return max(this.segments, (segment) => segment.diameter);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Refreshes Rope indices and uvs */
|
|
41
|
-
private build(): void {
|
|
42
|
-
const segments = this.segments;
|
|
43
|
-
|
|
44
|
-
if (!segments) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const vertexBuffer = this.getBuffer('aVertexPosition');
|
|
49
|
-
const uvBuffer = this.getBuffer('aTextureCoord');
|
|
50
|
-
const indexBuffer = this.getIndex();
|
|
51
|
-
|
|
52
|
-
const pointCount = sum(segments, (segment) => segment.points.length);
|
|
53
|
-
|
|
54
|
-
// if too few points, or texture hasn't got UVs set yet just move on.
|
|
55
|
-
if (pointCount < 1) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// if the number of points has changed we will need to recreate the arraybuffers
|
|
60
|
-
if (vertexBuffer.data.length / 4 !== pointCount) {
|
|
61
|
-
vertexBuffer.data = new Float32Array(pointCount * 4);
|
|
62
|
-
uvBuffer.data = new Float32Array(pointCount * 4);
|
|
63
|
-
indexBuffer.data = new Uint16Array((pointCount - 1) * 6); // eslint-disable-line no-magic-numbers
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const uvs = uvBuffer.data;
|
|
67
|
-
const indices = indexBuffer.data;
|
|
68
|
-
|
|
69
|
-
uvs[0] = 0;
|
|
70
|
-
uvs[1] = 0;
|
|
71
|
-
uvs[2] = 0;
|
|
72
|
-
uvs[3] = 1;
|
|
73
|
-
|
|
74
|
-
const segmentCount = segments.length;
|
|
75
|
-
const maxDiameter = max(segments, (segment) => segment.diameter);
|
|
76
|
-
|
|
77
|
-
let amount = 0;
|
|
78
|
-
let uvIndex = 0;
|
|
79
|
-
let indicesIndex = 0;
|
|
80
|
-
let indexCount = 0;
|
|
81
|
-
|
|
82
|
-
for (let i = 0; i < segmentCount; i++) {
|
|
83
|
-
let prev = segments[i].points[0];
|
|
84
|
-
const textureWidth = maxDiameter;
|
|
85
|
-
const radius = segments[i].diameter / maxDiameter / 2;
|
|
86
|
-
|
|
87
|
-
const total = segments[i].points.length; // - 1;
|
|
88
|
-
|
|
89
|
-
for (let j = 0; j < total; j++) {
|
|
90
|
-
// time to do some smart drawing!
|
|
91
|
-
|
|
92
|
-
// calculate pixel distance from previous point
|
|
93
|
-
const dx = prev.x - segments[i].points[j].x;
|
|
94
|
-
const dy = prev.y - segments[i].points[j].y;
|
|
95
|
-
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
96
|
-
|
|
97
|
-
prev = segments[i].points[j];
|
|
98
|
-
amount += distance / textureWidth;
|
|
99
|
-
|
|
100
|
-
uvs[uvIndex] = amount;
|
|
101
|
-
uvs[uvIndex + 1] = 0.5 - radius;
|
|
102
|
-
|
|
103
|
-
uvs[uvIndex + 2] = amount;
|
|
104
|
-
uvs[uvIndex + 3] = 0.5 + radius;
|
|
105
|
-
uvIndex += 4;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
for (let j = 0; j < total - 1; j++) {
|
|
109
|
-
indices[indexCount++] = indicesIndex;
|
|
110
|
-
indices[indexCount++] = indicesIndex + 1;
|
|
111
|
-
indices[indexCount++] = indicesIndex + 2;
|
|
112
|
-
|
|
113
|
-
indices[indexCount++] = indicesIndex + 2;
|
|
114
|
-
indices[indexCount++] = indicesIndex + 1;
|
|
115
|
-
indices[indexCount++] = indicesIndex + 3;
|
|
116
|
-
indicesIndex += 2;
|
|
117
|
-
}
|
|
118
|
-
indicesIndex += 2;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// ensure that the changes are uploaded
|
|
122
|
-
uvBuffer.update();
|
|
123
|
-
indexBuffer.update();
|
|
124
|
-
|
|
125
|
-
this.updateVertices();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** refreshes vertices of Rope mesh */
|
|
129
|
-
public updateVertices(): void {
|
|
130
|
-
const segments = this.segments;
|
|
131
|
-
const pointCount = sum(segments, (segment) => segment.points.length);
|
|
132
|
-
|
|
133
|
-
if (pointCount < 1) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const segmentCount = segments.length;
|
|
138
|
-
let lastIndex = 0;
|
|
139
|
-
for (let i = 0; i < segmentCount; i++) {
|
|
140
|
-
let lastPoint = segments[i].points[0];
|
|
141
|
-
let nextPoint;
|
|
142
|
-
let perpX = 0;
|
|
143
|
-
let perpY = 0;
|
|
144
|
-
|
|
145
|
-
const vertices = this.buffers[0].data;
|
|
146
|
-
const total = segments[i].points.length;
|
|
147
|
-
let index = 0;
|
|
148
|
-
for (let j = 0; j < total; j++) {
|
|
149
|
-
const point = segments[i].points[j];
|
|
150
|
-
index = lastIndex + j * 4;
|
|
151
|
-
|
|
152
|
-
if (j < segments[i].points.length - 1) {
|
|
153
|
-
nextPoint = segments[i].points[j + 1];
|
|
154
|
-
} else {
|
|
155
|
-
nextPoint = point;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
perpY = -(nextPoint.x - lastPoint.x);
|
|
159
|
-
perpX = nextPoint.y - lastPoint.y;
|
|
160
|
-
|
|
161
|
-
const perpLength = Math.sqrt(perpX * perpX + perpY * perpY);
|
|
162
|
-
const num = segments[i].diameter / 2;
|
|
163
|
-
|
|
164
|
-
perpX /= perpLength;
|
|
165
|
-
perpY /= perpLength;
|
|
166
|
-
|
|
167
|
-
perpX *= num;
|
|
168
|
-
perpY *= num;
|
|
169
|
-
|
|
170
|
-
vertices[index] = point.x + perpX;
|
|
171
|
-
vertices[index + 1] = point.y + perpY;
|
|
172
|
-
vertices[index + 2] = point.x - perpX;
|
|
173
|
-
vertices[index + 3] = point.y - perpY;
|
|
174
|
-
lastPoint = point;
|
|
175
|
-
}
|
|
176
|
-
lastIndex = index + 4;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
this.buffers[0].update();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
public update(): void {
|
|
183
|
-
// TODO: Possible optimiztion to be had here
|
|
184
|
-
// Figure out if/when it is enough to only update verticies with this.updateVertices()
|
|
185
|
-
// See PIXI.SimpleRope.update() for ideas
|
|
186
|
-
|
|
187
|
-
// build() sets indicies and uvs and then calls this.updateVertices()
|
|
188
|
-
this.build();
|
|
189
|
-
}
|
|
190
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { IPoint, Mesh, MeshMaterial, Renderer, RopeGeometry, Texture, WRAP_MODES } from 'pixi.js';
|
|
2
|
-
import { FixedWidthSimpleRopeGeometry } from './FixedWidthSimpleRopeGeometry';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The rope allows you to draw a texture across several points and then manipulate these points
|
|
6
|
-
* Width of rope is given in constructor
|
|
7
|
-
*/
|
|
8
|
-
export class FixedWidthSimpleRope extends Mesh {
|
|
9
|
-
/**
|
|
10
|
-
* re-calculate vertices by rope points each frame
|
|
11
|
-
* @member {boolean}
|
|
12
|
-
*/
|
|
13
|
-
public autoUpdate: boolean;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Note: The wrap mode of the texture is set to REPEAT if `textureScale` is positive.
|
|
17
|
-
* @param texture - The texture to use on the rope. (attempt to set UV wrapping, will fail on non-power of two textures)
|
|
18
|
-
* @param points - An array of {@link PIXI.Point} objects to construct this rope.
|
|
19
|
-
* @param width - Width of rope
|
|
20
|
-
*/
|
|
21
|
-
constructor(texture: Texture, points: IPoint[], width: number) {
|
|
22
|
-
const ropeGeometry = new FixedWidthSimpleRopeGeometry(points, width);
|
|
23
|
-
const meshMaterial = new MeshMaterial(texture);
|
|
24
|
-
|
|
25
|
-
texture.baseTexture.wrapMode = WRAP_MODES.REPEAT;
|
|
26
|
-
|
|
27
|
-
super(ropeGeometry, meshMaterial);
|
|
28
|
-
|
|
29
|
-
this.autoUpdate = true;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
_render(renderer: Renderer): void {
|
|
33
|
-
const geometry: RopeGeometry = this.geometry as RopeGeometry;
|
|
34
|
-
|
|
35
|
-
if (this.autoUpdate) {
|
|
36
|
-
geometry.update();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
super._render(renderer);
|
|
40
|
-
}
|
|
41
|
-
}
|