@pirireis/webglobeplugins 0.15.1-alpha → 0.15.2-3.alpha

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.
Files changed (46) hide show
  1. package/Math/arc.js +1 -2
  2. package/Math/circle-cdf-points.js +1 -170
  3. package/Math/circle.js +0 -25
  4. package/Math/methods.js +2 -2
  5. package/Math/vec3.js +6 -2
  6. package/altitude-locator/plugin.js +1 -1
  7. package/bearing-line/plugin.js +3 -2
  8. package/package.json +1 -1
  9. package/point-tracks/plugin.js +82 -22
  10. package/programs/line-on-globe/lines-color-instanced-flat.js +0 -1
  11. package/programs/line-on-globe/linestrip/linestrip.js +2 -30
  12. package/programs/point-on-globe/element-globe-surface-glow.js +0 -1
  13. package/programs/rings/partial-ring/piece-of-pie.js +55 -89
  14. package/programs/totems/camerauniformblock.js +7 -0
  15. package/programs/totems/canvas-webglobe-info.js +9 -9
  16. package/programs/totems/globe-changes.js +59 -0
  17. package/range-tools-on-terrain/bearing-line/adapters.js +8 -5
  18. package/range-tools-on-terrain/bearing-line/plugin.js +115 -18
  19. package/range-tools-on-terrain/circle-line-chain/adapters.js +15 -8
  20. package/range-tools-on-terrain/circle-line-chain/chain-list-map.js +35 -13
  21. package/range-tools-on-terrain/circle-line-chain/plugin.js +76 -16
  22. package/range-tools-on-terrain/range-ring/adapters.js +74 -6
  23. package/range-tools-on-terrain/range-ring/plugin.js +222 -7
  24. package/range-tools-on-terrain/range-ring/types.js +9 -1
  25. package/semiplugins/interface.js +1 -0
  26. package/semiplugins/lightweight/line-plugin.js +65 -47
  27. package/semiplugins/lightweight/piece-of-pie-plugin.js +50 -25
  28. package/semiplugins/shape-on-terrain/arc-plugin.js +197 -100
  29. package/semiplugins/shape-on-terrain/circle-plugin.js +209 -90
  30. package/semiplugins/shape-on-terrain/padding-1-degree.js +538 -0
  31. package/util/account/single-attribute-buffer-management/buffer-manager.js +10 -0
  32. package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +145 -8
  33. package/util/account/single-attribute-buffer-management/buffer-orchestrator1.js +159 -0
  34. package/util/account/single-attribute-buffer-management/object-store.js +7 -0
  35. package/util/build-strategy/static-dynamic.js +11 -1
  36. package/util/check/typecheck.js +12 -0
  37. package/util/frame-counter-trigger.js +84 -0
  38. package/util/geometry/index.js +2 -1
  39. package/write-text/context-text4.js +140 -0
  40. package/Math/arc-generate-points copy.js +0 -366
  41. package/Math/globe-util/horizon-plane.js +0 -112
  42. package/altitude-locator/draw-subset-obj.js +0 -16
  43. package/programs/line-on-globe/paddings/paddings.js +0 -1
  44. package/programs/rings/partial-ring/piece-of-pie copy.js +0 -286
  45. package/semiplugins/shape-on-terrain/derived/padding-plugin.js +0 -101
  46. package/semiplugins/shape-on-terrain/one-degree-padding.js +0 -85
@@ -19,15 +19,149 @@ export class BufferOrchestrator {
19
19
  this.tombstoneOffsets = [];
20
20
  this._length = 0;
21
21
  }
22
+ // ...existing code...
23
+ // TODO: CLEAN THIS
24
+ // insertBulk2(items: any[], bufferManagersMap: BufferManagersMap, bufferKeys: string[] | null = null) {
25
+ // this.ensureSpace(items.length, bufferManagersMap);
26
+ // const { offsetMap } = this;
27
+ // // For block insert (truly new, consecutive offsets)
28
+ // const blockItems: any[] = [];
29
+ // let blockStart: number | null = null;
30
+ // let lastBlockOffset: number | null = null;
31
+ // // For single insert (existing or tombstone-assigned)
32
+ // const singleItems: any[] = [];
33
+ // const singleOffsets: number[] = [];
34
+ // for (const item of items) {
35
+ // let offset = offsetMap.get(item.key);
36
+ // if (offset !== undefined) {
37
+ // // Already present, update in place
38
+ // singleItems.push(item);
39
+ // singleOffsets.push(offset);
40
+ // } else {
41
+ // // Assign offset (tombstone or new)
42
+ // if (this.tombstoneOffsets.length > 0) {
43
+ // offset = this.tombstoneOffsets.pop() as number;
44
+ // offsetMap.set(item.key, offset);
45
+ // singleItems.push(item);
46
+ // singleOffsets.push(offset);
47
+ // } else {
48
+ // offset = this._length++;
49
+ // if (offset >= this._capacity) throw new Error("The Size Should Be Increased!!");
50
+ // offsetMap.set(item.key, offset);
51
+ // // Check for consecutive block
52
+ // if (blockStart === null) {
53
+ // blockStart = offset;
54
+ // lastBlockOffset = offset;
55
+ // blockItems.push(item);
56
+ // } else if (lastBlockOffset !== null && offset === lastBlockOffset + 1) {
57
+ // lastBlockOffset = offset;
58
+ // blockItems.push(item);
59
+ // } else {
60
+ // // Not consecutive, flush current block
61
+ // if (blockItems.length > 0) {
62
+ // this._insertBlock(blockItems, blockStart, bufferManagersMap, bufferKeys);
63
+ // blockItems.length = 0;
64
+ // }
65
+ // blockStart = offset;
66
+ // lastBlockOffset = offset;
67
+ // blockItems.push(item);
68
+ // }
69
+ // }
70
+ // }
71
+ // }
72
+ // // Flush any remaining block
73
+ // if (blockItems.length > 0 && blockStart !== null) {
74
+ // this._insertBlock(blockItems, blockStart, bufferManagersMap, bufferKeys);
75
+ // }
76
+ // // Insert singles
77
+ // if (singleItems.length > 0) {
78
+ // if (bufferKeys) {
79
+ // for (const key of bufferKeys) {
80
+ // const bufferManagerComp = bufferManagersMap.get(key);
81
+ // if (!bufferManagerComp) throw new Error("insertBulk bufferKey does not exist");
82
+ // const { bufferManager, adaptor } = bufferManagerComp;
83
+ // bufferManager.insertBulk(singleItems.map(adaptor), singleOffsets);
84
+ // }
85
+ // } else {
86
+ // for (const [key, { bufferManager, adaptor }] of bufferManagersMap) {
87
+ // bufferManager.insertBulk(singleItems.map(adaptor), singleOffsets);
88
+ // }
89
+ // }
90
+ // }
91
+ // }
92
+ // // Helper for block insert
93
+ // private _insertBlock(blockItems: any[], blockStart: number, bufferManagersMap: BufferManagersMap, bufferKeys: string[] | null) {
94
+ // if (bufferKeys) {
95
+ // for (const key of bufferKeys) {
96
+ // const bufferManagerComp = bufferManagersMap.get(key);
97
+ // if (!bufferManagerComp) throw new Error("insertBulk bufferKey does not exist");
98
+ // const { bufferManager, adaptor } = bufferManagerComp;
99
+ // bufferManager.insertBlock(blockItems, blockStart, adaptor, Float32Array);
100
+ // }
101
+ // } else {
102
+ // for (const [key, { bufferManager, adaptor }] of bufferManagersMap) {
103
+ // bufferManager.insertBlock(blockItems, blockStart, adaptor, Float32Array);
104
+ // }
105
+ // }
106
+ // }
107
+ // ...existing code...
108
+ // want to add stack load to this method
109
+ // if offsetMap.has(item.key) === false get next offset, add the item to stack
110
+ // create a single big float32array and fill it with the items
111
+ // bufferManager.insertBulk([bigFloat32Array], [offsets[0]])
22
112
  insertBulk(items, bufferManagersMap, bufferKeys = null) {
23
113
  this.ensureSpace(items.length, bufferManagersMap);
24
114
  const { offsetMap } = this;
115
+ let offsetStart = null;
25
116
  const offsets = [];
117
+ const blockLoad = [];
26
118
  for (const item of items) {
27
119
  let o = offsetMap.get(item.key);
28
- const offset = o !== undefined ? o : this.nextOffset();
29
- offsetMap.set(item.key, offset);
30
- offsets.push(offset);
120
+ if (o === undefined && this.tombstoneOffsets.length > 0) {
121
+ // If there is a tombstone, use it
122
+ o = this.tombstoneOffsets.pop();
123
+ offsetMap.set(item.key, o);
124
+ }
125
+ if (o !== undefined) {
126
+ // Already exist or there is a random empty space in earlear part of memory.
127
+ // insert for single slots
128
+ if (bufferKeys) {
129
+ for (const key of bufferKeys) {
130
+ const bufferManagerComp = bufferManagersMap.get(key);
131
+ if (bufferManagerComp === undefined)
132
+ throw new Error("insertBulk bufferKey does not exist");
133
+ const { bufferManager, adaptor } = bufferManagerComp;
134
+ bufferManager.insertBulk([adaptor(item)], [o]);
135
+ }
136
+ }
137
+ else {
138
+ for (const [key, { bufferManager, adaptor }] of bufferManagersMap) {
139
+ bufferManager.insertBulk([adaptor(item)], [o]);
140
+ }
141
+ }
142
+ }
143
+ else {
144
+ // offset comes from increment function
145
+ // this part stacks data to be load a a single big block.
146
+ const offset = this.nextOffset();
147
+ if (offset === undefined) {
148
+ throw new Error("The Size Should Be Increased!!");
149
+ }
150
+ offsets.push(offset);
151
+ offsetMap.set(item.key, offset);
152
+ blockLoad.push(item);
153
+ if (offsetStart === null) {
154
+ offsetStart = offset;
155
+ }
156
+ }
157
+ }
158
+ if (offsetStart === null)
159
+ return;
160
+ for (let i = 0; i < offsets.length - 1; i++) {
161
+ if (offsets[i] - offsets[i + 1] !== -1) {
162
+ // TODO: DELETE THIS
163
+ throw new Error("consecutive is not consecutive");
164
+ }
31
165
  }
32
166
  if (bufferKeys) {
33
167
  for (const key of bufferKeys) {
@@ -35,12 +169,12 @@ export class BufferOrchestrator {
35
169
  if (bufferManagerComp === undefined)
36
170
  throw new Error("insertBulk bufferKey does not exist");
37
171
  const { bufferManager, adaptor } = bufferManagerComp;
38
- bufferManager.insertBulk(items.map(adaptor), offsets);
172
+ bufferManager.insertBlock(blockLoad, offsetStart, adaptor, Float32Array);
39
173
  }
40
174
  }
41
175
  else {
42
176
  for (const [key, { bufferManager, adaptor }] of bufferManagersMap) {
43
- bufferManager.insertBulk(items.map(adaptor), offsets);
177
+ bufferManager.insertBlock(blockLoad, offsetStart, adaptor, Float32Array);
44
178
  }
45
179
  }
46
180
  }
@@ -54,7 +188,7 @@ export class BufferOrchestrator {
54
188
  offsets.push(offset);
55
189
  }
56
190
  else {
57
- throw new Error("updateBulk item Key does not exist");
191
+ throw new Error(`updateBulk item Key does not exist, cannot update: ${item.key}`);
58
192
  }
59
193
  }
60
194
  if (bufferKeys) {
@@ -89,15 +223,18 @@ export class BufferOrchestrator {
89
223
  getOffset(key) {
90
224
  return this.offsetMap.get(key);
91
225
  }
92
- nextOffset() {
226
+ nextTombstone() {
93
227
  if (this.tombstoneOffsets.length > 0) {
94
228
  const offset = this.tombstoneOffsets.pop();
95
229
  return offset;
96
230
  }
231
+ return undefined;
232
+ }
233
+ nextOffset() {
97
234
  if (this._length < this._capacity) {
98
235
  return this._length++;
99
236
  }
100
- return false;
237
+ return undefined;
101
238
  }
102
239
  ensureSpace(itemsLength, bufferManagersMap) {
103
240
  if (itemsLength <= this.emptySpace)
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ // import { BufferOrchestrator as BufferOrchestratorI, BufferManagersMap, BufferManager } from "./types";
3
+ // const EXTRA_SIZE = 10;
4
+ // export class BufferOrchestrator implements BufferOrchestratorI {
5
+ // _capacity: number;
6
+ // offsetMap: Map<string, number>;
7
+ // tombstoneOffsets: number[];
8
+ // _length: number;
9
+ // constructor({ capacity = 10 } = {}) {
10
+ // this._capacity = capacity;
11
+ // this.offsetMap = new Map();
12
+ // this.tombstoneOffsets = [];
13
+ // this._length = 0;
14
+ // }
15
+ // resetWithCapacity(bufferManagersMap: BufferManagersMap, capacity: number | null = null) {
16
+ // this._capacity = capacity !== null ? capacity : this._capacity;
17
+ // for (const [key, { bufferManager }] of bufferManagersMap) {
18
+ // bufferManager.resetWithCapacity(this._capacity);
19
+ // }
20
+ // this.offsetMap.clear();
21
+ // this.tombstoneOffsets = [];
22
+ // this._length = 0;
23
+ // }
24
+ // insertBulk(items: any[], bufferManagersMap: BufferManagersMap, bufferKeys: string[] | null = null) {
25
+ // this.ensureSpace(items.length, bufferManagersMap);
26
+ // const { offsetMap } = this;
27
+ // const offsets = [];
28
+ // for (const item of items) {
29
+ // let o = offsetMap.get(item.key);
30
+ // const offset = o !== undefined ? o : this.nextOffset() as number;
31
+ // if (offset === undefined) {
32
+ // throw new Error("The Size Should Be Increased!!")
33
+ // }
34
+ // offsetMap.set(item.key, offset);
35
+ // offsets.push(offset);
36
+ // }
37
+ // if (bufferKeys) {
38
+ // for (const key of bufferKeys) {
39
+ // const bufferManagerComp = bufferManagersMap.get(key);
40
+ // if (bufferManagerComp === undefined) throw new Error("insertBulk bufferKey does not exist");
41
+ // const { bufferManager, adaptor } = bufferManagerComp;
42
+ // bufferManager.insertBulk(items.map(adaptor), offsets);
43
+ // }
44
+ // } else {
45
+ // for (const [key, { bufferManager, adaptor }] of bufferManagersMap) {
46
+ // bufferManager.insertBulk(items.map(adaptor), offsets);
47
+ // }
48
+ // }
49
+ // }
50
+ // // does not assign offset to the new items.
51
+ // updateBulk(items: any[], bufferManagersMap: BufferManagersMap, bufferKeys: string[] | null = null) {
52
+ // const { offsetMap } = this;
53
+ // const offsets = [];
54
+ // for (const item of items) {
55
+ // const offset = offsetMap.get(item.key);
56
+ // if (offset !== undefined) {
57
+ // offsets.push(offset);
58
+ // } else {
59
+ // throw new Error("updateBulk item Key does not exist");
60
+ // }
61
+ // }
62
+ // if (bufferKeys) {
63
+ // for (const key of bufferKeys) {
64
+ // const bufferManagerComp = bufferManagersMap.get(key);
65
+ // if (bufferManagerComp === undefined) throw new Error("updateBulk bufferKey does not exist");
66
+ // const { bufferManager, adaptor } = bufferManagerComp;
67
+ // bufferManager.insertBulk(items.map(adaptor), offsets);
68
+ // }
69
+ // } else {
70
+ // for (const [key, { bufferManager, adaptor }] of bufferManagersMap) {
71
+ // bufferManager.insertBulk(items.map(adaptor), offsets);
72
+ // }
73
+ // }
74
+ // }
75
+ // deleteBulk(keys: string[], bufferManagersMap: BufferManagersMap) {
76
+ // const offsets = [];
77
+ // for (const key of keys) {
78
+ // const offset = this.getOffset(key);
79
+ // if (offset !== undefined) {
80
+ // offsets.push(offset);
81
+ // this.offsetMap.delete(key);
82
+ // this.tombstoneOffsets.push(offset);
83
+ // }
84
+ // }
85
+ // for (const [key, { bufferManager }] of bufferManagersMap) {
86
+ // bufferManager.deleteBulk(offsets);
87
+ // }
88
+ // }
89
+ // getOffset(key: string) {
90
+ // return this.offsetMap.get(key);
91
+ // }
92
+ // nextOffset(): number | undefined {
93
+ // if (this.tombstoneOffsets.length > 0) {
94
+ // const offset = this.tombstoneOffsets.pop() as number;
95
+ // return offset;
96
+ // }
97
+ // if (this._length < this._capacity) {
98
+ // return this._length++;
99
+ // }
100
+ // return undefined;
101
+ // }
102
+ // ensureSpace(itemsLength: number, bufferManagersMap: BufferManagersMap) {
103
+ // if (itemsLength <= this.emptySpace) return;
104
+ // const newCapacity = this.length + itemsLength;
105
+ // for (const [key, { bufferManager }] of bufferManagersMap) {
106
+ // bufferManager.extendBuffer(this.length, newCapacity);
107
+ // }
108
+ // this._capacity = newCapacity;
109
+ // }
110
+ // defrag(bufferManagers: BufferManagersMap, bufferKeys: string[]) { // TODO defrag and leave some empty space
111
+ // const offsetMap = this.offsetMap;
112
+ // const newCapacity = offsetMap.size + EXTRA_SIZE;
113
+ // if (bufferKeys) {
114
+ // for (const key of bufferKeys) {
115
+ // const offset = offsetMap.get(key);
116
+ // if (offset !== undefined) {
117
+ // for (const [key, { bufferManager }] of bufferManagers) {
118
+ // bufferManager.defrag([offset], this.length, newCapacity);
119
+ // }
120
+ // }
121
+ // }
122
+ // } else {
123
+ // for (const [key, { bufferManager }] of bufferManagers) {
124
+ // bufferManager.defrag(offsetMap.values(), this.length, newCapacity);
125
+ // }
126
+ // }
127
+ // this._defrag();
128
+ // this._length = offsetMap.size;
129
+ // this._capacity = newCapacity;
130
+ // this.tombstoneOffsets = [];
131
+ // }
132
+ // /**
133
+ // * Flushes metadata and sets length to 0 without actualize change on buffers
134
+ // * This method created for cases in which data is loaded on each frame
135
+ // */
136
+ // flush({ capacity = 10 } = {}) {
137
+ // this._length = 0;
138
+ // this._capacity = capacity;
139
+ // this.tombstoneOffsets = []
140
+ // this.offsetMap.clear();
141
+ // }
142
+ // _defrag() {
143
+ // const newOffsetMap = new Map();
144
+ // let newOffset = 0;
145
+ // for (const [key, offset] of this.offsetMap) {
146
+ // newOffsetMap.set(key, newOffset++);
147
+ // }
148
+ // this.offsetMap = newOffsetMap
149
+ // }
150
+ // get length() {
151
+ // return this._length;
152
+ // }
153
+ // get emptySpace() {
154
+ // return this._capacity - this.offsetMap.size;
155
+ // }
156
+ // get capacity() {
157
+ // return this._capacity;
158
+ // }
159
+ // }
@@ -23,6 +23,13 @@ export class ObjectStore {
23
23
  }
24
24
  }
25
25
  }
26
+ insertBlock(objects, startOffset) {
27
+ for (let i = 0; i < objects.length; i++) {
28
+ const object = objects[i];
29
+ const offset = startOffset + i;
30
+ this._container[offset] = object;
31
+ }
32
+ }
26
33
  defrag(offsetValues, occupiedCapacity, newCapacity) {
27
34
  const hold = this._createEmptyList(newCapacity);
28
35
  for (let i = 0; i < offsetValues.length; i++) {
@@ -9,21 +9,31 @@ export class StaticDynamicStrategy {
9
9
  _staticDynamicState = StaticDynamicState.DYNAMIC;
10
10
  _transitionLevel = 8; // Default transition level
11
11
  _lastStaticDynamicState = StaticDynamicState.STATIC;
12
- constructor(globe, transitionLevel = 8) {
12
+ _lastGeometry = null;
13
+ _toStatic;
14
+ constructor(globe, transitionLevel = 8, toStatic) {
13
15
  this.globe = globe;
14
16
  this._transitionLevel = transitionLevel;
17
+ this._toStatic = toStatic;
15
18
  this.updateState();
16
19
  }
17
20
  updateState() {
18
21
  const currentLOD = this.globe.api_GetCurrentLODWithDecimal();
19
22
  const state = currentLOD < this._transitionLevel ? StaticDynamicState.STATIC : StaticDynamicState.DYNAMIC;
23
+ const currentGeometry = this.globe.api_GetCurrentGeometry();
20
24
  if (this._lastStaticDynamicState === StaticDynamicState.DYNAMIC && state === StaticDynamicState.STATIC) {
21
25
  this._staticDynamicState = StaticDynamicState.TO_STATIC;
26
+ this._toStatic();
27
+ }
28
+ else if ((currentGeometry !== this._lastGeometry) && state === StaticDynamicState.STATIC) {
29
+ this._staticDynamicState = StaticDynamicState.TO_STATIC;
30
+ this._toStatic();
22
31
  }
23
32
  else {
24
33
  this._staticDynamicState = state;
25
34
  }
26
35
  this._lastStaticDynamicState = this._staticDynamicState;
36
+ this._lastGeometry = currentGeometry;
27
37
  }
28
38
  getState() {
29
39
  return this._staticDynamicState;
@@ -9,6 +9,18 @@ const doesOwnProperties = (properties, errorMessage) => {
9
9
  };
10
10
  export const isHexColor = (hexColor) => /^#[0-9A-F]{6}$/i.test(hexColor);
11
11
  export const isHexColorWithOpacity = (hexColor) => /^#[0-9A-F]{6}[0-9a-f]{0,2}$/i.test(hexColor);
12
+ export const colorCheck = (color) => {
13
+ if (Array.isArray(color)) {
14
+ if (color.length !== 4)
15
+ throw new TypeError("Color must be an array 4 numbers RGBA");
16
+ color.forEach(c => {
17
+ if (typeof c !== "number")
18
+ throw new TypeError("Color array must contain only numbers");
19
+ if (c < 0 || c > 1)
20
+ throw new RangeError("Color values must be between 0 and 1");
21
+ });
22
+ }
23
+ };
12
24
  export const opacityCheck = (opacity) => {
13
25
  if (typeof opacity !== "number")
14
26
  throw new TypeError("style.opacity must a number");
@@ -0,0 +1,84 @@
1
+ import { CameraUniformBlockTotemCache } from "../programs/totems/camerauniformblock";
2
+ export class FrameCounterTrigger {
3
+ globe;
4
+ count = 0;
5
+ threshold;
6
+ timeoutMs;
7
+ timeoutId = null;
8
+ accumulatedChanges = {
9
+ geometry: false,
10
+ look: false,
11
+ lod: false,
12
+ lod2DWheel: false,
13
+ elevationScale: false,
14
+ screenMoved: false
15
+ };
16
+ cameraBlockTotem;
17
+ updateCallback;
18
+ constructor(globe, threshold, timeoutMs, updateCallback) {
19
+ this.threshold = threshold;
20
+ this.timeoutMs = timeoutMs;
21
+ this.updateCallback = updateCallback;
22
+ this.globe = globe;
23
+ this.cameraBlockTotem = CameraUniformBlockTotemCache.get(globe);
24
+ }
25
+ trigger(level = null) {
26
+ const globeChanges = this.cameraBlockTotem.getGlobeChanges();
27
+ if (!globeChanges.screenMoved)
28
+ return;
29
+ this.setChanges(globeChanges);
30
+ if (globeChanges.geometry || globeChanges.elevationScale || globeChanges.lod2DWheel) {
31
+ this.triggerUpdate();
32
+ return;
33
+ }
34
+ this.count++;
35
+ if (this.count === 1) {
36
+ this.startTimeout();
37
+ }
38
+ if (this.count >= this.threshold) {
39
+ this.triggerUpdate();
40
+ }
41
+ }
42
+ startTimeout() {
43
+ this.clearTimeout();
44
+ this.timeoutId = setTimeout(() => {
45
+ this.triggerUpdate();
46
+ }, this.timeoutMs);
47
+ }
48
+ triggerUpdate() {
49
+ this.clearTimeout();
50
+ this.updateCallback(this.accumulatedChanges);
51
+ this.reset();
52
+ }
53
+ clearTimeout() {
54
+ if (this.timeoutId) {
55
+ clearTimeout(this.timeoutId);
56
+ this.timeoutId = null;
57
+ }
58
+ }
59
+ setChanges(changes) {
60
+ // accumulate true states until reset
61
+ this.accumulatedChanges.geometry = this.accumulatedChanges.geometry || changes.geometry;
62
+ this.accumulatedChanges.look = this.accumulatedChanges.look || changes.look;
63
+ this.accumulatedChanges.lod = this.accumulatedChanges.lod || changes.lod;
64
+ this.accumulatedChanges.elevationScale = this.accumulatedChanges.elevationScale || changes.elevationScale;
65
+ this.accumulatedChanges.screenMoved = this.accumulatedChanges.screenMoved || changes.screenMoved;
66
+ this.accumulatedChanges.lod2DWheel = this.accumulatedChanges.lod2DWheel || changes.lod2DWheel;
67
+ }
68
+ getLevel() {
69
+ return this.accumulatedChanges;
70
+ }
71
+ reset() {
72
+ this.count = 0;
73
+ this.accumulatedChanges.geometry = false;
74
+ this.accumulatedChanges.look = false;
75
+ this.accumulatedChanges.lod = false;
76
+ this.accumulatedChanges.lod2DWheel = false;
77
+ this.accumulatedChanges.elevationScale = false;
78
+ this.accumulatedChanges.screenMoved = false;
79
+ this.clearTimeout();
80
+ }
81
+ free() {
82
+ CameraUniformBlockTotemCache.release(this.globe);
83
+ }
84
+ }
@@ -40,7 +40,8 @@ function normalize(array, newLength = 1) {
40
40
  }
41
41
  return result;
42
42
  }
43
+ // TODO carry the usefull content to math module.
43
44
  function sphereCoord(long, lat, globe, height = 0) {
44
- return normalize(globe.api_GetCartesian3DPoint(long, lat, 0, 0), 6378.137 + height);
45
+ return normalize(globe.api_GetCartesian3DPoint(long, lat, 0, false), 6378.137 + height);
45
46
  }
46
47
  export { createBBoxMatrix, latLongToPixelXY, latLongBboxtoPixelXYBbox, sphereCoord, normalize };
@@ -0,0 +1,140 @@
1
+ // @ts-ignore
2
+ import { CSZMode } from "@pirireis/webglobe";
3
+ import { isTextFont, opacityCheck } from "../util/check/typecheck";
4
+ /**
5
+ * TODOs:
6
+ * 1) update all if initials change (propably need a context and a callback to iterate over zPayload)
7
+ * 2) expose a mechanic to update text on zoom change
8
+ * 3) extend the mechanic on 2 to other events
9
+ *
10
+ * TODO: key check and raise error if doesnt exist
11
+ */
12
+ const defaultStyle = {
13
+ textFont: {
14
+ name: 'Arial',
15
+ textColor: '#FFFFFF', // beyaz
16
+ hollowColor: '#000000', // siyah
17
+ size: 12, // piksel
18
+ hollow: true,
19
+ bold: true,
20
+ italic: false,
21
+ },
22
+ opacity: 1.0,
23
+ zMode: CSZMode.Z_GROUND_PERVERTEX,
24
+ };
25
+ // xOffset = 0,
26
+ // yOffset = 0,
27
+ // doDraw = true,
28
+ // textAdaptor = null,
29
+ // coordinatesAdaptor = null,
30
+ // keyAdaptor = null,
31
+ // opacityAdaptor = null,
32
+ // angleAdaptor = null,
33
+ // angleOnSphere = false,
34
+ // positionAdaptor = (item: any, i: number, container: any[], properties?: any): string => "left",
35
+ export class ContextTextWriter4 {
36
+ globe;
37
+ itemMap;
38
+ style;
39
+ doDraw;
40
+ textAdaptor;
41
+ deleteAdaptor;
42
+ zoomLevelAdaptor;
43
+ xOffset;
44
+ yOffset;
45
+ angleOptions;
46
+ constructor(globe, textAdaptor, deleteAdaptor, zoomLevelAdaptor = (zoomLevel) => (item) => {
47
+ return {
48
+ opacityMultiplier: 1,
49
+ sizeMultiplier: 1
50
+ };
51
+ }, style = defaultStyle, angleOptions = {
52
+ angleOnSphere: false,
53
+ angleIsOn: false
54
+ }, doDraw = true, offset = { x: 0, y: 0 }) {
55
+ this.globe = globe;
56
+ this.itemMap = new Map();
57
+ this.setStyle(style);
58
+ this.angleOptions = angleOptions;
59
+ this.doDraw = doDraw;
60
+ this.style = style;
61
+ this.angleOptions = angleOptions;
62
+ this.textAdaptor = textAdaptor;
63
+ this.deleteAdaptor = deleteAdaptor;
64
+ this.zoomLevelAdaptor = zoomLevelAdaptor;
65
+ this.xOffset = offset.x;
66
+ this.yOffset = offset.y;
67
+ }
68
+ setDoDraw(bool) {
69
+ this.doDraw = bool;
70
+ this.globe.DrawRender();
71
+ }
72
+ setStyle(style) {
73
+ isTextFont(style.textFont);
74
+ opacityCheck(style.opacity); //TODO: use shallow copy
75
+ this.style = style;
76
+ this.globe.DrawRender();
77
+ }
78
+ setOpacity(opacity) {
79
+ this.style.opacity = opacity;
80
+ this.globe.DrawRender();
81
+ }
82
+ draw() {
83
+ if (!this.doDraw)
84
+ return;
85
+ const { globe, style, itemMap, xOffset, yOffset } = this;
86
+ const { textFont, opacity: opacity_ } = style;
87
+ const textSize = textFont.size;
88
+ const is3D = globe.api_GetCurrentGeometry() === 0;
89
+ const angleIsOn = is3D ? (this.angleOptions.angleIsOn && this.angleOptions.angleOnSphere) : (this.angleOptions.angleIsOn);
90
+ const zoomLevel = globe.api_GetCurrentLODWithDecimal();
91
+ const zoomAdaptor = this.zoomLevelAdaptor(zoomLevel);
92
+ for (const item of itemMap.values()) {
93
+ const { lat, long, text, opacity = null, angle = null, zPayload, position } = item;
94
+ const { x, y } = globe.api_GetScreenPointFromGeo({
95
+ long: long,
96
+ lat: lat,
97
+ z: 0,
98
+ }, style.zMode === CSZMode.Z_MSL);
99
+ const { opacityMultiplier, sizeMultiplier } = zoomAdaptor(zPayload);
100
+ const o = (opacity === null ? opacity_ : opacity * opacity_) * opacityMultiplier;
101
+ textFont.size = sizeMultiplier * textSize;
102
+ textFont.position = position;
103
+ if (x !== null && y !== null)
104
+ globe.api_DrawContextTextMultiLine(text, textFont, o, { x: x + xOffset, y: y - yOffset }, angleIsOn, angle);
105
+ }
106
+ textFont.size = textSize;
107
+ }
108
+ insertText(data) {
109
+ const textDatas = this.textAdaptor(data);
110
+ for (const textData of textDatas) {
111
+ this.itemMap.set(textData.key, textData);
112
+ }
113
+ }
114
+ insertTextBulk(datas) {
115
+ for (const data of datas) {
116
+ this.insertText(data);
117
+ }
118
+ }
119
+ deleteText(data) {
120
+ const key = this.deleteAdaptor ? this.deleteAdaptor(data) : data;
121
+ if (this.itemMap.has(key)) {
122
+ this.itemMap.delete(key);
123
+ }
124
+ }
125
+ deleteTextBulk(datas) {
126
+ for (const data of datas) {
127
+ this.deleteText(data);
128
+ }
129
+ }
130
+ setOffsets(x, y) {
131
+ this.xOffset = x;
132
+ this.yOffset = y;
133
+ }
134
+ clear() {
135
+ this.itemMap.clear();
136
+ }
137
+ free() {
138
+ this.itemMap = null;
139
+ }
140
+ }