@gg-web-engine/core 0.0.1

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 (181) hide show
  1. package/.prettierrc +8 -0
  2. package/README.md +8 -0
  3. package/blender_exporter/build_blender_scene.py +180 -0
  4. package/blender_exporter/spherical_to_cube_texture.py +116 -0
  5. package/dist/2d/entities/gg-2d-entity.d.ts +20 -0
  6. package/dist/2d/entities/gg-2d-entity.js +84 -0
  7. package/dist/2d/entities/gg-2d-trigger.entity.d.ts +10 -0
  8. package/dist/2d/entities/gg-2d-trigger.entity.js +17 -0
  9. package/dist/2d/entities/gg-positionable-2d-entity.d.ts +7 -0
  10. package/dist/2d/entities/gg-positionable-2d-entity.js +16 -0
  11. package/dist/2d/factories.d.ts +18 -0
  12. package/dist/2d/factories.js +13 -0
  13. package/dist/2d/gg-2d-world.d.ts +9 -0
  14. package/dist/2d/gg-2d-world.js +34 -0
  15. package/dist/2d/interfaces.d.ts +26 -0
  16. package/dist/2d/interfaces.js +7 -0
  17. package/dist/2d/models/body-options.d.ts +3 -0
  18. package/dist/2d/models/body-options.js +2 -0
  19. package/dist/2d/models/shapes.d.ts +13 -0
  20. package/dist/2d/models/shapes.js +2 -0
  21. package/dist/3d/controllers/car-keyboard.controller.d.ts +25 -0
  22. package/dist/3d/controllers/car-keyboard.controller.js +98 -0
  23. package/dist/3d/controllers/free-camera.controller.d.ts +23 -0
  24. package/dist/3d/controllers/free-camera.controller.js +79 -0
  25. package/dist/3d/entities/controllers/entity-motion.controller.d.ts +32 -0
  26. package/dist/3d/entities/controllers/entity-motion.controller.js +100 -0
  27. package/dist/3d/entities/gg-3d-camera.entity.d.ts +7 -0
  28. package/dist/3d/entities/gg-3d-camera.entity.js +12 -0
  29. package/dist/3d/entities/gg-3d-entity.d.ts +25 -0
  30. package/dist/3d/entities/gg-3d-entity.js +108 -0
  31. package/dist/3d/entities/gg-3d-map-graph.entity.d.ts +51 -0
  32. package/dist/3d/entities/gg-3d-map-graph.entity.js +164 -0
  33. package/dist/3d/entities/gg-3d-raycast-vehicle.entity.d.ts +107 -0
  34. package/dist/3d/entities/gg-3d-raycast-vehicle.entity.js +372 -0
  35. package/dist/3d/entities/gg-3d-trigger.entity.d.ts +10 -0
  36. package/dist/3d/entities/gg-3d-trigger.entity.js +21 -0
  37. package/dist/3d/entities/gg-positionable-3d-entity.d.ts +11 -0
  38. package/dist/3d/entities/gg-positionable-3d-entity.js +27 -0
  39. package/dist/3d/factories.d.ts +21 -0
  40. package/dist/3d/factories.js +22 -0
  41. package/dist/3d/gg-3d-world.d.ts +11 -0
  42. package/dist/3d/gg-3d-world.js +36 -0
  43. package/dist/3d/interfaces.d.ts +65 -0
  44. package/dist/3d/interfaces.js +40 -0
  45. package/dist/3d/loader.d.ts +40 -0
  46. package/dist/3d/loader.js +129 -0
  47. package/dist/3d/models/body-options.d.ts +3 -0
  48. package/dist/3d/models/body-options.js +2 -0
  49. package/dist/3d/models/gg-meta.d.ts +22 -0
  50. package/dist/3d/models/gg-meta.js +2 -0
  51. package/dist/3d/models/shapes.d.ts +35 -0
  52. package/dist/3d/models/shapes.js +2 -0
  53. package/dist/base/clock.d.ts +26 -0
  54. package/dist/base/clock.js +82 -0
  55. package/dist/base/controllers/common.d.ts +8 -0
  56. package/dist/base/controllers/common.js +32 -0
  57. package/dist/base/controllers/i-controller.d.ts +4 -0
  58. package/dist/base/controllers/i-controller.js +2 -0
  59. package/dist/base/controllers/keyboard.controller.d.ts +16 -0
  60. package/dist/base/controllers/keyboard.controller.js +109 -0
  61. package/dist/base/controllers/mouse.controller.d.ts +24 -0
  62. package/dist/base/controllers/mouse.controller.js +68 -0
  63. package/dist/base/data-structures/graph.d.ts +20 -0
  64. package/dist/base/data-structures/graph.js +118 -0
  65. package/dist/base/entities/base-gg-renderer.d.ts +28 -0
  66. package/dist/base/entities/base-gg-renderer.js +49 -0
  67. package/dist/base/entities/gg-entity.d.ts +14 -0
  68. package/dist/base/entities/gg-entity.js +55 -0
  69. package/dist/base/entities/gg-positionable-entity.d.ts +23 -0
  70. package/dist/base/entities/gg-positionable-entity.js +47 -0
  71. package/dist/base/entities/inline-controller.d.ts +3 -0
  72. package/dist/base/entities/inline-controller.js +25 -0
  73. package/dist/base/entities/interfaces/i-tick-listener.d.ts +7 -0
  74. package/dist/base/entities/interfaces/i-tick-listener.js +6 -0
  75. package/dist/base/gg-static.d.ts +9 -0
  76. package/dist/base/gg-static.js +40 -0
  77. package/dist/base/gg-viewport-manager.d.ts +14 -0
  78. package/dist/base/gg-viewport-manager.js +125 -0
  79. package/dist/base/gg-viewport.d.ts +23 -0
  80. package/dist/base/gg-viewport.js +123 -0
  81. package/dist/base/gg-world.d.ts +32 -0
  82. package/dist/base/gg-world.js +172 -0
  83. package/dist/base/interfaces/gg-body.d.ts +15 -0
  84. package/dist/base/interfaces/gg-body.js +2 -0
  85. package/dist/base/interfaces/gg-debug-physics-drawer.d.ts +7 -0
  86. package/dist/base/interfaces/gg-debug-physics-drawer.js +2 -0
  87. package/dist/base/interfaces/gg-object.d.ts +16 -0
  88. package/dist/base/interfaces/gg-object.js +2 -0
  89. package/dist/base/interfaces/gg-physics-world.d.ts +18 -0
  90. package/dist/base/interfaces/gg-physics-world.js +2 -0
  91. package/dist/base/interfaces/gg-trigger.d.ts +8 -0
  92. package/dist/base/interfaces/gg-trigger.js +2 -0
  93. package/dist/base/interfaces/gg-visual-scene.d.ts +9 -0
  94. package/dist/base/interfaces/gg-visual-scene.js +2 -0
  95. package/dist/base/math/box.d.ts +5 -0
  96. package/dist/base/math/box.js +21 -0
  97. package/dist/base/math/matrix4.d.ts +5 -0
  98. package/dist/base/math/matrix4.js +33 -0
  99. package/dist/base/math/numbers.d.ts +2 -0
  100. package/dist/base/math/numbers.js +14 -0
  101. package/dist/base/math/point2.d.ts +15 -0
  102. package/dist/base/math/point2.js +40 -0
  103. package/dist/base/math/point3.d.ts +25 -0
  104. package/dist/base/math/point3.js +104 -0
  105. package/dist/base/math/quaternion.d.ts +28 -0
  106. package/dist/base/math/quaternion.js +145 -0
  107. package/dist/base/models/axis-directions.d.ts +3 -0
  108. package/dist/base/models/axis-directions.js +2 -0
  109. package/dist/base/models/body-options.d.ts +6 -0
  110. package/dist/base/models/body-options.js +2 -0
  111. package/dist/base/models/geometry-nodes.d.ts +7 -0
  112. package/dist/base/models/geometry-nodes.js +2 -0
  113. package/dist/base/models/points.d.ts +15 -0
  114. package/dist/base/models/points.js +2 -0
  115. package/dist/base/ui/gg-console.ui.d.ts +21 -0
  116. package/dist/base/ui/gg-console.ui.js +162 -0
  117. package/dist/base/ui/gg-debugger.ui.d.ts +10 -0
  118. package/dist/base/ui/gg-debugger.ui.js +68 -0
  119. package/dist/index.d.ts +51 -0
  120. package/dist/index.js +67 -0
  121. package/package.json +64 -0
  122. package/src/2d/entities/gg-2d-entity.ts +86 -0
  123. package/src/2d/entities/gg-2d-trigger.entity.ts +17 -0
  124. package/src/2d/entities/gg-positionable-2d-entity.ts +16 -0
  125. package/src/2d/factories.ts +20 -0
  126. package/src/2d/gg-2d-world.ts +32 -0
  127. package/src/2d/interfaces.ts +31 -0
  128. package/src/2d/models/body-options.ts +3 -0
  129. package/src/2d/models/shapes.ts +7 -0
  130. package/src/3d/controllers/car-keyboard.controller.ts +128 -0
  131. package/src/3d/controllers/free-camera.controller.ts +86 -0
  132. package/src/3d/entities/controllers/entity-motion.controller.ts +122 -0
  133. package/src/3d/entities/gg-3d-camera.entity.ts +8 -0
  134. package/src/3d/entities/gg-3d-entity.ts +116 -0
  135. package/src/3d/entities/gg-3d-map-graph.entity.ts +204 -0
  136. package/src/3d/entities/gg-3d-raycast-vehicle.entity.ts +468 -0
  137. package/src/3d/entities/gg-3d-trigger.entity.ts +22 -0
  138. package/src/3d/entities/gg-positionable-3d-entity.ts +31 -0
  139. package/src/3d/factories.ts +29 -0
  140. package/src/3d/gg-3d-world.ts +36 -0
  141. package/src/3d/interfaces.ts +96 -0
  142. package/src/3d/loader.ts +165 -0
  143. package/src/3d/models/body-options.ts +3 -0
  144. package/src/3d/models/gg-meta.ts +12 -0
  145. package/src/3d/models/shapes.ts +13 -0
  146. package/src/base/clock.ts +97 -0
  147. package/src/base/controllers/common.ts +37 -0
  148. package/src/base/controllers/i-controller.ts +5 -0
  149. package/src/base/controllers/keyboard.controller.ts +109 -0
  150. package/src/base/controllers/mouse.controller.ts +73 -0
  151. package/src/base/data-structures/graph.ts +125 -0
  152. package/src/base/entities/base-gg-renderer.ts +77 -0
  153. package/src/base/entities/gg-entity.ts +61 -0
  154. package/src/base/entities/gg-positionable-entity.ts +64 -0
  155. package/src/base/entities/inline-controller.ts +31 -0
  156. package/src/base/entities/interfaces/i-tick-listener.ts +15 -0
  157. package/src/base/gg-static.ts +30 -0
  158. package/src/base/gg-viewport-manager.ts +122 -0
  159. package/src/base/gg-viewport.ts +159 -0
  160. package/src/base/gg-world.ts +198 -0
  161. package/src/base/interfaces/gg-body.ts +23 -0
  162. package/src/base/interfaces/gg-debug-physics-drawer.ts +10 -0
  163. package/src/base/interfaces/gg-object.ts +26 -0
  164. package/src/base/interfaces/gg-physics-world.ts +24 -0
  165. package/src/base/interfaces/gg-trigger.ts +10 -0
  166. package/src/base/interfaces/gg-visual-scene.ts +11 -0
  167. package/src/base/math/box.ts +19 -0
  168. package/src/base/math/matrix4.ts +29 -0
  169. package/src/base/math/numbers.ts +10 -0
  170. package/src/base/math/point2.ts +43 -0
  171. package/src/base/math/point3.ts +119 -0
  172. package/src/base/math/quaternion.ts +172 -0
  173. package/src/base/models/axis-directions.ts +3 -0
  174. package/src/base/models/body-options.ts +6 -0
  175. package/src/base/models/geometry-nodes.ts +5 -0
  176. package/src/base/models/points.ts +3 -0
  177. package/src/base/ui/gg-console.ui.ts +165 -0
  178. package/src/base/ui/gg-debugger.ui.ts +69 -0
  179. package/src/index.ts +53 -0
  180. package/test/base/data-structures/graph.spec.ts +76 -0
  181. package/tsconfig.json +9 -0
package/.prettierrc ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "semi": true,
3
+ "trailingComma": "all",
4
+ "singleQuote": true,
5
+ "bracketSameLine":true,
6
+ "printWidth": 120,
7
+ "arrowParens": "avoid"
8
+ }
package/README.md ADDED
@@ -0,0 +1,8 @@
1
+ <p align="center">
2
+ <img src="../../documentation/assets/logo.png" style="height: 400px; width:400px;" alt=''/>
3
+ </p>
4
+
5
+ ## Core package for [gg-web-engine](https://github.com/AndyGura/gg-web-engine)
6
+
7
+ ### Installation:
8
+ 1) `npm install --save @gg-web-engine/core`
@@ -0,0 +1,180 @@
1
+ import os
2
+ import sys
3
+ import tempfile
4
+
5
+ from string import Template
6
+
7
+ __blender_script_template = Template("""
8
+ import bpy
9
+ import json
10
+ import os
11
+ from rna_prop_ui import rna_idprop_value_to_python
12
+
13
+
14
+ def parse_curve_obj(object):
15
+ curve = bpy.data.curves[object.data.name]
16
+ spline = curve.splines[0]
17
+ is_cyclic = spline.use_cyclic_u
18
+ points = list(map(lambda p: {
19
+ "x": p.co.x + object.location.x,
20
+ "y": p.co.y + object.location.y,
21
+ "z": p.co.z + object.location.z
22
+ }, spline.points))
23
+ return {
24
+ "name": object.name,
25
+ "cyclic": is_cyclic,
26
+ "points": points,
27
+ **{x: rna_idprop_value_to_python(object[x]) for x in object.keys() if x != '_RNA_UI'}
28
+ }
29
+
30
+ def parse_dummy_obj(object):
31
+ object.rotation_mode = 'QUATERNION'
32
+ return {
33
+ "name": object.name,
34
+ "position": {
35
+ "x": object.location.x,
36
+ "y": object.location.y,
37
+ "z": object.location.z,
38
+ },
39
+ "rotation": {
40
+ "x": object.rotation_quaternion.x,
41
+ "y": object.rotation_quaternion.y,
42
+ "z": object.rotation_quaternion.z,
43
+ "w": object.rotation_quaternion.w,
44
+ },
45
+ **{x: object[x] for x in object.keys() if x != '_RNA_UI'}
46
+ }
47
+
48
+ def get_rigid_body_description(obj, export_body_parameters=True):
49
+ body = obj.rigid_body
50
+ obj.rotation_mode = 'QUATERNION'
51
+ meta = {
52
+ "name": obj.name,
53
+ "position": {
54
+ 'x': obj.location.x,
55
+ 'y': obj.location.y,
56
+ 'z': obj.location.z,
57
+ },
58
+ # FIXME relative rotation
59
+ "rotation": { 'x': obj.rotation_quaternion.x, 'y': obj.rotation_quaternion.y, 'z': obj.rotation_quaternion.z, 'w': obj.rotation_quaternion.w },
60
+ "shape": {
61
+ "shape": body.collision_shape,
62
+ },
63
+ }
64
+ if (export_body_parameters):
65
+ meta['body'] = {
66
+ "dynamic": body.type == "ACTIVE",
67
+ "mass": body.mass,
68
+ "restitution": body.restitution,
69
+ "friction": body.friction,
70
+ }
71
+ parent = obj.parent
72
+ while parent:
73
+ meta['position']['x'] -= parent.location.x
74
+ meta['position']['y'] -= parent.location.y
75
+ meta['position']['z'] -= parent.location.z
76
+ parent = parent.parent
77
+ meta['position']['x'] = round(meta['position']['x'], 6)
78
+ meta['position']['y'] = round(meta['position']['y'], 6)
79
+ meta['position']['z'] = round(meta['position']['z'], 6)
80
+ if meta['shape']['shape'] == 'SPHERE':
81
+ meta['shape']['radius'] = max(obj.dimensions.x, obj.dimensions.y, obj.dimensions.z) / 2
82
+ elif meta['shape']['shape'] == 'BOX':
83
+ meta['shape']['dimensions'] = { 'x': obj.dimensions.x, 'y': obj.dimensions.y, 'z': obj.dimensions.z }
84
+ elif meta['shape']['shape'] in ['CONE', 'CYLINDER']:
85
+ meta['shape']['radius'] = max(obj.dimensions.x, obj.dimensions.y) / 2
86
+ meta['shape']['height'] = obj.dimensions.z
87
+ elif meta['shape']['shape'] == 'CAPSULE':
88
+ meta['shape']['radius'] = max(obj.dimensions.x, obj.dimensions.y) / 2
89
+ meta['shape']['centersDistance'] = obj.dimensions.z - max(obj.dimensions.x, obj.dimensions.y)
90
+ elif meta['shape']['shape'] == 'CONVEX_HULL':
91
+ meta['shape']['vertices'] = [{ 'x': v.co.x, 'y': v.co.y, 'z': v.co.z } for v in obj.data.vertices]
92
+ elif meta['shape']['shape'] == 'MESH':
93
+ meta['shape']['vertices'] = [{ 'x': v.co.x, 'y': v.co.y, 'z': v.co.z } for v in obj.data.vertices]
94
+ import bmesh
95
+ bm = bmesh.new()
96
+ bm.from_mesh(obj.data)
97
+ bmesh.ops.triangulate(bm, faces=bm.faces[:])
98
+ meta['shape']['faces'] = [[v.index for v in f.verts] for f in bm.faces]
99
+ bm.free()
100
+ elif meta['shape']['shape'] == 'COMPOUND':
101
+ meta['shape']['children'] = [get_rigid_body_description(sub_obj, export_body_parameters=False)
102
+ for sub_obj in bpy.context.scene.objects
103
+ if sub_obj.rigid_body is not None and sub_obj.parent == obj]
104
+ else:
105
+ raise NotImplementedError(f'GG does not support exporting rigid body {meta["shape"]["shape"]} shape')
106
+ return meta
107
+
108
+ if "$src_file":
109
+ bpy.ops.wm.open_mainfile(filepath="$src_file")
110
+
111
+ # compound metadata
112
+ metadata = {"curves": [], "dummies": [], "rigidBodies": []}
113
+ for obj in filter(lambda x: x.type == "CURVE", bpy.data.objects):
114
+ metadata["curves"].append(parse_curve_obj(obj))
115
+ for obj in filter(lambda x: x.type == "EMPTY", bpy.data.objects):
116
+ metadata["dummies"].append(parse_dummy_obj(obj))
117
+
118
+ # saving scene
119
+ for obj in bpy.context.scene.objects:
120
+ include_in_export = obj.type in ["MESH", "LIGHT", "CURVE"]
121
+ include_in_glb = not obj.hide_render
122
+ obj.select_set(state=include_in_export and include_in_glb)
123
+ if not include_in_export:
124
+ continue
125
+ for modifier in obj.modifiers:
126
+ bpy.ops.object.modifier_apply(modifier=modifier.name)
127
+ if obj.rigid_body is not None and (obj.parent is None or obj.parent.rigid_body is None or obj.parent.rigid_body.collision_shape != 'COMPOUND'):
128
+ metadata["rigidBodies"].append(get_rigid_body_description(obj))
129
+
130
+ bpy.ops.export_scene.gltf(export_format="GLB",
131
+ export_copyright="Gurakl Games",
132
+ export_texcoords=True,
133
+ export_normals=True,
134
+ export_tangents=True,
135
+ export_materials='$export_materials',
136
+ export_colors=True,
137
+ export_cameras=False,
138
+ export_lights=True,
139
+ export_extras=True,
140
+ export_yup=False,
141
+ export_apply=False,
142
+ export_animations=False,
143
+ use_selection=True,
144
+ export_skins=False,
145
+ export_morph=False,
146
+ filepath="$file_name.glb")
147
+ # saving metadata
148
+ with open("$file_name.meta", 'w') as outfile:
149
+ json.dump(metadata, outfile)""")
150
+
151
+
152
+ def construct_blender_export_script(file_name, src_file="", export_materials="EXPORT") -> str:
153
+ return __blender_script_template.substitute({
154
+ 'src_file': src_file,
155
+ 'file_name': file_name,
156
+ 'export_materials': export_materials
157
+ })
158
+
159
+ if __name__ == "__main__":
160
+ # will be invoked if this module is being run directly, but not via import
161
+ skip_textures = sys.argv[1] == '--skip-textures'
162
+ if skip_textures:
163
+ files = sys.argv[2:]
164
+ else:
165
+ files = sys.argv[1:]
166
+
167
+ script = ""
168
+ for file in files:
169
+ if file.startswith('./'):
170
+ file = file[2:]
171
+ full_path = os.path.join(os.getcwd(), file)
172
+ script += '\n\n\n' + construct_blender_export_script(src_file=full_path,
173
+ file_name=full_path[:full_path.rindex('.')],
174
+ export_materials="NONE" if skip_textures else "EXPORT")
175
+
176
+ script_file = tempfile.NamedTemporaryFile(delete=False, mode='w')
177
+ script_file.write(script)
178
+ script_file.flush()
179
+ os.system(f"blender --python {script_file.name} --background")
180
+ os.unlink(script_file.name)
@@ -0,0 +1,116 @@
1
+ import sys
2
+ from math import pi, atan2, hypot, floor, ceil
3
+
4
+ from PIL import Image
5
+ from numpy import clip, average
6
+
7
+
8
+ # get x,y,z coords from out image pixels coords
9
+ # i,j are pixel coords
10
+ # face is face number
11
+ # edge is edge length
12
+ def outImgToXYZ(i, j, face, edge):
13
+ a = 2.0 * float(i) / edge
14
+ b = 2.0 * float(j) / edge
15
+ if face == 0: # back
16
+ (x, y, z) = (-1.0, 1.0 - a, 3.0 - b)
17
+ elif face == 1: # left
18
+ (x, y, z) = (a - 3.0, -1.0, 3.0 - b)
19
+ elif face == 2: # front
20
+ (x, y, z) = (1.0, a - 5.0, 3.0 - b)
21
+ elif face == 3: # right
22
+ (x, y, z) = (7.0 - a, 1.0, 3.0 - b)
23
+ elif face == 4: # top
24
+ (x, y, z) = (b - 1.0, a - 5.0, 1.0)
25
+ elif face == 5: # bottom
26
+ (x, y, z) = (5.0 - b, a - 5.0, -1.0)
27
+ return (x, y, z)
28
+
29
+
30
+ # convert using an inverse transformation
31
+ def convertBack(imgIn, imgOut):
32
+ inSize = imgIn.size
33
+ outSize = imgOut.size
34
+ inPix = imgIn.load()
35
+ outPix = imgOut.load()
36
+ edge = int(inSize[0] / 4) # the length of each edge in pixels
37
+ for i in range(outSize[0]):
38
+ face = int(i / edge) # 0 - back, 1 - left 2 - front, 3 - right
39
+ if face == 2:
40
+ rng = range(0, edge * 3)
41
+ else:
42
+ rng = range(edge, edge * 2)
43
+
44
+ for j in rng:
45
+ if j < edge:
46
+ face2 = 4 # top
47
+ elif j >= 2 * edge:
48
+ face2 = 5 # bottom
49
+ else:
50
+ face2 = face
51
+
52
+ (x, y, z) = outImgToXYZ(i, j, face2, edge)
53
+ theta = atan2(y, x) # range -pi to pi
54
+ r = hypot(x, y)
55
+ phi = atan2(z, r) # range -pi/2 to pi/2
56
+ # source img coords
57
+ uf = (2.0 * edge * (theta + pi) / pi)
58
+ vf = (2.0 * edge * (pi / 2 - phi) / pi)
59
+ # Use bilinear interpolation between the four surrounding pixels
60
+ ui = floor(uf) # coord of pixel to bottom left
61
+ vi = floor(vf)
62
+ u2 = ui + 1 # coords of pixel to top right
63
+ v2 = vi + 1
64
+ mu = uf - ui # fraction of way across pixel
65
+ nu = vf - vi
66
+ # Pixel values of four corners
67
+ A = inPix[ui % inSize[0], clip(vi, 0, inSize[1] - 1)]
68
+ B = inPix[u2 % inSize[0], clip(vi, 0, inSize[1] - 1)]
69
+ C = inPix[ui % inSize[0], clip(v2, 0, inSize[1] - 1)]
70
+ D = inPix[u2 % inSize[0], clip(v2, 0, inSize[1] - 1)]
71
+ # interpolate
72
+ (r, g, b) = (
73
+ A[0] * (1 - mu) * (1 - nu) + B[0] * (mu) * (1 - nu) + C[0] * (1 - mu) * nu + D[0] * mu * nu,
74
+ A[1] * (1 - mu) * (1 - nu) + B[1] * (mu) * (1 - nu) + C[1] * (1 - mu) * nu + D[1] * mu * nu,
75
+ A[2] * (1 - mu) * (1 - nu) + B[2] * (mu) * (1 - nu) + C[2] * (1 - mu) * nu + D[2] * mu * nu)
76
+
77
+ outPix[i, j] = (int(round(r)), int(round(g)), int(round(b)))
78
+
79
+
80
+ files = sys.argv[1:]
81
+ for file_name in files:
82
+ imgIn = Image.open(file_name)
83
+ width, height = imgIn.size
84
+ if width < height * 2:
85
+ imgIn = imgIn.resize((height * 2, height), Image.ANTIALIAS)
86
+ elif width > height * 2:
87
+ imgIn = imgIn.resize((width, width / 2), Image.ANTIALIAS)
88
+ imgOut = Image.new("RGB", (imgIn.size[0], int(imgIn.size[0] * 3 / 4)), "black")
89
+ convertBack(imgIn, imgOut)
90
+ # imgOut.save('cubemap.png')
91
+ # split squares
92
+ file_extension = ".png"
93
+
94
+ name_map = [["", "", "pz", ""],
95
+ ["ny", "nx", "py", "px"],
96
+ ["", "", "nz", ""]]
97
+ rotation = [[0, 0, 180, 0],
98
+ [0, 90, 180, -90],
99
+ [0, 0, 0, 0]]
100
+ width, height = imgOut.size
101
+
102
+ cube_size = width / 4
103
+
104
+ filelist = []
105
+ for row in range(3):
106
+ for col in range(4):
107
+ if name_map[row][col] != "":
108
+ sx = cube_size * col
109
+ sy = cube_size * row
110
+ fn = file_name[:-4] + '_' + name_map[row][col] + file_extension
111
+ filelist.append(fn)
112
+ print("%s --> %s" % (str((sx, sy, sx + cube_size, sy + cube_size)), fn))
113
+ img = imgOut.crop((sx, sy, sx + cube_size, sy + cube_size))
114
+ if rotation[row][col]:
115
+ img = img.rotate(rotation[row][col])
116
+ img.save(fn)
@@ -0,0 +1,20 @@
1
+ import { Subject } from 'rxjs';
2
+ import { GgPositionable2dEntity } from './gg-positionable-2d-entity';
3
+ import { ITickListener } from '../../base/entities/interfaces/i-tick-listener';
4
+ import { Point2 } from '../../base/models/points';
5
+ import { IGg2dBody, IGg2dObject } from '../interfaces';
6
+ import { Gg2dWorld } from '../gg-2d-world';
7
+ export declare class Gg2dEntity extends GgPositionable2dEntity implements ITickListener {
8
+ readonly object2D: IGg2dObject | null;
9
+ readonly objectBody: IGg2dBody | null;
10
+ readonly tick$: Subject<[number, number]>;
11
+ readonly tickOrder = 750;
12
+ private tickSub;
13
+ set position(value: Point2);
14
+ set rotation(value: number);
15
+ set scale(value: Point2);
16
+ constructor(object2D: IGg2dObject | null, objectBody: IGg2dBody | null);
17
+ onSpawned(world: Gg2dWorld): void;
18
+ onRemoved(): void;
19
+ dispose(): void;
20
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Gg2dEntity = void 0;
4
+ const rxjs_1 = require("rxjs");
5
+ const gg_positionable_2d_entity_1 = require("./gg-positionable-2d-entity");
6
+ class Gg2dEntity extends gg_positionable_2d_entity_1.GgPositionable2dEntity {
7
+ constructor(object2D, objectBody) {
8
+ super();
9
+ this.object2D = object2D;
10
+ this.objectBody = objectBody;
11
+ this.tick$ = new rxjs_1.Subject();
12
+ this.tickOrder = 750;
13
+ this.tickSub = null;
14
+ if (objectBody && object2D) {
15
+ this.tickSub = this.tick$.subscribe(() => {
16
+ // bind physics body transform to object transform
17
+ const pos = objectBody.position;
18
+ const rot = objectBody.rotation;
19
+ object2D.position = pos;
20
+ object2D.rotation = rot;
21
+ this._position$.next(pos);
22
+ this._rotation$.next(rot);
23
+ });
24
+ }
25
+ else if (!objectBody && !object2D) {
26
+ throw new Error('Cannot create entity without a sprite and a body');
27
+ }
28
+ if (objectBody) {
29
+ objectBody.entity = this;
30
+ }
31
+ }
32
+ set position(value) {
33
+ if (this.object2D) {
34
+ this.object2D.position = value;
35
+ }
36
+ if (this.objectBody) {
37
+ this.objectBody.position = value;
38
+ }
39
+ super.position = value;
40
+ }
41
+ set rotation(value) {
42
+ if (this.object2D) {
43
+ this.object2D.rotation = value;
44
+ }
45
+ if (this.objectBody) {
46
+ this.objectBody.rotation = value;
47
+ }
48
+ super.rotation = value;
49
+ }
50
+ set scale(value) {
51
+ if (this.object2D) {
52
+ this.object2D.scale = value;
53
+ }
54
+ if (this.objectBody) {
55
+ this.objectBody.scale = value;
56
+ }
57
+ super.scale = value;
58
+ }
59
+ onSpawned(world) {
60
+ var _a, _b;
61
+ super.onSpawned(world);
62
+ (_a = this.object2D) === null || _a === void 0 ? void 0 : _a.addToWorld(world.visualScene);
63
+ (_b = this.objectBody) === null || _b === void 0 ? void 0 : _b.addToWorld(world.physicsWorld);
64
+ }
65
+ onRemoved() {
66
+ var _a, _b;
67
+ (_a = this.object2D) === null || _a === void 0 ? void 0 : _a.removeFromWorld(this.world.visualScene);
68
+ (_b = this.objectBody) === null || _b === void 0 ? void 0 : _b.removeFromWorld(this.world.physicsWorld);
69
+ super.onRemoved();
70
+ }
71
+ dispose() {
72
+ var _a;
73
+ super.dispose();
74
+ (_a = this.tickSub) === null || _a === void 0 ? void 0 : _a.unsubscribe();
75
+ this.tickSub = null;
76
+ if (this.object2D) {
77
+ this.object2D.dispose();
78
+ }
79
+ if (this.objectBody) {
80
+ this.objectBody.dispose();
81
+ }
82
+ }
83
+ }
84
+ exports.Gg2dEntity = Gg2dEntity;
@@ -0,0 +1,10 @@
1
+ import { IGg2dTrigger } from '../interfaces';
2
+ import { Gg2dEntity } from './gg-2d-entity';
3
+ import { Observable } from 'rxjs';
4
+ import { GgPositionable2dEntity } from './gg-positionable-2d-entity';
5
+ export declare class Gg2dTriggerEntity extends Gg2dEntity {
6
+ readonly objectBody: IGg2dTrigger;
7
+ get onEntityEntered(): Observable<GgPositionable2dEntity>;
8
+ get onEntityLeft(): Observable<GgPositionable2dEntity | null>;
9
+ constructor(objectBody: IGg2dTrigger);
10
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Gg2dTriggerEntity = void 0;
4
+ const gg_2d_entity_1 = require("./gg-2d-entity");
5
+ class Gg2dTriggerEntity extends gg_2d_entity_1.Gg2dEntity {
6
+ constructor(objectBody) {
7
+ super(null, objectBody);
8
+ this.objectBody = objectBody;
9
+ }
10
+ get onEntityEntered() {
11
+ return this.objectBody.onEntityEntered;
12
+ }
13
+ get onEntityLeft() {
14
+ return this.objectBody.onEntityLeft;
15
+ }
16
+ }
17
+ exports.Gg2dTriggerEntity = Gg2dTriggerEntity;
@@ -0,0 +1,7 @@
1
+ import { Point2 } from '../../base/models/points';
2
+ import { GgPositionableEntity } from '../../base/entities/gg-positionable-entity';
3
+ export declare abstract class GgPositionable2dEntity extends GgPositionableEntity<Point2, number> {
4
+ getDefaultPosition(): Point2;
5
+ getDefaultRotation(): number;
6
+ getDefaultScale(): Point2;
7
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GgPositionable2dEntity = void 0;
4
+ const gg_positionable_entity_1 = require("../../base/entities/gg-positionable-entity");
5
+ class GgPositionable2dEntity extends gg_positionable_entity_1.GgPositionableEntity {
6
+ getDefaultPosition() {
7
+ return { x: 0, y: 0 };
8
+ }
9
+ getDefaultRotation() {
10
+ return 0;
11
+ }
12
+ getDefaultScale() {
13
+ return { x: 1, y: 1 };
14
+ }
15
+ }
16
+ exports.GgPositionable2dEntity = GgPositionable2dEntity;
@@ -0,0 +1,18 @@
1
+ import { BodyShape2DDescriptor, Shape2DDescriptor } from './models/shapes';
2
+ import { Point2 } from '../base/models/points';
3
+ import { IGg2dBody, IGg2dObject, IGg2dTrigger } from './interfaces';
4
+ export declare abstract class IGg2dObjectFactory<T extends IGg2dObject = IGg2dObject> {
5
+ abstract createPrimitive(descriptor: Shape2DDescriptor): T;
6
+ createSquare(dimensions: Point2): T;
7
+ createCircle(radius: number): T;
8
+ }
9
+ export interface IGg2dBodyFactory<T extends IGg2dBody = IGg2dBody, K extends IGg2dTrigger = IGg2dTrigger> {
10
+ createRigidBody(descriptor: BodyShape2DDescriptor, transform?: {
11
+ position?: Point2;
12
+ rotation?: number;
13
+ }): T;
14
+ createTrigger(descriptor: Shape2DDescriptor, transform?: {
15
+ position?: Point2;
16
+ rotation?: number;
17
+ }): K;
18
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IGg2dObjectFactory = void 0;
4
+ class IGg2dObjectFactory {
5
+ // shortcuts
6
+ createSquare(dimensions) {
7
+ return this.createPrimitive({ shape: 'SQUARE', dimensions });
8
+ }
9
+ createCircle(radius) {
10
+ return this.createPrimitive({ shape: 'CIRCLE', radius });
11
+ }
12
+ }
13
+ exports.IGg2dObjectFactory = IGg2dObjectFactory;
@@ -0,0 +1,9 @@
1
+ import { GgWorld } from '../base/gg-world';
2
+ import { Point2 } from '../base/models/points';
3
+ import { IGg2dPhysicsWorld, IGg2dVisualScene } from './interfaces';
4
+ export declare class Gg2dWorld<V extends IGg2dVisualScene = IGg2dVisualScene, P extends IGg2dPhysicsWorld = IGg2dPhysicsWorld> extends GgWorld<Point2, number, V, P> {
5
+ readonly visualScene: V;
6
+ readonly physicsWorld: P;
7
+ protected readonly consoleEnabled: boolean;
8
+ constructor(visualScene: V, physicsWorld: P, consoleEnabled?: boolean);
9
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Gg2dWorld = void 0;
13
+ const gg_world_1 = require("../base/gg-world");
14
+ class Gg2dWorld extends gg_world_1.GgWorld {
15
+ constructor(visualScene, physicsWorld, consoleEnabled = false) {
16
+ super(visualScene, physicsWorld, consoleEnabled);
17
+ this.visualScene = visualScene;
18
+ this.physicsWorld = physicsWorld;
19
+ this.consoleEnabled = consoleEnabled;
20
+ if (consoleEnabled) {
21
+ this.registerConsoleCommand('ph_gravity', (...args) => __awaiter(this, void 0, void 0, function* () {
22
+ if (args.length == 1) {
23
+ args = ['0', args[0]]; // mean Y axis
24
+ }
25
+ if (args.length > 0) {
26
+ this.physicsWorld.gravity = { x: +args[0], y: +args[1] };
27
+ }
28
+ return JSON.stringify(this.physicsWorld.gravity);
29
+ }), 'args: [float] or [float float]; change 2D world gravity vector. 1 argument means ' +
30
+ '{x: 0, y: value}, 2 arguments set the whole vector. Default value is "9.82" or "0 9.82"');
31
+ }
32
+ }
33
+ }
34
+ exports.Gg2dWorld = Gg2dWorld;
@@ -0,0 +1,26 @@
1
+ import { GgBody } from '../base/interfaces/gg-body';
2
+ import { Point2 } from '../base/models/points';
3
+ import { GgObject } from '../base/interfaces/gg-object';
4
+ import { GgPhysicsWorld } from '../base/interfaces/gg-physics-world';
5
+ import { GgVisualScene } from '../base/interfaces/gg-visual-scene';
6
+ import { BaseGgRenderer } from '../base/entities/base-gg-renderer';
7
+ import { GgTrigger } from '../base/interfaces/gg-trigger';
8
+ import { Observable } from 'rxjs';
9
+ import { GgPositionable2dEntity } from './entities/gg-positionable-2d-entity';
10
+ import { IGg2dBodyFactory, IGg2dObjectFactory } from './factories';
11
+ export interface IGg2dPhysicsWorld extends GgPhysicsWorld<Point2, number> {
12
+ readonly factory: IGg2dBodyFactory;
13
+ }
14
+ export declare abstract class Gg2dRenderer extends BaseGgRenderer {
15
+ }
16
+ export interface IGg2dBody extends GgBody<Point2, number> {
17
+ }
18
+ export interface IGg2dTrigger extends GgTrigger<Point2, number> {
19
+ get onEntityEntered(): Observable<GgPositionable2dEntity>;
20
+ get onEntityLeft(): Observable<GgPositionable2dEntity | null>;
21
+ }
22
+ export interface IGg2dVisualScene extends GgVisualScene<Point2, number> {
23
+ readonly factory: IGg2dObjectFactory;
24
+ }
25
+ export interface IGg2dObject extends GgObject<Point2, number> {
26
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Gg2dRenderer = void 0;
4
+ const base_gg_renderer_1 = require("../base/entities/base-gg-renderer");
5
+ class Gg2dRenderer extends base_gg_renderer_1.BaseGgRenderer {
6
+ }
7
+ exports.Gg2dRenderer = Gg2dRenderer;
@@ -0,0 +1,3 @@
1
+ import { BodyOptions } from '../../base/models/body-options';
2
+ export interface Body2DOptions extends BodyOptions {
3
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,13 @@
1
+ import { Point2 } from '../../base/models/points';
2
+ import { Body2DOptions } from './body-options';
3
+ export declare type Shape2DDescriptor = {
4
+ shape: 'SQUARE';
5
+ dimensions: Point2;
6
+ } | {
7
+ shape: 'CIRCLE';
8
+ radius: number;
9
+ };
10
+ export declare type BodyShape2DDescriptor = {
11
+ shape: Shape2DDescriptor;
12
+ body: Partial<Body2DOptions>;
13
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,25 @@
1
+ import { BehaviorSubject } from 'rxjs';
2
+ import { IController } from '../../base/controllers/i-controller';
3
+ import { KeyboardController } from '../../base/controllers/keyboard.controller';
4
+ import { Gg3dRaycastVehicleEntity } from '../entities/gg-3d-raycast-vehicle.entity';
5
+ import { DirectionKeymap } from '../../base/controllers/common';
6
+ declare type CarKeyboardControllerOptions = {
7
+ keymap: DirectionKeymap;
8
+ gearUpDownKeys: [string, string];
9
+ };
10
+ export declare class CarKeyboardController implements IController {
11
+ private readonly keyboardController;
12
+ private readonly options;
13
+ private readonly x$;
14
+ private readonly y$;
15
+ private lastX;
16
+ private readonly stop$;
17
+ protected readonly car$: BehaviorSubject<Gg3dRaycastVehicleEntity>;
18
+ pairTickerPipe: import("rxjs").UnaryFunction<import("rxjs").Observable<number>, import("rxjs").Observable<number>>;
19
+ set car(value: Gg3dRaycastVehicleEntity);
20
+ get car(): Gg3dRaycastVehicleEntity;
21
+ constructor(keyboardController: KeyboardController, car: Gg3dRaycastVehicleEntity, options?: CarKeyboardControllerOptions);
22
+ start(): Promise<void>;
23
+ stop(): Promise<void>;
24
+ }
25
+ export {};