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,282 @@
1
+ /**
2
+ * DataConnection - App Data Layer
3
+ *
4
+ * Standalone RTCPeerConnection for app data negotiation.
5
+ * Receives offer/answer/ICE candidates via signal() method.
6
+ * Emits 'data' events when data channel receives messages.
7
+ *
8
+ * USAGE:
9
+ * ```javascript
10
+ * const connection = new DataConnection({
11
+ * localPeerId: 'peer1',
12
+ * remotePeerId: 'peer2'
13
+ * });
14
+ *
15
+ * // Handle tracker messages
16
+ * connection.signal(offerFromTracker);
17
+ * connection.signal(answerFromTracker);
18
+ * connection.signal(iceCandidate);
19
+ *
20
+ * connection.on('connect', () => {
21
+ * connection.send({ type: 'greeting' });
22
+ * });
23
+ * ```
24
+ */
25
+
26
+ class DataConnection {
27
+ constructor(options = {}) {
28
+ this.pc = null;
29
+ this.dataChannel = null;
30
+ this.handlers = new Map();
31
+
32
+ // Store peer IDs
33
+ this.localPeerId = options.localPeerId;
34
+ this.remotePeerId = options.remotePeerId;
35
+
36
+ // Store ICE servers
37
+ this.iceServers = options.iceServers || [
38
+ { urls: 'stun:stun.l.google.com:19302' },
39
+ { urls: 'stun:stun1.l.google.com:19302' }
40
+ ];
41
+
42
+ // Determine initiator: either explicitly set or by peer ID comparison
43
+ if (options.initiator !== undefined) {
44
+ this.isInitiator = options.initiator;
45
+ } else {
46
+ this.isInitiator = options.localPeerId > options.remotePeerId;
47
+ }
48
+
49
+ this.connected = false;
50
+ this.ready = false;
51
+
52
+ this._setup();
53
+ }
54
+
55
+ /**
56
+ * Setup DataConnection with standalone RTCPeerConnection
57
+ */
58
+ _setup() {
59
+ // Create RTCPeerConnection for app data channel
60
+ this.pc = new RTCPeerConnection({
61
+ iceServers: this.iceServers
62
+ });
63
+
64
+ // Listen for ICE candidates
65
+ this.pc.onicecandidate = (evt) => {
66
+ if (evt.candidate) {
67
+ // Emit ICE candidate so caller can relay it
68
+ this.emit('signal', {
69
+ type: 'ice-candidate',
70
+ candidate: evt.candidate
71
+ });
72
+ }
73
+ };
74
+
75
+ // Listen for remote data channel
76
+ this.pc.ondatachannel = (evt) => {
77
+ this.dataChannel = evt.channel;
78
+ this._setupDataChannel();
79
+ };
80
+
81
+ // If initiator, create offer
82
+ if (this.isInitiator) {
83
+ this._createOffer();
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Create and send offer
89
+ */
90
+ async _createOffer() {
91
+ try {
92
+ // Create data channel
93
+ const channel = this.pc.createDataChannel('app', { ordered: true });
94
+ this.dataChannel = channel;
95
+ this._setupDataChannel();
96
+
97
+ // Create offer
98
+ const offer = await this.pc.createOffer();
99
+ await this.pc.setLocalDescription(offer);
100
+
101
+ // Wait for ICE gathering to complete
102
+ await new Promise((resolve) => {
103
+ if (this.pc.iceGatheringState === 'complete') {
104
+ resolve();
105
+ return;
106
+ }
107
+
108
+ const checkComplete = () => {
109
+ if (this.pc.iceGatheringState === 'complete') {
110
+ this.pc.removeEventListener('icegatheringstatechange', checkComplete);
111
+ resolve();
112
+ }
113
+ };
114
+
115
+ this.pc.addEventListener('icegatheringstatechange', checkComplete);
116
+
117
+ // Fallback timeout
118
+ setTimeout(() => {
119
+ this.pc.removeEventListener('icegatheringstatechange', checkComplete);
120
+ resolve();
121
+ }, 3000);
122
+ });
123
+
124
+ // Emit offer
125
+ this.emit('signal', {
126
+ type: 'offer',
127
+ sdp: this.pc.localDescription.sdp
128
+ });
129
+
130
+ this.ready = true;
131
+ } catch (e) {
132
+ this.emit('error', e);
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Handle incoming offer/answer/ICE from caller
138
+ */
139
+ signal(data) {
140
+ if (!this.pc) return;
141
+
142
+ if (data.type === 'offer') {
143
+ // Responder receives offer
144
+ this._handleOffer(data);
145
+ } else if (data.type === 'answer') {
146
+ // Initiator receives answer
147
+ this.pc.setRemoteDescription({ type: 'answer', sdp: data.sdp })
148
+ .catch((error) => {
149
+ this.emit('error', new Error(`Failed to set remote answer: ${error.message}`));
150
+ });
151
+ } else if (data.candidate) {
152
+ // ICE candidate
153
+ this.pc.addIceCandidate(new RTCIceCandidate(data.candidate))
154
+ .catch((e) => {
155
+ console.debug('[DataConnection] ICE candidate error (non-fatal):', e.message);
156
+ });
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Handle incoming offer (responder side)
162
+ */
163
+ async _handleOffer(data) {
164
+ try {
165
+ await this.pc.setRemoteDescription({ type: 'offer', sdp: data.sdp });
166
+
167
+ const answer = await this.pc.createAnswer();
168
+ await this.pc.setLocalDescription(answer);
169
+
170
+ // Wait for ICE gathering to complete
171
+ await new Promise((resolve) => {
172
+ if (this.pc.iceGatheringState === 'complete') {
173
+ resolve();
174
+ return;
175
+ }
176
+
177
+ const checkComplete = () => {
178
+ if (this.pc.iceGatheringState === 'complete') {
179
+ this.pc.removeEventListener('icegatheringstatechange', checkComplete);
180
+ resolve();
181
+ }
182
+ };
183
+
184
+ this.pc.addEventListener('icegatheringstatechange', checkComplete);
185
+
186
+ // Fallback timeout
187
+ setTimeout(() => {
188
+ this.pc.removeEventListener('icegatheringstatechange', checkComplete);
189
+ resolve();
190
+ }, 3000);
191
+ });
192
+
193
+ // Emit answer
194
+ this.emit('signal', {
195
+ type: 'answer',
196
+ sdp: this.pc.localDescription.sdp
197
+ });
198
+
199
+ this.ready = true;
200
+ } catch (e) {
201
+ this.emit('error', e);
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Setup data channel handlers
207
+ */
208
+ _setupDataChannel() {
209
+ this.dataChannel.onopen = () => {
210
+ this.connected = true;
211
+ this.emit('connect');
212
+ };
213
+
214
+ this.dataChannel.onclose = () => {
215
+ this.connected = false;
216
+ this.emit('close');
217
+ };
218
+
219
+ this.dataChannel.onerror = (evt) => {
220
+ this.emit('error', evt.error);
221
+ };
222
+
223
+ this.dataChannel.onmessage = (evt) => {
224
+ try {
225
+ const message = JSON.parse(evt.data);
226
+ this.emit('data', message);
227
+ } catch (e) {
228
+ // Non-JSON messages are ignored
229
+ }
230
+ };
231
+ }
232
+
233
+ /**
234
+ * Send a message through the data channel
235
+ */
236
+ send(message) {
237
+ if (!this.connected || !this.dataChannel || this.dataChannel.readyState !== 'open') {
238
+ return false;
239
+ }
240
+
241
+ try {
242
+ this.dataChannel.send(JSON.stringify(message));
243
+ return true;
244
+ } catch (e) {
245
+ return false;
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Event handling
251
+ */
252
+ on(event, handler) {
253
+ if (!this.handlers.has(event)) {
254
+ this.handlers.set(event, []);
255
+ }
256
+ this.handlers.get(event).push(handler);
257
+ }
258
+
259
+ emit(event, ...args) {
260
+ if (!this.handlers.has(event)) return;
261
+ for (const handler of this.handlers.get(event)) {
262
+ try {
263
+ handler(...args);
264
+ } catch (e) {
265
+ console.error(`[DataConnection] Error in ${event} handler:`, e);
266
+ }
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Cleanup
272
+ */
273
+ close() {
274
+ if (this.dataChannel) {
275
+ this.dataChannel.close();
276
+ }
277
+ if (this.pc) {
278
+ this.pc.close();
279
+ }
280
+ this.connected = false;
281
+ }
282
+ }