@cjcoding-git/gamelib 1.1.2 → 1.1.3

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 (136) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  3. package/.github/dependabot.yml +6 -0
  4. package/.github/workflows/build.yml +54 -0
  5. package/.github/workflows/release.yml +79 -0
  6. package/LICENSE +21 -0
  7. package/README.md +7 -0
  8. package/assets/test-frog.gltf +1921 -0
  9. package/assets/test-frog.gml +0 -0
  10. package/buildtime.txt +1 -0
  11. package/buildversion.txt +1 -0
  12. package/dist/GameLib.js +71599 -0
  13. package/dist/GameLib.min.js +8 -0
  14. package/docs/2D/API.md +1 -0
  15. package/docs/2D/GETTING_STARTED.md +1 -0
  16. package/docs/3D/API.md +1 -0
  17. package/docs/3D/GETTING_STARTED.md +23 -0
  18. package/docs/Core/API.md +1 -0
  19. package/docs/Core/GETTING_STARTED.md +1 -0
  20. package/docs/README.md +32 -0
  21. package/package.json +12 -13
  22. package/scripts/gltf2gml.html +312 -0
  23. package/src/2D/Box.js +42 -0
  24. package/src/2D/Coord.js +17 -0
  25. package/src/2D/GameLib.js +317 -0
  26. package/src/2D/Renderable.js +31 -0
  27. package/src/2D/Rotation.js +42 -0
  28. package/src/2D/Size.js +17 -0
  29. package/src/2D/Sprite.js +56 -0
  30. package/src/2D/UI/Button.js +52 -0
  31. package/src/2D/UI/TextInput.js +77 -0
  32. package/src/2D/UI/UIElement.js +10 -0
  33. package/src/2D/UI/index.js +15 -0
  34. package/src/2D/index.js +24 -0
  35. package/src/3D/Camera.js +25 -0
  36. package/src/3D/GameLib.js +202 -0
  37. package/src/3D/Geometry/Box.js +39 -0
  38. package/src/3D/Geometry/Cone.js +45 -0
  39. package/src/3D/Geometry/ModelLoaders/GLBLoader.js +12 -0
  40. package/src/3D/Geometry/ModelLoaders/GLTFLoader.js +12 -0
  41. package/src/3D/Geometry/ModelLoaders/GMLLoader.js +114 -0
  42. package/src/3D/Geometry/ModelLoaders/OBJLoader.js +12 -0
  43. package/src/3D/Geometry/ModelLoaders/index.js +17 -0
  44. package/src/3D/Geometry/Pyramid.js +55 -0
  45. package/src/3D/Geometry/Sphere.js +37 -0
  46. package/src/3D/Geometry/index.js +19 -0
  47. package/src/3D/Lighting/AmbientLight.js +17 -0
  48. package/src/3D/Lighting/DirectionalLight.js +17 -0
  49. package/src/3D/Lighting/PointLight.js +17 -0
  50. package/src/3D/Lighting/index.js +15 -0
  51. package/src/3D/Material.js +181 -0
  52. package/src/3D/Mesh.js +142 -0
  53. package/src/3D/Object.js +13 -0
  54. package/src/3D/Position.js +15 -0
  55. package/src/3D/Rotation.js +21 -0
  56. package/src/3D/Scale.js +10 -0
  57. package/src/3D/ShaderFactory/FunctionParam.js +14 -0
  58. package/src/3D/ShaderFactory/Modifiers/Variable.js +85 -0
  59. package/src/3D/ShaderFactory/Modifiers/index.js +11 -0
  60. package/src/3D/ShaderFactory/Node.js +25 -0
  61. package/src/3D/ShaderFactory/NodeTypes/A.js +9 -0
  62. package/src/3D/ShaderFactory/NodeTypes/Add.js +13 -0
  63. package/src/3D/ShaderFactory/NodeTypes/AssignVariable.js +11 -0
  64. package/src/3D/ShaderFactory/NodeTypes/Clamp.js +14 -0
  65. package/src/3D/ShaderFactory/NodeTypes/Constant.js +9 -0
  66. package/src/3D/ShaderFactory/NodeTypes/Define.js +11 -0
  67. package/src/3D/ShaderFactory/NodeTypes/Divide.js +13 -0
  68. package/src/3D/ShaderFactory/NodeTypes/Dot.js +14 -0
  69. package/src/3D/ShaderFactory/NodeTypes/Exp2.js +9 -0
  70. package/src/3D/ShaderFactory/NodeTypes/Function.js +36 -0
  71. package/src/3D/ShaderFactory/NodeTypes/Group.js +9 -0
  72. package/src/3D/ShaderFactory/NodeTypes/Header.js +12 -0
  73. package/src/3D/ShaderFactory/NodeTypes/Length.js +9 -0
  74. package/src/3D/ShaderFactory/NodeTypes/MainFunction.js +7 -0
  75. package/src/3D/ShaderFactory/NodeTypes/Max.js +14 -0
  76. package/src/3D/ShaderFactory/NodeTypes/Mix.js +14 -0
  77. package/src/3D/ShaderFactory/NodeTypes/Multiply.js +13 -0
  78. package/src/3D/ShaderFactory/NodeTypes/Negative.js +9 -0
  79. package/src/3D/ShaderFactory/NodeTypes/NodeTypes.js +9 -0
  80. package/src/3D/ShaderFactory/NodeTypes/Normalize.js +10 -0
  81. package/src/3D/ShaderFactory/NodeTypes/Precision.js +11 -0
  82. package/src/3D/ShaderFactory/NodeTypes/RGB.js +9 -0
  83. package/src/3D/ShaderFactory/NodeTypes/Subtract.js +13 -0
  84. package/src/3D/ShaderFactory/NodeTypes/Symbol.js +9 -0
  85. package/src/3D/ShaderFactory/NodeTypes/Texture2D.js +10 -0
  86. package/src/3D/ShaderFactory/NodeTypes/Variable.js +22 -0
  87. package/src/3D/ShaderFactory/NodeTypes/Vector.js +15 -0
  88. package/src/3D/ShaderFactory/NodeTypes/XYZ.js +9 -0
  89. package/src/3D/ShaderFactory/NodeTypes/index.js +32 -0
  90. package/src/3D/ShaderFactory/PrecisionTypes.js +8 -0
  91. package/src/3D/ShaderFactory/Program.js +41 -0
  92. package/src/3D/ShaderFactory/VariableTypes.js +49 -0
  93. package/src/3D/ShaderFactory/index.js +45 -0
  94. package/src/3D/Texture.js +59 -0
  95. package/src/3D/TextureFactory.js +22 -0
  96. package/src/3D/Transform.js +35 -0
  97. package/src/3D/UI/UIImage.js +24 -0
  98. package/src/3D/UI/UILoading.js +41 -0
  99. package/src/3D/UI/UIObject.js +16 -0
  100. package/src/3D/UI/UIPath.js +25 -0
  101. package/src/3D/UI/UIRenderer.js +207 -0
  102. package/src/3D/UI/UIText.js +35 -0
  103. package/src/3D/UI/index.js +19 -0
  104. package/src/3D/Utils.js +9 -0
  105. package/src/3D/index.js +43 -0
  106. package/src/Core/AssetManager.js +116 -0
  107. package/src/Core/AudioManager.js +151 -0
  108. package/src/Core/Error.js +9 -0
  109. package/src/Core/FullscreenManager.js +49 -0
  110. package/src/Core/GameLibBase.js +29 -0
  111. package/src/Core/InputManager.js +195 -0
  112. package/src/Core/Loading.js +111 -0
  113. package/src/Core/Matrix/index.js +11 -0
  114. package/src/Core/Matrix/mat4.js +178 -0
  115. package/src/Core/Multiplayer.js +54 -0
  116. package/src/Core/Network/PeerNetwork.js +410 -0
  117. package/src/Core/Network/index.js +11 -0
  118. package/src/Core/Storage.js +45 -0
  119. package/src/Core/Store.js +45 -0
  120. package/src/Core/Utils.js +34 -0
  121. package/src/Core/index.js +30 -0
  122. package/src/Lib/Ammo.js +72 -0
  123. package/src/Lib/Matter.js +1 -0
  124. package/src/Shaders/Material/Fragment/GL1.glsl +49 -0
  125. package/src/Shaders/Material/Fragment/GL2.glsl +51 -0
  126. package/src/Shaders/Material/Vertex/GL1.glsl +19 -0
  127. package/src/Shaders/Material/Vertex/GL2.glsl +20 -0
  128. package/src/Shaders/UI/Fragment/GL1.glsl +5 -0
  129. package/src/Shaders/UI/Fragment/GL2.glsl +7 -0
  130. package/src/Shaders/UI/Vertex/GL1.glsl +10 -0
  131. package/src/Shaders/UI/Vertex/GL2.glsl +11 -0
  132. package/src/Shaders/UITexture/Fragment/GL1.glsl +6 -0
  133. package/src/Shaders/UITexture/Fragment/GL2.glsl +8 -0
  134. package/src/Shaders/UITexture/Vertex/GL1.glsl +10 -0
  135. package/src/Shaders/UITexture/Vertex/GL2.glsl +11 -0
  136. package/src/index.js +19 -0
@@ -0,0 +1,202 @@
1
+ import { GameLibCore } from "../Core/index.js"
2
+ import { GameLib3D } from "./index.js"
3
+ import { Object } from "./Object.js"
4
+ import { UIRenderer } from "./UI/UIRenderer.js"
5
+ import { UILoading } from "./UI/UILoading.js"
6
+ class GameLib extends GameLibCore.GameLibBase {
7
+ constructor(renderCanvas, renderCtx, options) {
8
+ super();
9
+ if (GameLib3D.GameLib._instance != null) {
10
+ return GameLib3D.GameLib._instance;
11
+ } else {
12
+ console.log("[GameLib] No GameLib3D instance found. Creating new instance.");
13
+ this._canvas = renderCanvas;
14
+ this._gl = renderCtx;
15
+ this._objects = [];
16
+ this._options = options;
17
+ this._clearColor = [ 0.0, 0.0, 0.0, 1.0 ];
18
+ this._camera = null;
19
+ this._program = null;
20
+ this._uiRenderer = new UIRenderer(this);
21
+ this._scene = "loading";
22
+ this._loadingConfig = {};
23
+ this._uiLoading = new UILoading(this);
24
+ this._uiLoading.setConfig(this._loadingConfig);
25
+ this._uiRenderer.addObject(this._uiLoading);
26
+ this._listeners = {};
27
+ this.registerMainloop();
28
+ GameLib3D.GameLib._instance = this;
29
+ }
30
+ }
31
+ setLoadingConfig(config) {
32
+ this._loadingConfig = config;
33
+ this._uiLoading.setConfig(config);
34
+ }
35
+ static getContext(canvas, webgl2=true) {
36
+ if(webgl2) {
37
+ return canvas.getContext('webgl2');
38
+ } else {
39
+ return canvas.getContext('webgl');
40
+ }
41
+ }
42
+ get webgl() {
43
+ return this._gl;
44
+ }
45
+ get options() {
46
+ return this._options;
47
+ }
48
+ setClearColor(color) {
49
+ this._clearColor = color;
50
+ }
51
+ compileShader(type, source) {
52
+ if(typeof type == "string") {
53
+ if(type == "vertex") {
54
+ type = this._gl.VERTEX_SHADER;
55
+ }
56
+ if(type == "fragment") {
57
+ type = this._gl.FRAGMENT_SHADER;
58
+ }
59
+ }
60
+ var shader = this._gl.createShader(type);
61
+ this._gl.shaderSource(shader, source);
62
+ this._gl.compileShader(shader);
63
+ if(!this._gl.getShaderParameter(shader, this._gl.COMPILE_STATUS)) {
64
+ console.warn("[GameLib] Shader compilation failed:", this._gl.getShaderInfoLog(shader));
65
+ this._gl.deleteShader(shader);
66
+ return null;
67
+ }
68
+ return shader;
69
+ }
70
+ createProgram(...shaders) {
71
+ var program = this._gl.createProgram();
72
+ for(var i=0;i<shaders.length;i++) {
73
+ this._gl.attachShader(program, shaders[i]);
74
+ }
75
+ this._gl.linkProgram(program);
76
+ if(!this._gl.getProgramParameter(program, this._gl.LINK_STATUS)) {
77
+ console.warn("[GameLib] Program linking failed:", this._gl.getProgramInfoLog(program));
78
+ return null;
79
+ }
80
+ return program;
81
+ }
82
+ useProgram(program) {
83
+ this._program = program;
84
+ this._gl.useProgram(program);
85
+ }
86
+ setCamera(camera) {
87
+ this._camera = camera;
88
+ }
89
+ getAttributeLocation(program, name, forceMode=null) {
90
+ var location;
91
+ if((!forceMode && name.startsWith('a')) || forceMode == 'attribute') {
92
+ location = this._gl.getAttribLocation(program, name);
93
+ }
94
+ if((!forceMode && name.startsWith('u')) || forceMode == 'uniform') {
95
+ location = this._gl.getUniformLocation(program, name);
96
+ }
97
+ return location;
98
+ }
99
+ setProgramAttribute(program, name, buffer, num, type, normalize=false, stride=0, offset=0, forceMode=null) {
100
+ if(!type) type = this._gl.FLOAT;
101
+ var location = this.getAttributeLocation(program, name, forceMode);
102
+ if (location === null || location === -1) {
103
+ return;
104
+ }
105
+ this._gl.bindBuffer(this._gl.ARRAY_BUFFER, buffer);
106
+ this._gl.vertexAttribPointer(location, num, type, normalize, stride, offset);
107
+ this._gl.enableVertexAttribArray(location);
108
+ }
109
+ addObject(object) {
110
+ if(object instanceof Object) {
111
+ object.setup();
112
+ this._objects.push(object);
113
+ } else {
114
+ throw new GameLibCore.Error("GameLib3D.GameLib.addObject(object) must be passed an instance of Object!");
115
+ }
116
+ }
117
+ update() {
118
+ if(!this._active) return;
119
+ this.callHook('pre-update');
120
+ for(var i=0;i<this._objects.length;i++) {
121
+ this._objects[i].update(this._camera);
122
+ }
123
+ this.callHook('post-update');
124
+ }
125
+ clearCanvas() {
126
+ this._gl.clearColor(...this._clearColor);
127
+ this._gl.clearDepth(1.0);
128
+ this._gl.enable(this._gl.DEPTH_TEST);
129
+ this._gl.depthFunc(this._gl.LEQUAL);
130
+ this._gl.enable(this._gl.BLEND);
131
+ this._gl.blendFunc(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_ALPHA);
132
+ this._gl.clear(this._gl.COLOR_BUFFER_BIT | this._gl.DEPTH_BUFFER_BIT);
133
+ }
134
+ draw() {
135
+ if(!this._rendering) return;
136
+ this.clearCanvas();
137
+ this.callHook('pre-render');
138
+ for(var i=0;i<this._objects.length;i++) {
139
+ if(this._objects[i].scene === this._scene) {
140
+ this._objects[i].draw(this._camera);
141
+ }
142
+ }
143
+ this._uiRenderer.render(this._scene);
144
+ this.callHook('post-render');
145
+ }
146
+ addUIObject(object) {
147
+ return this._uiRenderer.addObject(object);
148
+ }
149
+ getUIObjects() {
150
+ return this._uiRenderer.getObjects();
151
+ }
152
+ removeUIObject(id) {
153
+ this._uiRenderer.removeObject(id);
154
+ }
155
+ mainloop() {
156
+ this.update();
157
+ this.draw();
158
+ this.registerMainloop();
159
+ }
160
+ registerMainloop() {
161
+ window.requestAnimationFrame(this.mainloop.bind(this));
162
+ }
163
+ stopLoading() {
164
+ this._scene = "init";
165
+ }
166
+ setScene(scene) {
167
+ this._scene = scene;
168
+ }
169
+ listen(type, callback) {
170
+ if(!this._listeners[type]) this._listeners[type] = [];
171
+ this._listeners[type].push(callback);
172
+ }
173
+ _fire(type) {
174
+ if(!this._listeners[type]) return;
175
+ for(var i=0;i<this._listeners[type].length;i++) {
176
+ var listener = this._listeners[type][i];
177
+ if(listener && typeof listener === "function") {
178
+ listener();
179
+ }
180
+ }
181
+ }
182
+ resizeToWindow() {
183
+ this._canvas.width = window.innerWidth;
184
+ this._canvas.height = window.innerHeight;
185
+ this._canvas.style.position = "fixed";
186
+ this._canvas.style.top = "0";
187
+ this._canvas.style.left = "0";
188
+ this._gl.viewport(0, 0, this._canvas.width, this._canvas.height);
189
+ this._fire('resize');
190
+ }
191
+ fillWindow() {
192
+ window.addEventListener('resize', this.resizeToWindow.bind(this), false);
193
+ this.resizeToWindow();
194
+ }
195
+ getLights(scene) {
196
+ if(!scene) scene = this._scene;
197
+ return this._objects.filter(object => object.isLight && object.scene === scene);
198
+ }
199
+ }
200
+ export {
201
+ GameLib
202
+ }
@@ -0,0 +1,39 @@
1
+ class Box {
2
+ constructor(width=1, height=1, depth=1) {
3
+ var w = width / 2;
4
+ var h = height / 2;
5
+ var d = depth / 2;
6
+ var positions = [
7
+ -w, -h, d, w, -h, d, w, h, d, -w, h, d,
8
+ -w, -h, -d, -w, h, -d, w, h, -d, w, -h, -d,
9
+ -w, h, -d, -w, h, d, w, h, d, w, h, -d,
10
+ -w, -h, -d, w, -h, -d, w, -h, d, -w, -h, d,
11
+ w, -h, -d, w, h, -d, w, h, d, w, -h, d,
12
+ -w, -h, -d, -w, -h, d, -w, h, d, -w, h, -d
13
+ ];
14
+ var normals = [
15
+ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
16
+ 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1,
17
+ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
18
+ 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0,
19
+ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
20
+ -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0
21
+ ];
22
+ var uv = [];
23
+ for(var i=0;i<6;i++) {
24
+ uv.push(0, 0, 1, 0, 1, 1, 0, 1);
25
+ }
26
+ var indices = [];
27
+ for(var i=0;i<6;i++) {
28
+ var offset = i * 4;
29
+ indices.push(offset, offset + 1, offset + 2, offset, offset + 2, offset + 3);
30
+ }
31
+ this.positions = positions;
32
+ this.normals = normals;
33
+ this.uv = uv;
34
+ this.indices = indices;
35
+ }
36
+ }
37
+ export {
38
+ Box
39
+ }
@@ -0,0 +1,45 @@
1
+ class Cone {
2
+ constructor(radius=1, height=2, segments=24) {
3
+ var positions = [];
4
+ var normals = [];
5
+ var uv = [];
6
+ var indices = [];
7
+ var halfH = height / 2;
8
+ positions.push(0, halfH, 0);
9
+ normals.push(0, 1, 0);
10
+ uv.push(0.5, 1.0);
11
+ for(var i=0;i<=segments;i++) {
12
+ var angle = (i * 2 * Math.PI) / segments;
13
+ var x = Math.sin(angle);
14
+ var z = Math.cos(angle);
15
+ positions.push(radius * x, -halfH, radius * z);
16
+ var slantLen = Math.sqrt(radius * radius + height * height);
17
+ normals.push((height / slantLen) * x, radius / slantLen, (height / slantLen) * z);
18
+ uv.push(i / segments, 0.0);
19
+ }
20
+ for(var i=0;i<=segments;i++) {
21
+ indices.push(0, i, i + 1);
22
+ }
23
+ var baseCenterIdx = positions.length / 3;
24
+ positions.push(0, -halfH, 0);
25
+ normals.push(0, -1, 0);
26
+ uv.push(0.5, 0.5);
27
+ var baseStartIdx = positions.length / 3;
28
+ for(var i=0;i<=segments;i++) {
29
+ var angle = (i * 2 * Math.PI) / segments;
30
+ positions.push(radius * Math.cos(angle), -halfH, radius * Math.sin(angle));
31
+ normals.push(0, -1, 0);
32
+ uv.push(0.5 + 0.5 * Math.cos(angle), 0.5 + 0.5 * Math.sin(angle));
33
+ }
34
+ for(var i=0;i<segments;i++) {
35
+ indices.push(baseCenterIdx, baseStartIdx + i + 1, baseStartIdx + i);
36
+ }
37
+ this.positions = positions;
38
+ this.normals = normals;
39
+ this.uv = uv;
40
+ this.indices = indices;
41
+ }
42
+ }
43
+ export {
44
+ Cone
45
+ }
@@ -0,0 +1,12 @@
1
+ import { GameLibCore } from "../../../Core/index.js"
2
+ class GLBLoader {
3
+ constructor() {
4
+ throw new GameLibCore.Error("Class GLBLoader may not be constructed!");
5
+ }
6
+ static load(url, options={}) {
7
+ throw new GameLibCore.Error("Loading GLB files is not yet implemented.");
8
+ }
9
+ }
10
+ export {
11
+ GLBLoader
12
+ }
@@ -0,0 +1,12 @@
1
+ import { GameLibCore } from "../../../Core/index.js"
2
+ class GLTFLoader {
3
+ constructor() {
4
+ throw new GameLibCore.Error("Class GLTFLoader may not be constructed!");
5
+ }
6
+ static load(url, options={}) {
7
+ throw new GameLibCore.Error("Loading GLTF files is not yet implemented.");
8
+ }
9
+ }
10
+ export {
11
+ GLTFLoader
12
+ }
@@ -0,0 +1,114 @@
1
+ import { GameLibCore } from "../../../Core/index.js"
2
+ class GMLLoader {
3
+ constructor() {
4
+ throw new GameLibCore.Error("Class GMLLoader may not be constructed!");
5
+ }
6
+ static MAGIC = "GML1";
7
+ static VERSION = 1;
8
+ static async load(url, options = {}) {
9
+ if (typeof fetch !== "function") {
10
+ throw new GameLibCore.Error("GMLLoader.load requires fetch support.");
11
+ }
12
+ const response = await fetch(url, options);
13
+ if (!response.ok) {
14
+ throw new GameLibCore.Error(`Failed to load model (${response.status} ${response.statusText}): ${url}`);
15
+ }
16
+ return GMLLoader.parse(await response.arrayBuffer());
17
+ }
18
+ static parse(input) {
19
+ let buffer;
20
+ if (input instanceof ArrayBuffer) {
21
+ buffer = input;
22
+ } else if (ArrayBuffer.isView(input)) {
23
+ buffer = input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength);
24
+ } else {
25
+ throw new GameLibCore.Error("GMLLoader.parse expects an ArrayBuffer or typed-array view.");
26
+ }
27
+ const view = new DataView(buffer);
28
+ let offset = 0;
29
+ const ensure = (byteLength) => {
30
+ if (!Number.isSafeInteger(byteLength) || byteLength < 0 || offset + byteLength > view.byteLength) {
31
+ throw new GameLibCore.Error("Invalid or truncated GML1 model data.");
32
+ }
33
+ };
34
+ const readUint16 = () => {
35
+ ensure(2);
36
+ const value = view.getUint16(offset, true);
37
+ offset += 2;
38
+ return value;
39
+ };
40
+ const readUint32 = () => {
41
+ ensure(4);
42
+ const value = view.getUint32(offset, true);
43
+ offset += 4;
44
+ return value;
45
+ };
46
+ const readFloat32Array = (length) => {
47
+ const byteLength = length * 4;
48
+ ensure(byteLength);
49
+ const values = new Float32Array(length);
50
+ for (let i = 0; i < length; i++) {
51
+ values[i] = view.getFloat32(offset, true);
52
+ offset += 4;
53
+ }
54
+ return values;
55
+ };
56
+ ensure(8);
57
+ const magic = String.fromCharCode(
58
+ view.getUint8(0), view.getUint8(1), view.getUint8(2), view.getUint8(3)
59
+ );
60
+ if (magic !== GMLLoader.MAGIC) {
61
+ throw new GameLibCore.Error(`Invalid native model signature: expected ${GMLLoader.MAGIC}.`);
62
+ }
63
+ offset = 4;
64
+ const version = readUint16();
65
+ if (version !== GMLLoader.VERSION) {
66
+ throw new GameLibCore.Error(`Unsupported GML1 model version: ${version}.`);
67
+ }
68
+ const meshCount = readUint16();
69
+ const decoder = new TextDecoder();
70
+ const meshes = [];
71
+ for (let meshIndex = 0; meshIndex < meshCount; meshIndex++) {
72
+ const nameLength = readUint16();
73
+ ensure(nameLength);
74
+ const name = decoder.decode(new Uint8Array(buffer, offset, nameLength));
75
+ offset += nameLength;
76
+ const vertexCount = readUint32();
77
+ const indexCount = readUint32();
78
+ if (vertexCount === 0 || indexCount === 0 || indexCount % 3 !== 0) {
79
+ throw new GameLibCore.Error(`Invalid vertex or triangle index count in GML1 mesh ${meshIndex}.`);
80
+ }
81
+ const color = readFloat32Array(4);
82
+ const positions = readFloat32Array(vertexCount * 3);
83
+ const normals = readFloat32Array(vertexCount * 3);
84
+ const uv = readFloat32Array(vertexCount * 2);
85
+ const indices = readFloat32Array(0); // Keep all reads checked through the shared bounds helper.
86
+ void indices;
87
+ const indexByteLength = indexCount * 4;
88
+ ensure(indexByteLength);
89
+ const meshIndices = new Uint32Array(indexCount);
90
+ for (let i = 0; i < indexCount; i++) {
91
+ const index = readUint32();
92
+ if (index >= vertexCount) {
93
+ throw new GameLibCore.Error(`GML1 mesh ${meshIndex} contains an out-of-range index.`);
94
+ }
95
+ meshIndices[i] = index;
96
+ }
97
+ meshes.push({
98
+ name,
99
+ positions,
100
+ normals,
101
+ uv,
102
+ indices: meshIndices,
103
+ material: { color }
104
+ });
105
+ }
106
+ if (offset !== view.byteLength) {
107
+ throw new GameLibCore.Error("Unexpected trailing bytes in GML1 model data.");
108
+ }
109
+ return { format: GMLLoader.MAGIC, version, meshes };
110
+ }
111
+ }
112
+ export {
113
+ GMLLoader
114
+ }
@@ -0,0 +1,12 @@
1
+ import { GameLibCore } from "../../../Core/index.js"
2
+ class OBJLoader {
3
+ constructor() {
4
+ throw new GameLibCore.Error("Class OBJLoader may not be constructed!");
5
+ }
6
+ static load(url, options={}) {
7
+ throw new GameLibCore.Error("Loading OBJ files is not yet implemented.");
8
+ }
9
+ }
10
+ export {
11
+ OBJLoader
12
+ }
@@ -0,0 +1,17 @@
1
+ import { GameLibCore } from "../../../Core/index.js"
2
+ import { GMLLoader } from "./GMLLoader.js"
3
+ import { GLBLoader } from "./GLBLoader.js"
4
+ import { GLTFLoader } from "./GLTFLoader.js"
5
+ import { OBJLoader } from "./OBJLoader.js"
6
+ class ModelLoaders {
7
+ constructor() {
8
+ throw new GameLibCore.Error("Class ModelLoaders may not be constructed!");
9
+ }
10
+ static GMLLoader = GMLLoader;
11
+ static GLBLoader = GLBLoader;
12
+ static GLTFLoader = GLTFLoader;
13
+ static OBJLoader = OBJLoader;
14
+ }
15
+ export {
16
+ ModelLoaders
17
+ }
@@ -0,0 +1,55 @@
1
+ class Pyramid {
2
+ constructor(width=1, height=1, depth=1, sides=4) {
3
+ height = height / 2;
4
+ sides = Math.max(3, Math.floor(sides));
5
+ var positions = [];
6
+ var normals = [];
7
+ var uv = [];
8
+ var indices = [];
9
+ var halfW = width / 2;
10
+ var halfH = height / 2;
11
+ var halfD = depth / 2;
12
+ for (var i = 0; i < sides; i++) {
13
+ var angle0 = (i * 2 * Math.PI) / sides;
14
+ var angle1 = ((i + 1) * 2 * Math.PI) / sides;
15
+ var x0 = halfW * Math.cos(angle0);
16
+ var z0 = halfD * Math.sin(angle0);
17
+ var x1 = halfW * Math.cos(angle1);
18
+ var z1 = halfD * Math.sin(angle1);
19
+ var centerX = (x0 + x1) / 2;
20
+ var centerZ = (z0 + z1) / 2;
21
+ var normalLength = Math.hypot(height * centerX, halfH * (z0 - z1));
22
+ var nx = (height * centerX) / normalLength;
23
+ var ny = (halfH * (z0 - z1)) / normalLength;
24
+ var nz = (halfH * (x1 - x0)) / normalLength;
25
+ var offset = positions.length / 3;
26
+ positions.push(x0, -halfH, z0, x1, -halfH, z1, 0, halfH, 0);
27
+ for (var vertex = 0; vertex < 3; vertex++) {
28
+ normals.push(nx, ny, nz);
29
+ }
30
+ uv.push(0, 0, 1, 0, 0.5, 1);
31
+ indices.push(offset, offset + 1, offset + 2);
32
+ }
33
+ var baseCenter = positions.length / 3;
34
+ positions.push(0, -halfH, 0);
35
+ normals.push(0, -1, 0);
36
+ uv.push(0.5, 0.5);
37
+ var baseStart = positions.length / 3;
38
+ for (var j = 0; j < sides; j++) {
39
+ var baseAngle = (j * 2 * Math.PI) / sides;
40
+ positions.push(halfW * Math.cos(baseAngle), -halfH, halfD * Math.sin(baseAngle));
41
+ normals.push(0, -1, 0);
42
+ uv.push(0.5 + 0.5 * Math.cos(baseAngle), 0.5 + 0.5 * Math.sin(baseAngle));
43
+ }
44
+ for (var k = 0; k < sides; k++) {
45
+ indices.push(baseCenter, baseStart + (k + 1) % sides, baseStart + k);
46
+ }
47
+ this.positions = positions;
48
+ this.normals = normals;
49
+ this.uv = uv;
50
+ this.indices = indices;
51
+ }
52
+ }
53
+ export {
54
+ Pyramid
55
+ }
@@ -0,0 +1,37 @@
1
+ class Sphere {
2
+ constructor(radius = 1, latBands = 24, longBands = 24) {
3
+ var positions = [];
4
+ var normals = [];
5
+ var uv = [];
6
+ var indices = [];
7
+ for (var lat = 0; lat <= latBands; lat++) {
8
+ var theta = (lat * Math.PI) / latBands;
9
+ var sinTheta = Math.sin(theta);
10
+ var cosTheta = Math.cos(theta);
11
+ for (var lon = 0; lon <= longBands; lon++) {
12
+ var phi = (lon * 2 * Math.PI) / longBands;
13
+ var x = Math.cos(phi) * sinTheta;
14
+ var y = cosTheta;
15
+ var z = Math.sin(phi) * sinTheta;
16
+ normals.push(x, y, z);
17
+ uv.push(1 - (lon / longBands), 1 - (lat / latBands));
18
+ positions.push(radius * x, radius * y, radius * z);
19
+ }
20
+ }
21
+ for (var lat = 0; lat < latBands; lat++) {
22
+ for (var lon = 0; lon < longBands; lon++) {
23
+ var first = (lat * (longBands + 1)) + lon;
24
+ var second = first + longBands + 1;
25
+ indices.push(first, first + 1, second);
26
+ indices.push(second, first + 1, second + 1);
27
+ }
28
+ }
29
+ this.positions = positions;
30
+ this.normals = normals;
31
+ this.uv = uv;
32
+ this.indices = indices;
33
+ }
34
+ }
35
+ export {
36
+ Sphere
37
+ };
@@ -0,0 +1,19 @@
1
+ import { GameLibCore } from "../../Core/index.js"
2
+ import { Box } from "./Box.js"
3
+ import { Sphere } from "./Sphere.js"
4
+ import { Cone } from "./Cone.js"
5
+ import { Pyramid } from "./Pyramid.js"
6
+ import { ModelLoaders } from "./ModelLoaders/index.js"
7
+ class Geometry {
8
+ constructor() {
9
+ throw new GameLibCore.Error("Class Geometry may not be constructed!");
10
+ }
11
+ static Box = Box;
12
+ static Sphere = Sphere;
13
+ static Cone = Cone;
14
+ static Pyramid = Pyramid;
15
+ static ModelLoaders = ModelLoaders;
16
+ }
17
+ export {
18
+ Geometry
19
+ }
@@ -0,0 +1,17 @@
1
+ import { Object } from "../Object.js"
2
+ import { Rotation } from "../Rotation.js"
3
+ class AmbientLight extends Object {
4
+ constructor(gameLib, scene, position, { color = [1.0, 1.0, 1.0], intensity = 1, direction = new Rotation(0, -1, 0), range = 10 }) {
5
+ super(gameLib, scene);
6
+ this.isLight = true;
7
+ this.type = "ambient";
8
+ this.position = position;
9
+ this.color = color;
10
+ this.intensity = intensity;
11
+ this.direction = direction;
12
+ this.range = range;
13
+ }
14
+ }
15
+ export {
16
+ AmbientLight
17
+ }
@@ -0,0 +1,17 @@
1
+ import { Object } from "../Object.js"
2
+ import { Rotation } from "../Rotation.js"
3
+ class DirectionalLight extends Object {
4
+ constructor(gameLib, scene, position, { color = [1.0, 1.0, 1.0], intensity = 1, direction = new Rotation(0, -1, 0), range = 10 }) {
5
+ super(gameLib, scene);
6
+ this.isLight = true;
7
+ this.type = "directional";
8
+ this.position = position;
9
+ this.color = color;
10
+ this.intensity = intensity;
11
+ this.direction = direction;
12
+ this.range = range;
13
+ }
14
+ }
15
+ export {
16
+ DirectionalLight
17
+ }
@@ -0,0 +1,17 @@
1
+ import { Object } from "../Object.js"
2
+ import { Rotation } from "../Rotation.js"
3
+ class PointLight extends Object {
4
+ constructor(gameLib, scene, position, { color = [1.0, 1.0, 1.0], intensity = 1, direction = new Rotation(0, -1, 0), range = 10 }) {
5
+ super(gameLib, scene);
6
+ this.isLight = true;
7
+ this.type = "point";
8
+ this.position = position;
9
+ this.color = color;
10
+ this.intensity = intensity;
11
+ this.direction = direction;
12
+ this.range = range;
13
+ }
14
+ }
15
+ export {
16
+ PointLight
17
+ }
@@ -0,0 +1,15 @@
1
+ import { GameLibCore } from "../../Core/index.js"
2
+ import { PointLight } from "./PointLight.js"
3
+ import { DirectionalLight } from "./DirectionalLight.js"
4
+ import { AmbientLight } from "./AmbientLight.js"
5
+ class Lighting {
6
+ constructor() {
7
+ throw new GameLibCore.Error("Class Lighting may not be constructed!");
8
+ }
9
+ static PointLight = PointLight;
10
+ static DirectionalLight = DirectionalLight;
11
+ static AmbientLight = AmbientLight;
12
+ }
13
+ export {
14
+ Lighting
15
+ }