@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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/dependabot.yml +6 -0
- package/.github/workflows/build.yml +54 -0
- package/.github/workflows/release.yml +79 -0
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/assets/test-frog.gltf +1921 -0
- package/assets/test-frog.gml +0 -0
- package/buildtime.txt +1 -0
- package/buildversion.txt +1 -0
- package/dist/GameLib.js +71599 -0
- package/dist/GameLib.min.js +8 -0
- package/docs/2D/API.md +1 -0
- package/docs/2D/GETTING_STARTED.md +1 -0
- package/docs/3D/API.md +1 -0
- package/docs/3D/GETTING_STARTED.md +23 -0
- package/docs/Core/API.md +1 -0
- package/docs/Core/GETTING_STARTED.md +1 -0
- package/docs/README.md +32 -0
- package/package.json +12 -13
- package/scripts/gltf2gml.html +312 -0
- package/src/2D/Box.js +42 -0
- package/src/2D/Coord.js +17 -0
- package/src/2D/GameLib.js +317 -0
- package/src/2D/Renderable.js +31 -0
- package/src/2D/Rotation.js +42 -0
- package/src/2D/Size.js +17 -0
- package/src/2D/Sprite.js +56 -0
- package/src/2D/UI/Button.js +52 -0
- package/src/2D/UI/TextInput.js +77 -0
- package/src/2D/UI/UIElement.js +10 -0
- package/src/2D/UI/index.js +15 -0
- package/src/2D/index.js +24 -0
- package/src/3D/Camera.js +25 -0
- package/src/3D/GameLib.js +202 -0
- package/src/3D/Geometry/Box.js +39 -0
- package/src/3D/Geometry/Cone.js +45 -0
- package/src/3D/Geometry/ModelLoaders/GLBLoader.js +12 -0
- package/src/3D/Geometry/ModelLoaders/GLTFLoader.js +12 -0
- package/src/3D/Geometry/ModelLoaders/GMLLoader.js +114 -0
- package/src/3D/Geometry/ModelLoaders/OBJLoader.js +12 -0
- package/src/3D/Geometry/ModelLoaders/index.js +17 -0
- package/src/3D/Geometry/Pyramid.js +55 -0
- package/src/3D/Geometry/Sphere.js +37 -0
- package/src/3D/Geometry/index.js +19 -0
- package/src/3D/Lighting/AmbientLight.js +17 -0
- package/src/3D/Lighting/DirectionalLight.js +17 -0
- package/src/3D/Lighting/PointLight.js +17 -0
- package/src/3D/Lighting/index.js +15 -0
- package/src/3D/Material.js +181 -0
- package/src/3D/Mesh.js +142 -0
- package/src/3D/Object.js +13 -0
- package/src/3D/Position.js +15 -0
- package/src/3D/Rotation.js +21 -0
- package/src/3D/Scale.js +10 -0
- package/src/3D/ShaderFactory/FunctionParam.js +14 -0
- package/src/3D/ShaderFactory/Modifiers/Variable.js +85 -0
- package/src/3D/ShaderFactory/Modifiers/index.js +11 -0
- package/src/3D/ShaderFactory/Node.js +25 -0
- package/src/3D/ShaderFactory/NodeTypes/A.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/Add.js +13 -0
- package/src/3D/ShaderFactory/NodeTypes/AssignVariable.js +11 -0
- package/src/3D/ShaderFactory/NodeTypes/Clamp.js +14 -0
- package/src/3D/ShaderFactory/NodeTypes/Constant.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/Define.js +11 -0
- package/src/3D/ShaderFactory/NodeTypes/Divide.js +13 -0
- package/src/3D/ShaderFactory/NodeTypes/Dot.js +14 -0
- package/src/3D/ShaderFactory/NodeTypes/Exp2.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/Function.js +36 -0
- package/src/3D/ShaderFactory/NodeTypes/Group.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/Header.js +12 -0
- package/src/3D/ShaderFactory/NodeTypes/Length.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/MainFunction.js +7 -0
- package/src/3D/ShaderFactory/NodeTypes/Max.js +14 -0
- package/src/3D/ShaderFactory/NodeTypes/Mix.js +14 -0
- package/src/3D/ShaderFactory/NodeTypes/Multiply.js +13 -0
- package/src/3D/ShaderFactory/NodeTypes/Negative.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/NodeTypes.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/Normalize.js +10 -0
- package/src/3D/ShaderFactory/NodeTypes/Precision.js +11 -0
- package/src/3D/ShaderFactory/NodeTypes/RGB.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/Subtract.js +13 -0
- package/src/3D/ShaderFactory/NodeTypes/Symbol.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/Texture2D.js +10 -0
- package/src/3D/ShaderFactory/NodeTypes/Variable.js +22 -0
- package/src/3D/ShaderFactory/NodeTypes/Vector.js +15 -0
- package/src/3D/ShaderFactory/NodeTypes/XYZ.js +9 -0
- package/src/3D/ShaderFactory/NodeTypes/index.js +32 -0
- package/src/3D/ShaderFactory/PrecisionTypes.js +8 -0
- package/src/3D/ShaderFactory/Program.js +41 -0
- package/src/3D/ShaderFactory/VariableTypes.js +49 -0
- package/src/3D/ShaderFactory/index.js +45 -0
- package/src/3D/Texture.js +59 -0
- package/src/3D/TextureFactory.js +22 -0
- package/src/3D/Transform.js +35 -0
- package/src/3D/UI/UIImage.js +24 -0
- package/src/3D/UI/UILoading.js +41 -0
- package/src/3D/UI/UIObject.js +16 -0
- package/src/3D/UI/UIPath.js +25 -0
- package/src/3D/UI/UIRenderer.js +207 -0
- package/src/3D/UI/UIText.js +35 -0
- package/src/3D/UI/index.js +19 -0
- package/src/3D/Utils.js +9 -0
- package/src/3D/index.js +43 -0
- package/src/Core/AssetManager.js +116 -0
- package/src/Core/AudioManager.js +151 -0
- package/src/Core/Error.js +9 -0
- package/src/Core/FullscreenManager.js +49 -0
- package/src/Core/GameLibBase.js +29 -0
- package/src/Core/InputManager.js +195 -0
- package/src/Core/Loading.js +111 -0
- package/src/Core/Matrix/index.js +11 -0
- package/src/Core/Matrix/mat4.js +178 -0
- package/src/Core/Multiplayer.js +54 -0
- package/src/Core/Network/PeerNetwork.js +410 -0
- package/src/Core/Network/index.js +11 -0
- package/src/Core/Storage.js +45 -0
- package/src/Core/Store.js +45 -0
- package/src/Core/Utils.js +34 -0
- package/src/Core/index.js +30 -0
- package/src/Lib/Ammo.js +72 -0
- package/src/Lib/Matter.js +1 -0
- package/src/Shaders/Material/Fragment/GL1.glsl +49 -0
- package/src/Shaders/Material/Fragment/GL2.glsl +51 -0
- package/src/Shaders/Material/Vertex/GL1.glsl +19 -0
- package/src/Shaders/Material/Vertex/GL2.glsl +20 -0
- package/src/Shaders/UI/Fragment/GL1.glsl +5 -0
- package/src/Shaders/UI/Fragment/GL2.glsl +7 -0
- package/src/Shaders/UI/Vertex/GL1.glsl +10 -0
- package/src/Shaders/UI/Vertex/GL2.glsl +11 -0
- package/src/Shaders/UITexture/Fragment/GL1.glsl +6 -0
- package/src/Shaders/UITexture/Fragment/GL2.glsl +8 -0
- package/src/Shaders/UITexture/Vertex/GL1.glsl +10 -0
- package/src/Shaders/UITexture/Vertex/GL2.glsl +11 -0
- 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
|
+
}
|