action-engine-js 1.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 (93) hide show
  1. package/LICENSE +45 -0
  2. package/README.md +348 -0
  3. package/actionengine/3rdparty/goblin/goblin.js +9609 -0
  4. package/actionengine/3rdparty/goblin/goblin.min.js +5 -0
  5. package/actionengine/camera/actioncamera.js +90 -0
  6. package/actionengine/camera/cameracollisionhandler.js +69 -0
  7. package/actionengine/character/actioncharacter.js +360 -0
  8. package/actionengine/character/actioncharacter3D.js +61 -0
  9. package/actionengine/core/app.js +430 -0
  10. package/actionengine/debug/basedebugpanel.js +858 -0
  11. package/actionengine/display/canvasmanager.js +75 -0
  12. package/actionengine/display/gl/programmanager.js +570 -0
  13. package/actionengine/display/gl/shaders/lineshader.js +118 -0
  14. package/actionengine/display/gl/shaders/objectshader.js +1756 -0
  15. package/actionengine/display/gl/shaders/particleshader.js +43 -0
  16. package/actionengine/display/gl/shaders/shadowshader.js +319 -0
  17. package/actionengine/display/gl/shaders/spriteshader.js +100 -0
  18. package/actionengine/display/gl/shaders/watershader.js +67 -0
  19. package/actionengine/display/graphics/actionmodel3D.js +191 -0
  20. package/actionengine/display/graphics/actionsprite3D.js +230 -0
  21. package/actionengine/display/graphics/lighting/actiondirectionalshadowlight.js +864 -0
  22. package/actionengine/display/graphics/lighting/actionlight.js +211 -0
  23. package/actionengine/display/graphics/lighting/actionomnidirectionalshadowlight.js +862 -0
  24. package/actionengine/display/graphics/lighting/lightingconstants.js +263 -0
  25. package/actionengine/display/graphics/lighting/lightmanager.js +789 -0
  26. package/actionengine/display/graphics/renderableobject.js +44 -0
  27. package/actionengine/display/graphics/renderers/actionrenderer2D.js +341 -0
  28. package/actionengine/display/graphics/renderers/actionrenderer3D/actionrenderer3D.js +655 -0
  29. package/actionengine/display/graphics/renderers/actionrenderer3D/canvasmanager3D.js +82 -0
  30. package/actionengine/display/graphics/renderers/actionrenderer3D/debugrenderer3D.js +493 -0
  31. package/actionengine/display/graphics/renderers/actionrenderer3D/objectrenderer3D.js +790 -0
  32. package/actionengine/display/graphics/renderers/actionrenderer3D/spriteRenderer3D.js +266 -0
  33. package/actionengine/display/graphics/renderers/actionrenderer3D/sunrenderer3D.js +140 -0
  34. package/actionengine/display/graphics/renderers/actionrenderer3D/waterrenderer3D.js +173 -0
  35. package/actionengine/display/graphics/renderers/actionrenderer3D/weatherrenderer3D.js +87 -0
  36. package/actionengine/display/graphics/texture/proceduraltexture.js +192 -0
  37. package/actionengine/display/graphics/texture/texturemanager.js +242 -0
  38. package/actionengine/display/graphics/texture/textureregistry.js +177 -0
  39. package/actionengine/input/actionscrollablearea.js +1405 -0
  40. package/actionengine/input/inputhandler.js +1647 -0
  41. package/actionengine/math/geometry/geometrybuilder.js +161 -0
  42. package/actionengine/math/geometry/glbexporter.js +364 -0
  43. package/actionengine/math/geometry/glbloader.js +722 -0
  44. package/actionengine/math/geometry/modelcodegenerator.js +97 -0
  45. package/actionengine/math/geometry/triangle.js +33 -0
  46. package/actionengine/math/geometry/triangleutils.js +34 -0
  47. package/actionengine/math/mathutils.js +25 -0
  48. package/actionengine/math/matrix4.js +785 -0
  49. package/actionengine/math/physics/actionphysics.js +108 -0
  50. package/actionengine/math/physics/actionphysicsobject3D.js +164 -0
  51. package/actionengine/math/physics/actionphysicsworld3D.js +238 -0
  52. package/actionengine/math/physics/actionraycast.js +129 -0
  53. package/actionengine/math/physics/shapes/actionphysicsbox3D.js +158 -0
  54. package/actionengine/math/physics/shapes/actionphysicscapsule3D.js +200 -0
  55. package/actionengine/math/physics/shapes/actionphysicscompoundshape3D.js +147 -0
  56. package/actionengine/math/physics/shapes/actionphysicscone3D.js +126 -0
  57. package/actionengine/math/physics/shapes/actionphysicsconvexshape3D.js +72 -0
  58. package/actionengine/math/physics/shapes/actionphysicscylinder3D.js +117 -0
  59. package/actionengine/math/physics/shapes/actionphysicsmesh3D.js +74 -0
  60. package/actionengine/math/physics/shapes/actionphysicsplane3D.js +100 -0
  61. package/actionengine/math/physics/shapes/actionphysicssphere3D.js +95 -0
  62. package/actionengine/math/quaternion.js +61 -0
  63. package/actionengine/math/vector2.js +277 -0
  64. package/actionengine/math/vector3.js +318 -0
  65. package/actionengine/math/viewfrustum.js +136 -0
  66. package/actionengine/network/ACTIONNETREADME.md +810 -0
  67. package/actionengine/network/client/ActionNetManager.js +802 -0
  68. package/actionengine/network/client/ActionNetManagerGUI.js +1709 -0
  69. package/actionengine/network/client/ActionNetManagerP2P.js +1537 -0
  70. package/actionengine/network/client/SyncSystem.js +422 -0
  71. package/actionengine/network/p2p/ActionNetPeer.js +142 -0
  72. package/actionengine/network/p2p/ActionNetTrackerClient.js +623 -0
  73. package/actionengine/network/p2p/DataConnection.js +282 -0
  74. package/actionengine/network/p2p/README.md +510 -0
  75. package/actionengine/network/p2p/example.html +502 -0
  76. package/actionengine/network/server/ActionNetServer.js +577 -0
  77. package/actionengine/network/server/ActionNetServerSSL.js +579 -0
  78. package/actionengine/network/server/ActionNetServerUtils.js +458 -0
  79. package/actionengine/network/server/SERVERREADME.md +314 -0
  80. package/actionengine/network/server/package-lock.json +35 -0
  81. package/actionengine/network/server/package.json +13 -0
  82. package/actionengine/network/server/start.bat +27 -0
  83. package/actionengine/network/server/start.sh +25 -0
  84. package/actionengine/network/server/startwss.bat +27 -0
  85. package/actionengine/sound/audiomanager.js +1589 -0
  86. package/actionengine/sound/soundfont/ACTIONSOUNDFONT_README.md +205 -0
  87. package/actionengine/sound/soundfont/actionparser.js +718 -0
  88. package/actionengine/sound/soundfont/actionreverb.js +252 -0
  89. package/actionengine/sound/soundfont/actionsoundfont.js +543 -0
  90. package/actionengine/sound/soundfont/sf2playerlicence.txt +29 -0
  91. package/actionengine/sound/soundfont/soundfont.js +2 -0
  92. package/dist/action-engine.min.js +328 -0
  93. package/package.json +35 -0
@@ -0,0 +1,360 @@
1
+ // game/character/basecharacter/actioncharacter.js
2
+
3
+ class ActionCharacter extends RenderableObject {
4
+ constructor(camera, game, position) {
5
+ super();
6
+
7
+ this.game = game;
8
+ this.camera = camera;
9
+
10
+ this.height = 6;
11
+ this.scale = 1;
12
+
13
+ this.isFirstPerson = false;
14
+ this.firstPersonHeight = this.height * 0.5;
15
+
16
+ this.basePosition = new Vector3(0, 0, 0); // Ground position
17
+ this.position = new Vector3(0, 40, 0); // Center position
18
+
19
+ this.facingDirection = new Vector3(0, 0, 1);
20
+ this.rotation = 0;
21
+
22
+ this.debugInfo = null;
23
+
24
+ // Camera properties
25
+ this.cameraDistance = 40;
26
+ this.cameraHeight = 10;
27
+ this.cameraPitch = 0;
28
+ this.cameraYaw = 0;
29
+
30
+ // Store pointer position for camera movment
31
+ this.lastPointerX = null;
32
+ this.lastPointerY = null;
33
+ this.swipeStartX = null;
34
+ this.swipeStartY = null;
35
+
36
+ // Create controller
37
+ this.controller = new Goblin.CharacterController(this.game.physicsWorld.getWorld());
38
+ // Get the character body from the controller
39
+ this.body = this.controller.body;
40
+
41
+ if(position){
42
+ this.body.position.set(position.x, position.y, position.z);
43
+ } else {
44
+ this.body.position.set(0, 500, 0);
45
+ }
46
+
47
+ // Add debug tracking
48
+ this.body.debugName = `CharacterBody_${Date.now()}`;
49
+ this.body.createdAt = Date.now();
50
+
51
+ // Get the character body from the controller
52
+ this.body = this.controller.body;
53
+
54
+ // Fine tune physics properties if needed
55
+ this.body.linear_damping = 0.01;
56
+ this.body.angular_damping = 0;
57
+ this.body.friction = 0;
58
+ this.body.restitution = 0.2;
59
+ const worldGravity = game.physicsWorld.getWorld().gravity;
60
+ const gravityMultiplier = 1;
61
+ this.body.setGravity(
62
+ worldGravity.x * gravityMultiplier,
63
+ worldGravity.y * gravityMultiplier,
64
+ worldGravity.z * gravityMultiplier
65
+ );
66
+ this.characterVisualYOffset = 0.75;
67
+ // Add character body to physics world
68
+ this.game.physicsWorld.getWorld().addRigidBody(this.body);
69
+ }
70
+
71
+ applyInput(input, deltaTime) {
72
+ if (input.isKeyJustPressed("Numpad0")) {
73
+ this.camera.isDetached = !this.camera.isDetached;
74
+ }
75
+ if (this.camera.isDetached) {
76
+ this.camera.handleDetachedInput(input, deltaTime);
77
+ return;
78
+ }
79
+
80
+ if (input.isKeyJustPressed("Action6")) {
81
+ this.isFirstPerson = !this.isFirstPerson;
82
+ }
83
+
84
+ // Handle pointer lock with Action7 (C key)
85
+ if (input.isKeyJustPressed("Action7")) {
86
+ if (document.pointerLockElement) {
87
+ document.exitPointerLock();
88
+ } else {
89
+ document.body.requestPointerLock();
90
+ }
91
+ }
92
+
93
+ // Update camera rotation based on pointer movement when locked
94
+ if (document.pointerLockElement) {
95
+ const mouseSensitivity = 0.01;
96
+ const movement = input.getLockedPointerMovement();
97
+
98
+ if (this.lastPointerX !== movement.x || this.lastPointerY !== movement.y) {
99
+ this.cameraYaw -= movement.x * mouseSensitivity;
100
+
101
+ if (this.isFirstPerson) {
102
+ this.cameraPitch += movement.y * mouseSensitivity;
103
+ } else {
104
+ this.cameraPitch -= movement.y * mouseSensitivity;
105
+ }
106
+
107
+ this.lastPointerX = movement.x;
108
+ this.lastPointerY = movement.y;
109
+ }
110
+
111
+ this.cameraPitch = Math.max(-1.57, Math.min(1.57, this.cameraPitch));
112
+ }
113
+
114
+ // Handle swipe camera control
115
+ if (!document.pointerLockElement) {
116
+ const pointerPos = input.getPointerPosition();
117
+
118
+ // Start tracking swipe
119
+ if (input.isPointerJustDown()) {
120
+ this.swipeStartX = pointerPos.x;
121
+ this.swipeStartY = pointerPos.y;
122
+ }
123
+
124
+ // Update camera during swipe
125
+ if (input.isPointerDown() && this.swipeStartX !== null) {
126
+ const deltaX = pointerPos.x - this.swipeStartX;
127
+ const deltaY = pointerPos.y - this.swipeStartY;
128
+
129
+ const swipeSensitivity = 0.005;
130
+ this.cameraYaw -= deltaX * swipeSensitivity;
131
+
132
+ if (this.isFirstPerson) {
133
+ this.cameraPitch += deltaY * swipeSensitivity;
134
+ } else {
135
+ this.cameraPitch -= deltaY * swipeSensitivity;
136
+ }
137
+
138
+ this.cameraPitch = Math.max(-1.57, Math.min(1.57, this.cameraPitch));
139
+
140
+ // Update start position for next frame
141
+ this.swipeStartX = pointerPos.x;
142
+ this.swipeStartY = pointerPos.y;
143
+ } else {
144
+ // Reset swipe tracking when pointer is released
145
+ this.swipeStartX = null;
146
+ this.swipeStartY = null;
147
+ }
148
+ }
149
+
150
+ // Get input direction relative to camera
151
+ const viewMatrix = this.camera.getViewMatrix();
152
+ const moveDir = new Goblin.Vector3();
153
+
154
+ // Track if we're moving this frame
155
+ let isMovingThisFrame = false;
156
+
157
+ // Get input direction relative to camera
158
+ if (input.isKeyPressed("DirUp")) {
159
+ moveDir.x += viewMatrix.forward.x;
160
+ moveDir.z += viewMatrix.forward.z;
161
+ isMovingThisFrame = true;
162
+ }
163
+ if (input.isKeyPressed("DirDown")) {
164
+ moveDir.x -= viewMatrix.forward.x;
165
+ moveDir.z -= viewMatrix.forward.z;
166
+ isMovingThisFrame = true;
167
+ }
168
+ if (input.isKeyPressed("DirRight")) {
169
+ moveDir.x += viewMatrix.right.x;
170
+ moveDir.z += viewMatrix.right.z;
171
+ isMovingThisFrame = true;
172
+ }
173
+ if (input.isKeyPressed("DirLeft")) {
174
+ moveDir.x -= viewMatrix.right.x;
175
+ moveDir.z -= viewMatrix.right.z;
176
+ isMovingThisFrame = true;
177
+ }
178
+
179
+ // Normalize the movement vector if moving diagonally
180
+ if (moveDir.lengthSquared() > 0) {
181
+ moveDir.normalize();
182
+ }
183
+
184
+ if (input.isKeyJustPressed("Action1")) {
185
+ this.controller.wishJump();
186
+ }
187
+ this.controller.handleInput(moveDir);
188
+
189
+ if (input.isKeyJustPressed("ActionDebugToggle")) {
190
+ console.log("Character Debug:", this.controller.getDebugInfo());
191
+ }
192
+ }
193
+
194
+ update(deltaTime) {
195
+ // Physics is now handled in fixed_update, only do non-physics updates here
196
+ }
197
+
198
+ fixed_update(fixedDeltaTime) {
199
+ // Physics and character controller updates should be handled in fixed timestep
200
+ this.controller.update(fixedDeltaTime);
201
+ if (this.body) {
202
+ const pos = this.body.position;
203
+
204
+ this.position.set(pos.x, pos.y, pos.z);
205
+ this.basePosition.set(this.position.x, this.position.y - this.size / 2, this.position.z);
206
+
207
+ // Use yaw for character facing
208
+ this.rotation = this.cameraYaw + Math.PI;
209
+
210
+ this.updateFacingDirection();
211
+
212
+ if (!this.camera.isDetached) {
213
+ // Initialize camera collision handler if needed
214
+ if (!this.cameraCollisionHandler && this.game && this.game.physicsWorld) {
215
+ this.cameraCollisionHandler = new CameraCollisionHandler(this.game.physicsWorld);
216
+ }
217
+
218
+ if (this.isFirstPerson) {
219
+ this.camera.position = this.position.add(new Vector3(0, this.firstPersonHeight, 0));
220
+
221
+ const lookDir = new Vector3(
222
+ Math.sin(this.cameraYaw + Math.PI) * Math.cos(this.cameraPitch),
223
+ -Math.sin(this.cameraPitch),
224
+ Math.cos(this.cameraYaw + Math.PI) * Math.cos(this.cameraPitch)
225
+ );
226
+ this.camera.target = this.camera.position.add(lookDir);
227
+ } else {
228
+ const cameraOffset = new Vector3(
229
+ Math.sin(this.cameraYaw) * Math.cos(this.cameraPitch) * this.cameraDistance,
230
+ -Math.sin(this.cameraPitch) * this.cameraDistance + this.cameraHeight,
231
+ Math.cos(this.cameraYaw) * Math.cos(this.cameraPitch) * this.cameraDistance
232
+ );
233
+
234
+ // Calculate desired camera position without collision
235
+ const desiredCameraPosition = this.position.add(cameraOffset);
236
+
237
+ // Apply camera collision if handler exists
238
+ if (this.cameraCollisionHandler) {
239
+ // Adjust camera position for collisions - no smoothing
240
+ this.camera.position = this.cameraCollisionHandler.adjustCameraPosition(
241
+ this.position,
242
+ desiredCameraPosition,
243
+ 1.6 // Camera collision radius
244
+ );
245
+ } else {
246
+ // Fall back to original behavior if no collision handler
247
+ this.camera.position = desiredCameraPosition;
248
+ }
249
+
250
+ this.camera.target = this.position.add(new Vector3(0, this.height / 2, 0));
251
+ }
252
+ }
253
+ }
254
+
255
+ // Store debug info
256
+ if (this.controller) {
257
+ this.debugInfo = this.controller.getDebugInfo();
258
+ }
259
+ }
260
+
261
+ // Standard method for renderable objects
262
+ updateVisual() {
263
+ this.triangles = this.getCharacterModelTriangles();
264
+ this.updateModelMatrix();
265
+ }
266
+
267
+ updateModelMatrix() {
268
+ // Calculate the model matrix based on position and facing direction
269
+ const angle = Math.atan2(this.facingDirection.x, this.facingDirection.z);
270
+ this.modelMatrix = Matrix4.create();
271
+
272
+ // Apply rotation around character's local origin first
273
+ Matrix4.rotateY(this.modelMatrix, this.modelMatrix, angle);
274
+
275
+ // Then translate to world position
276
+ Matrix4.translate(this.modelMatrix, this.modelMatrix, [this.position.x, this.position.y, this.position.z]);
277
+ }
278
+
279
+
280
+ // Original method - mainly used by 2d renderer
281
+ getCharacterModelTriangles() {
282
+ function transformVertexWithSkin(vertex, vertexIndex, triangle, skin) {
283
+ if (!triangle.jointData || !triangle.weightData) {
284
+ return vertex;
285
+ }
286
+
287
+ const finalPosition = new Vector3(0, 0, 0);
288
+ const joints = triangle.jointData[vertexIndex];
289
+ const weights = triangle.weightData[vertexIndex];
290
+ let totalWeight = 0;
291
+
292
+ for (let i = 0; i < 4; i++) {
293
+ const weight = weights[i];
294
+ if (weight > 0) {
295
+ totalWeight += weight;
296
+ const jointMatrix = skin.jointMatrices[joints[i]];
297
+ if (jointMatrix) {
298
+ const transformed = Vector3.transformMat4(vertex, jointMatrix);
299
+ finalPosition.x += transformed.x * weight;
300
+ finalPosition.y += transformed.y * weight;
301
+ finalPosition.z += transformed.z * weight;
302
+ }
303
+ }
304
+ }
305
+
306
+ if (totalWeight > 0 && Math.abs(totalWeight - 1.0) > 0.001) {
307
+ finalPosition.x /= totalWeight;
308
+ finalPosition.y /= totalWeight;
309
+ finalPosition.z /= totalWeight;
310
+ }
311
+
312
+ return finalPosition;
313
+ }
314
+
315
+ function applyTransform(vertex, transform) {
316
+ return Vector3.transformMat4(vertex, transform);
317
+ }
318
+
319
+ // Calculate model orientation transform based on facing direction
320
+ const angle = Math.atan2(this.facingDirection.x, this.facingDirection.z);
321
+ const modelTransform = Matrix4.create();
322
+
323
+ // Position the character at the correct world position
324
+ Matrix4.translate(modelTransform, modelTransform, [this.position.x, this.position.y + this.characterVisualYOffset, this.position.z]);
325
+
326
+ Matrix4.rotateY(modelTransform, modelTransform, angle);
327
+ const transformedTriangles = [];
328
+ const skin = this.characterModel.skins[0];
329
+
330
+ // Process each triangle in the model
331
+ for (const triangle of this.characterModel.triangles) {
332
+ // Apply skinning to each vertex
333
+ const skinnedVertices = [];
334
+ for (let i = 0; i < triangle.vertices.length; i++) {
335
+ skinnedVertices.push(transformVertexWithSkin(triangle.vertices[i], i, triangle, skin));
336
+ }
337
+
338
+ // Apply model transform to skinned vertices
339
+ const transformedVerts = [];
340
+ for (let i = 0; i < skinnedVertices.length; i++) {
341
+ transformedVerts.push(applyTransform(skinnedVertices[i], modelTransform));
342
+ }
343
+
344
+ // Create final transformed triangle
345
+ transformedTriangles.push(
346
+ new Triangle(transformedVerts[0], transformedVerts[1], transformedVerts[2], triangle.color)
347
+ );
348
+ }
349
+
350
+ return transformedTriangles;
351
+ }
352
+
353
+ updateFacingDirection() {
354
+ this.facingDirection = new Vector3(
355
+ Math.sin(this.rotation), // X component
356
+ 0, // Y component (flat on xz plane)
357
+ Math.cos(this.rotation) // Z component
358
+ );
359
+ }
360
+ }
@@ -0,0 +1,61 @@
1
+ // actionengine/character/actioncharacter3D.js
2
+
3
+ /*
4
+ * A basic character controller wrapper.
5
+ * It is based on GoblinPhysics spring based CharacterController.
6
+ */
7
+
8
+ class ActionCharacter3D extends ActionCharacter {
9
+ constructor(camera, game, position) {
10
+ super(camera, game, position);
11
+
12
+ // Set additional properties needed by the parent class
13
+ this.firstPersonHeight = this.height * 0.5;
14
+
15
+ // Create a capsule physics model
16
+ this.characterModel = new ActionPhysicsCapsule3D(
17
+ this.game.physicsWorld,
18
+ 2,
19
+ 6,
20
+ 0, // mass
21
+ new Vector3(0, 0, 0), // position
22
+ "#4488FF" // character color
23
+ );
24
+
25
+ console.log("[ActionCharacter3D] Initialized");
26
+ }
27
+
28
+ fixed_update(fixedDeltaTime) {
29
+ // Call parent's fixed_update for physics
30
+ super.fixed_update(fixedDeltaTime);
31
+ }
32
+
33
+ update(deltaTime) {
34
+ super.update(deltaTime);
35
+
36
+ // Update the visual representation to match the character controller
37
+ if (this.characterModel && this.body) {
38
+ // Copy position from character controller to our visual model
39
+ this.characterModel.body.position.x = this.body.position.x;
40
+ this.characterModel.body.position.y = this.body.position.y;
41
+ this.characterModel.body.position.z = this.body.position.z;
42
+
43
+ // Update capsule rotation based on character facing direction
44
+ const angle = Math.atan2(this.facingDirection.x, this.facingDirection.z);
45
+
46
+ // First create quaternion using ActionEngine's Quaternion class
47
+ const engineQuat = Quaternion.fromAxisAngle(new Vector3(0, 1, 0), angle);
48
+
49
+ // Directly set the rotation components on the body's rotation quaternion
50
+ this.characterModel.body.rotation.x = engineQuat.x;
51
+ this.characterModel.body.rotation.y = engineQuat.y;
52
+
53
+ // Mark the character model as dirty since we manually updated its position and rotation
54
+ if (typeof this.characterModel.markVisualDirty === 'function') {
55
+ this.characterModel.markVisualDirty();
56
+ }
57
+ this.characterModel.body.rotation.z = engineQuat.z;
58
+ this.characterModel.body.rotation.w = engineQuat.w;
59
+ }
60
+ }
61
+ }