webglmusti 0.0.0

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 (102) hide show
  1. package/.gitattributes +2 -0
  2. package/idea_list.txt +13 -0
  3. package/index.html +17 -0
  4. package/package.json +20 -0
  5. package/public/apple.png +0 -0
  6. package/public/base.png +0 -0
  7. package/public/car.png +0 -0
  8. package/public/drop.png +0 -0
  9. package/public/font16-Sheet.png +0 -0
  10. package/public/font16-Sheet.txt +52 -0
  11. package/public/letters-Sheet.png +0 -0
  12. package/public/letters-Sheet.txt +27 -0
  13. package/public/letters_Sheet.png +0 -0
  14. package/public/letters_Sheet.txt +4 -0
  15. package/public/vite.svg +1 -0
  16. package/src/App/ResourceSim/car.ts +172 -0
  17. package/src/App/ResourceSim/grid.ts +993 -0
  18. package/src/App/ResourceSim/grid_app.ts +1326 -0
  19. package/src/App/ResourceSim/grid_test.test.ts +18 -0
  20. package/src/App/ResourceSim/node_graph.ts +293 -0
  21. package/src/App/ResourceSim/nodes.ts +151 -0
  22. package/src/App/ResourceSim/resource.ts +8 -0
  23. package/src/App/ResourceSim/texts.ts +6 -0
  24. package/src/App/card/card.test.ts +22 -0
  25. package/src/App/card/card.ts +763 -0
  26. package/src/App/puzzle_box/app.ts +10 -0
  27. package/src/App/puzzle_box/engine.ts +374 -0
  28. package/src/App/puzzle_box/renderer.ts +102 -0
  29. package/src/App/puzzle_box/test.test.ts +49 -0
  30. package/src/App/water/water.ts +206 -0
  31. package/src/Interface/button.ts +345 -0
  32. package/src/Interface/interface_element.ts +30 -0
  33. package/src/Interface/internal_window.ts +100 -0
  34. package/src/Interface/options.ts +332 -0
  35. package/src/Interface/text_input.ts +183 -0
  36. package/src/WebGL/Matrix/matrix.test.ts +30 -0
  37. package/src/WebGL/Matrix/matrix.ts +293 -0
  38. package/src/WebGL/Shaders/Fragment/Program/circle.ts +49 -0
  39. package/src/WebGL/Shaders/Fragment/Program/circle_only.ts +47 -0
  40. package/src/WebGL/Shaders/Fragment/Program/circle_outline.ts +54 -0
  41. package/src/WebGL/Shaders/Fragment/Program/colour.ts +39 -0
  42. package/src/WebGL/Shaders/Fragment/Program/colour_alpha.ts +37 -0
  43. package/src/WebGL/Shaders/Fragment/Program/line.ts +39 -0
  44. package/src/WebGL/Shaders/Fragment/Program/multi_colour_centre_circle_path.ts +69 -0
  45. package/src/WebGL/Shaders/Fragment/Program/multi_colour_path.ts +69 -0
  46. package/src/WebGL/Shaders/Fragment/Program/path_centre_circle.ts +69 -0
  47. package/src/WebGL/Shaders/Fragment/Program/rect_outline.ts +39 -0
  48. package/src/WebGL/Shaders/Fragment/Program/solid_path.ts +64 -0
  49. package/src/WebGL/Shaders/Fragment/Program/sprite_sheet.ts +54 -0
  50. package/src/WebGL/Shaders/Fragment/Program/sprite_sheet_colour.ts +62 -0
  51. package/src/WebGL/Shaders/Fragment/Program/texture.ts +34 -0
  52. package/src/WebGL/Shaders/Fragment/Source/circle.frag +19 -0
  53. package/src/WebGL/Shaders/Fragment/Source/circle_only.frag +15 -0
  54. package/src/WebGL/Shaders/Fragment/Source/circle_outline.frag +23 -0
  55. package/src/WebGL/Shaders/Fragment/Source/colour.frag +9 -0
  56. package/src/WebGL/Shaders/Fragment/Source/colour_alpha.frag +7 -0
  57. package/src/WebGL/Shaders/Fragment/Source/fragment.frag +5 -0
  58. package/src/WebGL/Shaders/Fragment/Source/fragment_source.ts +15 -0
  59. package/src/WebGL/Shaders/Fragment/Source/line.frag +12 -0
  60. package/src/WebGL/Shaders/Fragment/Source/multi_colour_centre_circle_path.frag +36 -0
  61. package/src/WebGL/Shaders/Fragment/Source/multi_colour_path.frag +34 -0
  62. package/src/WebGL/Shaders/Fragment/Source/path_centre_circle.frag +29 -0
  63. package/src/WebGL/Shaders/Fragment/Source/rect_outline.frag +20 -0
  64. package/src/WebGL/Shaders/Fragment/Source/solid_path.frag +24 -0
  65. package/src/WebGL/Shaders/Fragment/Source/sprite_sheet.frag +17 -0
  66. package/src/WebGL/Shaders/Fragment/Source/sprite_sheet_colour.frag +19 -0
  67. package/src/WebGL/Shaders/Fragment/Source/texture.frag +11 -0
  68. package/src/WebGL/Shaders/Fragment/fragment.ts +43 -0
  69. package/src/WebGL/Shaders/Fragment/fragment_old.ts +261 -0
  70. package/src/WebGL/Shaders/Vertex/Program/mvp2d.ts +41 -0
  71. package/src/WebGL/Shaders/Vertex/Program/transform2d.ts +39 -0
  72. package/src/WebGL/Shaders/Vertex/Source/mvp2d.vert +17 -0
  73. package/src/WebGL/Shaders/Vertex/Source/mvp_i_2d.vert +18 -0
  74. package/src/WebGL/Shaders/Vertex/Source/simple.vert +9 -0
  75. package/src/WebGL/Shaders/Vertex/Source/transform2d.vert +13 -0
  76. package/src/WebGL/Shaders/Vertex/Source/transform2d_rel.vert +16 -0
  77. package/src/WebGL/Shaders/Vertex/Source/translate2d.vert +7 -0
  78. package/src/WebGL/Shaders/Vertex/Source/vertex_source.ts +13 -0
  79. package/src/WebGL/Shaders/Vertex/vertex.ts +10 -0
  80. package/src/WebGL/Shaders/Vertex/vertex_old.ts +289 -0
  81. package/src/WebGL/Shaders/custom.ts +129 -0
  82. package/src/WebGL/Shaders/shader.ts +197 -0
  83. package/src/WebGL/Shapes/Line.ts +29 -0
  84. package/src/WebGL/Shapes/Shapes.ts +189 -0
  85. package/src/WebGL/Texture/texture.ts +214 -0
  86. package/src/WebGL/Util/file.ts +24 -0
  87. package/src/WebGL/app.ts +150 -0
  88. package/src/WebGL/colour.ts +71 -0
  89. package/src/WebGL/globals.ts +353 -0
  90. package/src/WebGL/index.ts +3 -0
  91. package/src/WebGL/mixin.ts +2 -0
  92. package/src/global.d.ts +13 -0
  93. package/src/index.ts +4 -0
  94. package/src/main.ts +139 -0
  95. package/src/utils/array.ts +154 -0
  96. package/src/utils/assert.ts +8 -0
  97. package/src/utils/file.ts +0 -0
  98. package/src/utils/mixin.ts +22 -0
  99. package/src/utils/numbers.ts +11 -0
  100. package/src/utils/utils.test.ts +23 -0
  101. package/src/vite-env.d.ts +1 -0
  102. package/tsconfig.json +25 -0
@@ -0,0 +1,332 @@
1
+
2
+ import * as WebGL from "./../WebGL/globals";
3
+ import * as ArrayUtils from "./../utils/array";
4
+ import * as InterfaceElement from "./interface_element";
5
+
6
+ type Int32 = number;
7
+
8
+
9
+
10
+ export class SingleSelectOptions{
11
+ selected: Int32;
12
+ options: string[];
13
+ x: Int32;
14
+ y: Int32;
15
+ width: Int32;
16
+ height: Int32;
17
+ text_size: Int32;
18
+ padding: Int32;
19
+
20
+ background_colour: WebGL.Colour.ColourRGB;
21
+ text_colour: WebGL.Colour.ColourRGB;
22
+ selected_colour: WebGL.Colour.ColourRGB;
23
+
24
+ hover_colour: WebGL.Colour.ColourRGB;
25
+
26
+ mouse_over_option: Int32 | undefined;
27
+
28
+ onSelected: (id: Int32, opt: string) => void;
29
+
30
+ private dividers: Int32[];
31
+ constructor(options: string[], x: Int32, y: Int32, height: Int32){
32
+ this.selected = 0;
33
+ this.x = x;
34
+ this.y = y;
35
+ //this.width = 40;
36
+ this.height = height;
37
+ this.text_size = 10;
38
+ this.padding = 3;
39
+
40
+ this.options = options;
41
+
42
+ const n_chars = this.options.reduce((pv, cv) => {
43
+ return pv + cv.length;
44
+ }, 0);
45
+
46
+ this.width = (this.text_size*n_chars)+(this.padding*(this.options.length+1));
47
+ this.dividers = this.generateDividers(this.options, this.text_size);
48
+
49
+ this.background_colour = WebGL.Colour.ColourUtils.white();
50
+ this.text_colour = WebGL.Colour.ColourUtils.black();
51
+ this.selected_colour = WebGL.Colour.ColourUtils.pink();
52
+ this.hover_colour = WebGL.Colour.ColourUtils.grey();
53
+
54
+ this.mouse_over_option = undefined;
55
+
56
+ this.onSelected = () => {};
57
+ }
58
+ generateDividers(opts: string[], ts: Int32): Int32[]{
59
+ const divs: Int32[] = [];
60
+ let curr = 0;
61
+ for(const s of opts){
62
+ divs.push(curr);
63
+ curr += s.length*ts + this.padding;
64
+ }
65
+ return divs;
66
+ }
67
+
68
+ isInside(point: WebGL.Matrix.Point2D): boolean{
69
+ return this.x < point.x && point.x < this.x + this.width && this.y < point.y && point.y < this.y+this.height;
70
+ }
71
+
72
+ onMouseDown(){
73
+ if(this.mouse_over_option != undefined){
74
+ this.selected = this.mouse_over_option;
75
+ this.onSelected(this.selected, this.options[this.selected]);
76
+ }
77
+ }
78
+ onMouseUp(){
79
+
80
+ }
81
+
82
+ onMouseMove(point: WebGL.Matrix.Point2D){
83
+ if(this.isInside(point)){
84
+ const x = point.x - this.x;
85
+ // calculates dividors with padding on left (i.e. furtherest dividing line left)
86
+ this.mouse_over_option = ArrayUtils.binarySearchLowerBound(this.dividers, (t) => x-t);
87
+ }else{
88
+ this.mouse_over_option = undefined;
89
+ }
90
+ }
91
+
92
+ draw(vp: WebGL.Matrix.TransformationMatrix3x3, colour_shader: WebGL.Shader.MVPColourProgram, text_drawer: WebGL.TextDrawer){
93
+ if(this.options.length == 0) return;
94
+ const n_chars = this.options.reduce((pv, cv) => {
95
+ return pv + cv.length;
96
+ }, 0);
97
+ const padding = this.padding;
98
+ const width = (this.width);
99
+
100
+ //background
101
+ colour_shader.use();
102
+ colour_shader.setColourFromColourRGB(this.background_colour);
103
+ const background_model = WebGL.WebGL.rectangleModel(this.x, this.y, width, this.height);
104
+ colour_shader.setMvp(vp.multiplyCopy(background_model));
105
+ WebGL.Shapes.Quad.draw();
106
+
107
+ //mouse over
108
+ if(this.mouse_over_option != undefined){
109
+ colour_shader.setColourFromColourRGB(this.hover_colour);
110
+ const opt_width = text_drawer.getTextWidth(this.options[this.mouse_over_option], this.text_size)+padding;
111
+ const mouse_over_model = WebGL.WebGL.rectangleModel(this.x+this.dividers[this.mouse_over_option], this.y, opt_width, this.height);
112
+ colour_shader.setMvp(vp.multiplyCopy(mouse_over_model));
113
+ WebGL.Shapes.Quad.draw();
114
+ }
115
+
116
+ //selected
117
+ colour_shader.setColourFromColourRGB(this.selected_colour);
118
+ const opt_width = text_drawer.getTextWidth(this.options[this.selected], this.text_size)+padding;
119
+ const selected_model = WebGL.WebGL.rectangleModel(this.x+this.dividers[this.selected], this.y, opt_width, this.height);
120
+ colour_shader.setMvp(vp.multiplyCopy(selected_model));
121
+ WebGL.Shapes.Quad.draw();
122
+
123
+ let offset = this.x+this.padding;
124
+ const text_y = this.y+(this.height-this.text_size)*0.5;
125
+ const border_thickness = 3;
126
+ for(const str of this.options){
127
+ //draw text
128
+ const text_width = text_drawer.getTextWidth(str, this.text_size);
129
+ text_drawer.drawTextColour(vp, offset, text_y, str, this.text_size, this.text_colour);
130
+
131
+ //draw divider lines
132
+
133
+ const line_model = WebGL.WebGL.rectangleModel(offset-this.padding, this.y, border_thickness, this.height);
134
+ colour_shader.use();
135
+ colour_shader.setColourFromColourRGB(this.text_colour);
136
+ colour_shader.setMvp(vp.multiplyCopy(line_model));
137
+ WebGL.Shapes.Quad.draw();
138
+
139
+ offset += this.padding+text_width;
140
+ }
141
+ //last line
142
+ const line_model = WebGL.WebGL.rectangleModel(offset-this.padding, this.y, border_thickness, this.height);
143
+ colour_shader.use();
144
+ colour_shader.setColourFromColourRGB(this.text_colour);
145
+ colour_shader.setMvp(vp.multiplyCopy(line_model));
146
+ WebGL.Shapes.Quad.draw();
147
+
148
+ //top and bottom
149
+ const top_model = WebGL.WebGL.rectangleModel(this.x, this.y, this.width, border_thickness);
150
+ colour_shader.setMvp(vp.multiplyCopy(top_model));
151
+ WebGL.Shapes.Quad.draw();
152
+
153
+ const bot_model = WebGL.WebGL.rectangleModel(this.x, this.y+this.height, this.width, border_thickness);
154
+ colour_shader.setMvp(vp.multiplyCopy(bot_model));
155
+ WebGL.Shapes.Quad.draw();
156
+ }
157
+ }
158
+
159
+ const DropdownStateEnum = {
160
+ Closed: 0,
161
+ ClosedHover: 1,
162
+ Open: 2,
163
+ OpenHover: 3
164
+ } as const;
165
+
166
+ type DropdownState = (typeof DropdownStateEnum)[keyof typeof DropdownStateEnum];
167
+
168
+ export class DropdownOptions extends InterfaceElement.InterfaceElement{
169
+ static no_option_text = "-No Options-";
170
+ options: string[];
171
+ selected: Int32;
172
+ position_hovered: Int32; // the index of mouse over the interface from top, e.g. 0 is always selected
173
+ state: DropdownState;
174
+
175
+ background_colour: WebGL.Colour.ColourRGB;
176
+ hovered_background_colour: WebGL.Colour.ColourRGB;
177
+ text_colour: WebGL.Colour.ColourRGB;
178
+ border_colour: WebGL.Colour.ColourRGB;
179
+ text_size: Int32;
180
+
181
+ border_width: Int32;
182
+
183
+ onSelect: (id: Int32) => void;
184
+
185
+ constructor(x: Int32, y: Int32, width: Int32, height: Int32, options: string[]=[]){
186
+ super(x, y, width, height);
187
+ this.selected = 0;
188
+ this.position_hovered = -1;
189
+ this.options = options;
190
+ this.state = DropdownStateEnum.Closed;
191
+ this.background_colour = WebGL.Colour.ColourUtils.white();
192
+ this.hovered_background_colour = WebGL.Colour.ColourUtils.grey();
193
+ this.text_colour = WebGL.Colour.ColourUtils.black();
194
+ this.border_colour = WebGL.Colour.ColourUtils.blue();
195
+ this.text_size = this.height-4;
196
+
197
+ this.border_width = 2;
198
+ this.onSelect = () => {};
199
+ }
200
+ hasOptions(): boolean{
201
+ return this.options.length > 0;
202
+ }
203
+ openHeight(): Int32{
204
+ return this.height*this.options.length;
205
+ }
206
+ isInside(point: WebGL.Matrix.Point2D){
207
+ if(this.isOpen()){
208
+ return this.isInsideOpened(point);
209
+ }
210
+ return super.isInside(point);
211
+ }
212
+ isInsideOpened(point: WebGL.Matrix.Point2D): boolean{
213
+ const in_x = this.x < point.x && point.x < this.x+this.width;
214
+ const in_y = this.y < point.y && point.y < this.y+this.openHeight();
215
+ return in_x && in_y;
216
+ }
217
+ getPositionIndexFromY(y: Int32): Int32{
218
+ return Math.floor((y-this.y) / this.height);
219
+ }
220
+ // 0 is selected, otherwise a position in order from selected
221
+ getOptionIndexFromY(y: Int32): Int32{
222
+ return this.optionIndexFromSelectedIndex(this.getPositionIndexFromY(y));
223
+ }
224
+ optionIndexFromSelectedIndex(position: Int32): Int32{
225
+ return position == 0 ? this.selected : (position <= this.selected ? position-1 : position);
226
+ }
227
+ onMouseDown(point: WebGL.Matrix.Point2D){
228
+ if(this.isOpen()){
229
+ if(this.isHovered()){
230
+ this.selected = this.getOptionIndexFromY(point.y);
231
+ this.onSelect(this.selected);
232
+ this.state = DropdownStateEnum.ClosedHover;
233
+ }else{
234
+ this.state = DropdownStateEnum.Closed;
235
+ }
236
+ this.setStateFromMousePoint(point);
237
+ }else{
238
+ if(this.isHovered()){
239
+ this.state = DropdownStateEnum.OpenHover;
240
+ }
241
+ }
242
+ }
243
+ isHovered(){
244
+ return this.state == DropdownStateEnum.OpenHover || this.state == DropdownStateEnum.ClosedHover;
245
+ }
246
+ isOpen(){
247
+ return this.state == DropdownStateEnum.Open || this.state == DropdownStateEnum.OpenHover;
248
+ }
249
+ isClosed(){
250
+ return this.state == DropdownStateEnum.Closed || this.state == DropdownStateEnum.ClosedHover;
251
+ }
252
+ private setStateFromMousePoint(point: WebGL.Matrix.Point2D){
253
+ if(this.isInside(point)){
254
+ if(this.isOpen()){
255
+ this.state = DropdownStateEnum.OpenHover;
256
+ }else if(this.isClosed()){
257
+ this.state = DropdownStateEnum.ClosedHover;
258
+ }
259
+ }else{
260
+ if(this.isOpen()){
261
+ this.state = DropdownStateEnum.Open;
262
+ }else if(this.isClosed()){
263
+ this.state = DropdownStateEnum.Closed;
264
+ }
265
+ }
266
+ if(this.isInside(point)){
267
+ this.position_hovered = this.getPositionIndexFromY(point.y);
268
+ }else{
269
+ this.position_hovered = -1;
270
+ }
271
+ }
272
+ onMouseOver(point: WebGL.Matrix.Point2D){
273
+ this.setStateFromMousePoint(point);
274
+
275
+ }
276
+ draw(vp: WebGL.Matrix.TransformationMatrix3x3,
277
+ colour_shader: WebGL.Shader.MVPColourProgram,
278
+ text_drawer: WebGL.TextDrawer
279
+ ){
280
+
281
+
282
+ //const bg_colour = this.isHovered() ? this.hovered_background_colour : this.background_colour;
283
+
284
+ //drawing background and border
285
+ if(!this.isOpen()){
286
+ this.drawBackground(vp, colour_shader, this.background_colour); //bg
287
+ //border
288
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x, this.y, this.width, this.border_width, this.border_colour);
289
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x, this.y+this.height-this.border_width, this.width, this.border_width, this.border_colour);
290
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x, this.y, this.border_width, this.height, this.border_colour);
291
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x+this.width-this.border_width, this.y, this.border_width, this.height, this.border_colour);
292
+ }else{
293
+ const open_height = this.openHeight();
294
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x, this.y, this.width, open_height, this.background_colour); //bg
295
+ //border
296
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x, this.y, this.width, this.border_width, this.border_colour);
297
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x, this.y+open_height-this.border_width, this.width, this.border_width, this.border_colour);
298
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x, this.y, this.border_width, open_height, this.border_colour);
299
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x+this.width-this.border_width, this.y, this.border_width, open_height, this.border_colour);
300
+ }
301
+
302
+ //draw hovered background
303
+ if(this.position_hovered != -1){
304
+ WebGL.WebGL.drawColourRect(vp, colour_shader,
305
+ this.x, this.y+(this.position_hovered*this.height),
306
+ this.width, this.height, this.hovered_background_colour
307
+ );
308
+ }
309
+
310
+ //draw selected text;
311
+ const text = this.hasOptions() ? this.options[this.selected] : DropdownOptions.no_option_text;
312
+ text_drawer.drawTextColour(vp, this.x+this.border_width, this.y+this.border_width, text, this.text_size, this.text_colour);
313
+
314
+ if(this.isOpen()){
315
+ //draw other options
316
+ let y = this.y+this.height+this.border_width;
317
+ for(let i = 0; i < this.options.length; i++){
318
+
319
+ if(i == this.selected) continue;
320
+ const opt = this.options[i];
321
+
322
+ //dividing line (todo - set colour)
323
+ WebGL.WebGL.drawColourRect(vp, colour_shader, this.x, y-(this.border_width*1.5), this.width, this.border_width, this.border_colour);
324
+
325
+ //select text
326
+ text_drawer.drawTextColour(vp, this.x+this.border_width, y, opt, this.text_size, this.text_colour);
327
+ y += this.height;
328
+ }
329
+ }
330
+
331
+ }
332
+ }
@@ -0,0 +1,183 @@
1
+ import { colour } from "../WebGL/Shaders/Fragment/Source/fragment_source";
2
+ import * as WebGL from "./../WebGL/globals";
3
+
4
+ type Int32 = number;
5
+ type Float = number;
6
+ type VoidFunction = () => void;
7
+ const EmptyFunction = () => {};
8
+
9
+ export class TextGlobals{
10
+ static selected_text = undefined;
11
+ static cursor_on: boolean = false;
12
+ static cursor_milliseconds_interval: Float = 500;
13
+ static current_cursor_milliseconds: Float = 0;
14
+
15
+ static update(time_elapsed: Float){
16
+ this.current_cursor_milliseconds += time_elapsed;
17
+ if(this.current_cursor_milliseconds > this.cursor_milliseconds_interval){
18
+ this.current_cursor_milliseconds -= this.cursor_milliseconds_interval;
19
+ this.cursor_on = !this.cursor_on;
20
+ }
21
+ }
22
+ }
23
+
24
+ const TextStatusEnum = {
25
+ Deselected: 0,
26
+ Selected: 1
27
+ } as const;
28
+
29
+ type TextStatus = (typeof TextStatusEnum)[keyof typeof TextStatusEnum];
30
+
31
+ export class TextInput{
32
+ x: Int32;
33
+ y: Int32;
34
+ width: Int32;
35
+ height: Int32;
36
+
37
+ background_colour: WebGL.Colour.ColourRGB;
38
+ text_colour: WebGL.Colour.ColourRGB;
39
+ cursor_colour: WebGL.Colour.ColourRGB;
40
+
41
+ select_border_colour: WebGL.Colour.ColourRGB;
42
+
43
+ text: string;
44
+
45
+ text_offset: Int32;
46
+
47
+ text_size: Int32;
48
+
49
+ state: TextStatus;
50
+
51
+ cursor_thickness: Int32;
52
+ cursor_index: Int32;
53
+
54
+ onChange: (text: string) => void;
55
+
56
+ constructor(x: Int32, y: Int32, width: Int32, height: Int32, ts: Int32=height-4){
57
+ this.x = x;
58
+ this.y = y;
59
+ this.width = width;
60
+ this.height = height;
61
+
62
+ this.text_offset = 3;
63
+
64
+ this.text_size = ts;
65
+
66
+ this.background_colour = WebGL.Colour.ColourUtils.white();
67
+ this.text_colour = WebGL.Colour.ColourUtils.black();
68
+ this.cursor_colour = WebGL.Colour.ColourUtils.blue();
69
+ this.select_border_colour = WebGL.Colour.ColourUtils.fromRGB(0.3, 0.5, 0.9);
70
+
71
+ this.text = "";
72
+
73
+ this.state = TextStatusEnum.Deselected;
74
+
75
+ this.cursor_thickness = 1;
76
+ this.cursor_index = 0;
77
+ this.onChange = (_) => {};
78
+ }
79
+ maxTextSize(): Int32{
80
+ return Math.floor((this.width-(this.text_offset*2)) / this.text_size);
81
+ }
82
+ isInside(point: WebGL.Matrix.Point2D): boolean{
83
+ const in_x = this.x < point.x && point.x < this.x+this.width;
84
+ const in_y = this.y < point.y && point.y < this.y+this.height;
85
+ return in_x && in_y;
86
+ }
87
+ onKeyDown(ev: KeyboardEvent){
88
+ console.log(ev.key);
89
+ if(this.state == TextStatusEnum.Selected){
90
+ if(ev.key.length == 1 && this.text.length < this.maxTextSize()){
91
+ this.text = this.text.slice(0, this.cursor_index) + ev.key + this.text.slice(this.cursor_index);
92
+ this.cursor_index++;
93
+ this.onChange(this.text);
94
+ }else if(ev.key === "Backspace"){
95
+ if(this.cursor_index > 0){
96
+ this.text = this.text.slice(0, this.cursor_index-1) + this.text.slice(this.cursor_index);
97
+ this.cursor_index--;
98
+ this.onChange(this.text);
99
+ }
100
+ }else if(ev.key === "ArrowRight"){
101
+ if(this.cursor_index < this.text.length){
102
+ this.cursor_index++;
103
+ }
104
+ }else if(ev.key === "ArrowLeft"){
105
+ if(this.cursor_index > 0){
106
+ this.cursor_index--;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ cursorIndexFromX(x: Float): Int32{
112
+ const fl = (x-(this.x+this.text_offset))/this.text_size;
113
+ const i = Math.round(fl);
114
+ return i > this.text.length ? this.text.length : i;
115
+ }
116
+ onMouseMove(point: WebGL.Matrix.Point2D){
117
+
118
+ }
119
+ onMouseDown(point: WebGL.Matrix.Point2D){
120
+ if(this.isInside(point)){
121
+ this.state = TextStatusEnum.Selected;
122
+ const index = this.cursorIndexFromX(point.x);
123
+ this.cursor_index = index;
124
+ }else{
125
+ this.state = TextStatusEnum.Deselected;
126
+ }
127
+ }
128
+ onMouseUp(){
129
+
130
+ }
131
+
132
+ draw(vp: WebGL.Matrix.TransformationMatrix3x3,
133
+ colour_shader: WebGL.Shader.MVPColourProgram,
134
+ text_drawer: WebGL.TextDrawer){
135
+ //draw background
136
+ colour_shader.use();
137
+ colour_shader.setColourFromColourRGB(this.background_colour);
138
+ const background_model = WebGL.WebGL.rectangleModel(this.x, this.y, this.width, this.height);
139
+ colour_shader.setMvp(vp.multiplyCopy(background_model));
140
+ WebGL.Shapes.Quad.draw();
141
+
142
+ const text_height_diff = this.height - this.text_size;
143
+
144
+ const y = this.y + (text_height_diff*0.5);
145
+
146
+ //text cursor
147
+ if(TextGlobals.cursor_on && this.state == TextStatusEnum.Selected){
148
+ colour_shader.setColourFromColourRGB(this.cursor_colour);
149
+ const cursor_model = WebGL.WebGL.rectangleModel(
150
+ this.x+this.text_offset-this.cursor_thickness+(this.text_size*this.cursor_index),
151
+ y, this.cursor_thickness, this.text_size
152
+ );
153
+ colour_shader.setMvp(vp.multiplyCopy(cursor_model));
154
+ WebGL.Shapes.Quad.draw();
155
+ }
156
+
157
+
158
+ //draw text
159
+ text_drawer.drawTextColour(vp, this.x+this.text_offset, y, this.text, this.text_size, this.text_colour);
160
+
161
+ //draw border
162
+ if(this.state == TextStatusEnum.Selected){
163
+ const border_size = 2;
164
+ colour_shader.use();
165
+ colour_shader.setColourFromColourRGB(this.select_border_colour);
166
+ const left_model = WebGL.WebGL.rectangleModel(this.x, this.y, border_size, this.height);
167
+ colour_shader.setMvp(vp.multiplyCopy(left_model));
168
+ WebGL.Shapes.Quad.draw();
169
+
170
+ const right_model = WebGL.WebGL.rectangleModel(this.x+this.width-border_size, this.y, border_size, this.height);
171
+ colour_shader.setMvp(vp.multiplyCopy(right_model));
172
+ WebGL.Shapes.Quad.draw();
173
+
174
+ const top_model = WebGL.WebGL.rectangleModel(this.x, this.y, this.width, border_size);
175
+ colour_shader.setMvp(vp.multiplyCopy(top_model));
176
+ WebGL.Shapes.Quad.draw();
177
+
178
+ const bot_model = WebGL.WebGL.rectangleModel(this.x, this.y+this.height-border_size, this.width, border_size);
179
+ colour_shader.setMvp(vp.multiplyCopy(bot_model));
180
+ WebGL.Shapes.Quad.draw();
181
+ }
182
+ }
183
+ }
@@ -0,0 +1,30 @@
1
+ import { expect, test } from 'vitest'
2
+ import * as Matrix from './matrix'
3
+
4
+ test('3x3 matrix tests', () => {
5
+ const minor_test = new Matrix.Matrix3x3();
6
+ minor_test.setMatrix([3,0,2,2,0,-2,0,1,1]);
7
+ const equal_test = new Matrix.Matrix3x3();
8
+ equal_test.setMatrix([3,-0,2,2,-0,-2,0,1,1]);
9
+ expect(Matrix.Matrix3x3.equals(minor_test, equal_test)).toBeTruthy();
10
+ expect(minor_test.matrix[2]).toBe(2);
11
+ expect(minor_test.matrix[5]).toBe(-2);
12
+ expect(minor_test.matrix[1]).toBe(0);
13
+ expect(minor_test.matrix[6]).toBe(0);
14
+ expect(minor_test.matrix[7]).toBe(1);
15
+ const minor = minor_test.matrixMinorsCopy();
16
+ const minor_result = new Matrix.Matrix3x3();
17
+ minor_result.setMatrix([2, 2, 2, -2, 3, 3, 0, -10, 0]);
18
+ expect(Matrix.Matrix3x3.equals(minor, minor_result)).toBeTruthy();
19
+
20
+ const cofactor = minor_test.matrixCofactorsCopy();
21
+ const cofactor_result = Matrix.Matrix3x3.new([2,-2,2,2,3,-3,0,10,0]);
22
+ expect(Matrix.Matrix3x3.equals(cofactor, cofactor_result)).toBeTruthy();
23
+
24
+ const determinant = minor_test.determinant();
25
+ expect(determinant).toBe(10);
26
+
27
+ const inverse_result = Matrix.Matrix3x3.new([0.2, 0.2, 0, -0.2, 0.3, 1, 0.2, -0.3, 0]);
28
+ const inverse = minor_test.inverseCopy();
29
+ expect(Matrix.Matrix3x3.equals(inverse, inverse_result)).toBeTruthy();
30
+ });