simple2d-3d 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,5 @@
1
+ from .setup import Init as init , CleanUp as clean_up
2
+ from .render import Camera , Vector3 , Rect , Line , Circle , Scene , Scene2D , Raycaster2D , BreakObject2D as break_object_2d , CreatePlatform2D as create_platform_2d , CreatePlatform as create_platform , Project2D as project_2d, DrawFilledFace as draw_filled_face, Cube
3
+ from . import colors
4
+ __all__ = [
5
+ "init" , "clean_up" , "Camera" , "Vector3" , "Rect" , "Circle" , "Line" , "Scene" , "Scene2D" , "Raycaster2D" , "break_object_2d" , "create_platform_2d" , "create_platform" , "project_2d" , "draw_filled_face" , "Cube" , "colors"]
simple2d_3d/colors.py ADDED
@@ -0,0 +1,22 @@
1
+ import sdl2
2
+ RED = sdl2.SDL_Color(255,0,0,255)
3
+ GREEN = sdl2.SDL_Color(0,255,0,255)
4
+ BLUE = sdl2.SDL_Color(0,0,255,255)
5
+ YELLOW = sdl2.SDL_Color(255,255,0,255)
6
+ CYAN = sdl2.SDL_Color(0,255,255,255)
7
+ WHITE = sdl2.SDL_Color(255,255,255,255)
8
+ BLACK = sdl2.SDL_Color(0,0,0,255)
9
+ GHOST_WHITE = sdl2.SDL_Color(248, 248, 255, 128)
10
+ SHADOW = sdl2.SDL_Color(0, 0, 0, 150)
11
+ TERRA_COTTA = sdl2.SDL_Color(226, 114, 91, 255)
12
+ GOLDENROD = sdl2.SDL_Color(218, 165, 32, 255)
13
+ OLIVE_DRAB = sdl2.SDL_Color(107, 142, 35, 255)
14
+ CORAL = sdl2.SDL_Color(255, 127, 80, 255)
15
+ ELECTRIC_PURPLE = sdl2.SDL_Color(191, 0, 255, 255)
16
+ NEON_PINK = sdl2.SDL_Color(255, 20, 147, 255)
17
+ MINT_GREEN = sdl2.SDL_Color(152, 255, 152, 255)
18
+ TURQUOISE = sdl2.SDL_Color(64, 224, 208, 255)
19
+ MIDNIGHT_BLUE = sdl2.SDL_Color(25, 25, 112, 255)
20
+ SLATE_GRAY = sdl2.SDL_Color(112, 128, 144, 255)
21
+ CHARCOAL = sdl2.SDL_Color(54, 69, 79, 255)
22
+ EGGPLANT = sdl2.SDL_Color(49, 18, 59, 255)
simple2d_3d/render.py ADDED
@@ -0,0 +1,395 @@
1
+ import math , sdl2 , ctypes
2
+ from .colors import *
3
+ class Camera:
4
+ def __init__(self,x,y,z,yaw,pitch):
5
+ self.pos = Vector3(x,y,z)
6
+ self.yaw = yaw
7
+ self.pitch = pitch
8
+
9
+ class Vector3:
10
+ __slots__ = ['x', 'y', 'z']
11
+
12
+ def __init__(self, x=0.0, y=0.0, z=0.0):
13
+ self.x = float(x)
14
+ self.y = float(y)
15
+ self.z = float(z)
16
+
17
+ def __sub__(self, other):
18
+ return Vector3(self.x - other.x, self.y - other.y, self.z - other.z)
19
+
20
+ def dot(self, other):
21
+ return self.x * other.x + self.y * other.y + self.z * other.z
22
+
23
+ def cross(self, other):
24
+ return Vector3(
25
+ self.y * other.z - self.z * other.y,
26
+ self.z * other.x - self.x * other.z,
27
+ self.x * other.y - self.y * other.x
28
+ )
29
+
30
+ def Project2D(x, y, z , width , height):
31
+ if z <= 1: z = 1
32
+ ratio = height / width
33
+ fov_angle = 110
34
+ fov_rad = 1.0 / math.tan(fov_angle * 0.5 * math.pi / 180.0)
35
+
36
+ px = x * fov_rad * ratio / z
37
+ py = y * fov_rad / z
38
+
39
+ px = (px + 1) * 0.5 * width
40
+ py = (py + 1) * 0.5 * height
41
+
42
+ return px, py
43
+
44
+ def DrawFilledFace(renderer,idx1 , idx2 , idx3,points,color):
45
+ if points[idx1] and points[idx2] and points[idx3]:
46
+ #color = RED
47
+ v1 = sdl2.SDL_Vertex(sdl2.SDL_FPoint(points[idx1].x, points[idx1].y), color, sdl2.SDL_FPoint(0,0))
48
+ #color = BLUE
49
+ v2 = sdl2.SDL_Vertex(sdl2.SDL_FPoint(points[idx2].x, points[idx2].y), color, sdl2.SDL_FPoint(0,0))
50
+ #color = GREEN
51
+ v3 = sdl2.SDL_Vertex(sdl2.SDL_FPoint(points[idx3].x, points[idx3].y), color, sdl2.SDL_FPoint(0,0))
52
+ triangle_verts = (sdl2.SDL_Vertex * 3)(v1, v2, v3)
53
+ sdl2.SDL_RenderGeometry(renderer, None, triangle_verts, 3, None, 0)
54
+
55
+ class Cube:
56
+ def __init__(self,x,y,z,w,h,d,color):
57
+ self.pos = Vector3(x,y,z)
58
+ self.size = Vector3(w,h,d)
59
+ self.color = color
60
+ self.dist = 0
61
+ self.vertices = [
62
+ Vector3(-self.size.x , -self.size.y , -self.size.z), # 0
63
+ Vector3(-self.size.x , -self.size.y , self.size.z), # 1
64
+ Vector3(self.size.x , -self.size.y , self.size.z), # 2
65
+ Vector3(self.size.x, -self.size.y , -self.size.z), # 3
66
+ Vector3(self.size.x , self.size.y , -self.size.z), # 4
67
+ Vector3(-self.size.x , self.size.y , -self.size.z), # 5
68
+ Vector3(-self.size.x , self.size.y , self.size.z), # 6
69
+ Vector3(self.size.x , self.size.y , self.size.z) # 7
70
+ ]
71
+ # Each line is ONE triangle (3 indices)
72
+ self.triangle_indices = [
73
+ # FRONT (Z-) - Looking from the front
74
+ 0, 3, 4, 0, 4, 5,
75
+ # BACK (Z+) - Looking from the back
76
+ 2, 1, 6, 2, 6, 7,
77
+ # RIGHT (X+) - Looking from the right
78
+ 3, 2, 7, 3, 7, 4,
79
+ # LEFT (X-) - Looking from the left
80
+ 1, 0, 5, 1, 5, 6,
81
+ # TOP (Y-) - Looking from above
82
+ 0, 1, 2, 0, 2, 3,
83
+ # BOTTOM (Y+) - Looking from below
84
+ 5, 4, 7, 5, 7, 6
85
+ ]
86
+ def DrawFilled(self,renderer,camera,sin_y,cos_y,sin_p,cos_p, width , height):
87
+ points = []
88
+ rotated_points = []
89
+ for v in self.vertices:
90
+ worldX = v.x + self.pos.x
91
+ worldY = v.y + self.pos.y
92
+ worldZ = v.z + self.pos.z
93
+ relX = worldX - camera.pos.x
94
+ relY = worldY - camera.pos.y
95
+ relZ = worldZ - camera.pos.z
96
+ rot_x = relX * cos_y + relZ * sin_y
97
+ temp_z = -relX * sin_y + relZ * cos_y
98
+ rot_y = relY * cos_p - temp_z * sin_p
99
+ rot_z = relY * sin_p + temp_z * cos_p
100
+ rotated_points.append(Vector3(rot_x,rot_y,rot_z))
101
+
102
+ result = Project2D(rot_x,rot_y,rot_z, width , height)
103
+ px , py = 0 , 0
104
+ if result == None: points.append(result)
105
+ else: px , py = result
106
+ px = round(px,1)
107
+ py = round(py,1)
108
+ points.append(sdl2.SDL_FPoint(px,py))
109
+ j = 0
110
+ while j < len(self.triangle_indices):
111
+ idx1 = self.triangle_indices[j]
112
+ idx2 = self.triangle_indices[j+1]
113
+ idx3 = self.triangle_indices[j+2]
114
+ v1 = rotated_points[idx1]
115
+ v2 = rotated_points[idx2]
116
+ v3 = rotated_points[idx3]
117
+ edge1 = v2 - v1
118
+ edge2 = v3 - v1
119
+ normal = edge1.cross(edge2)
120
+ if normal.dot(v1) > 0:
121
+ DrawFilledFace(renderer,idx1,idx2,idx3,points,self.color)
122
+ j += 3
123
+
124
+ class Scene:
125
+ def __init__(self,camera,near_limit,far_limit, width , height):
126
+ self.camera = camera
127
+ self.near_limit = near_limit
128
+ self.far_limit = far_limit
129
+ self.width = width
130
+ self.height = height
131
+ self.object_list = []
132
+
133
+ def add(self,object):
134
+ self.object_list.append(object)
135
+
136
+ def remove(self,object):
137
+ self.object_list.remove(object)
138
+
139
+ def draw(self,renderer):
140
+ for object in self.object_list:
141
+ dx = object.pos.x - self.camera.pos.x
142
+ dy = object.pos.y - self.camera.pos.y
143
+ dz = object.pos.z - self.camera.pos.z
144
+ object.dist = math.sqrt(dx*dx + dy*dy + dz*dz)
145
+ self.object_list.sort(key=lambda c: c.dist, reverse=True)
146
+ rad_y = math.radians(-self.camera.yaw)
147
+ rad_p = math.radians(-self.camera.pitch)
148
+ cos_y = math.cos(rad_y)
149
+ sin_y = math.sin(rad_y)
150
+ cos_p = math.cos(rad_p)
151
+ sin_p = math.sin(rad_p)
152
+ for object in self.object_list:
153
+ if object.dist <= self.near_limit or object.dist > self.far_limit:
154
+ continue
155
+ if object.dist > self.far_limit - 10:
156
+ if object.color.a > 0:
157
+ object.color.a -= int(object.color.a - object.dist - 50)
158
+ else: object.color.a = 255
159
+ if isinstance(object,Cube):
160
+ object.DrawFilled(renderer, self.camera,sin_y,cos_y,sin_p,cos_p,self.width,self.height)
161
+
162
+ def CreatePlatform(renderer,scene,x,y,z,w,h,d,size,space,color):
163
+ for i in range(w):
164
+ for j in range(h):
165
+ for k in range(d):
166
+ new_cube = Cube(
167
+ x + i*(size*2+space),
168
+ y + j*(size*2+space),
169
+ z + k*(size*2+space),
170
+ size , size , size,color)
171
+ scene.add(new_cube)
172
+ class Circle:
173
+ def __init__(self , x , y , r , color,cast_shadow=True,breakable=True):
174
+ self.x = x
175
+ self.y = y
176
+ self.r = r
177
+ self.c = color
178
+ self.cast_shadow = cast_shadow
179
+ self.breakable = breakable
180
+
181
+ def Update(self):
182
+ pass
183
+
184
+ def DrawFilled(self , renderer):
185
+ sdl2.SDL_SetRenderDrawColor(renderer,self.c.r , self.c.g , self.c.b , self.c.a)
186
+ for y in range(-self.r , self.r+1):
187
+ x = math.sqrt(self.r*self.r - y*y)
188
+ sdl2.SDL_RenderDrawLineF(renderer, self.x - x, self.y + y , self.x + x , self.y + y)
189
+
190
+ def remove(self):
191
+ pass
192
+
193
+ class Line:
194
+ def __init__(self,x1,y1,x2,y2,color,parent=None,cast_shadow=True,breakable=True):
195
+ self.x1 = x1
196
+ self.x2 = x2
197
+ self.y1 = y1
198
+ self.y2 = y2
199
+ self.c = color
200
+ self.parent = parent
201
+ self.cast_shadow = cast_shadow
202
+ self.breakable = breakable
203
+
204
+ def Update(self):
205
+ pass
206
+
207
+ def DrawFilled(self,renderer):
208
+ if self.parent == None:
209
+ sdl2.SDL_SetRenderDrawColor(renderer,self.c.r , self.c.g , self.c.b , self.c.a)
210
+ sdl2.SDL_RenderDrawLine(renderer,self.x1,self.y1,self.x2,self.y2)
211
+ else: pass
212
+
213
+ def remove(self):
214
+ pass
215
+
216
+ class Rect:
217
+ def __init__(self,x,y,w,h,color,scene,cast_shadow=True,breakable=True):
218
+ self.x = x
219
+ self.y = y
220
+ self.w = w
221
+ self.h = h
222
+ self.c = color
223
+ self.scene = scene
224
+ self.cast_shadow = cast_shadow
225
+ self.breakable = breakable
226
+ self.rect = sdl2.SDL_Rect(x,y,w,h)
227
+ self.line_list = []
228
+ self.line_list.append(Line(x,y,x+w,y,color,1,cast_shadow,breakable))
229
+ self.line_list.append(Line(x,y,x,y+h,color,1,cast_shadow,breakable))
230
+ self.line_list.append(Line(x,y+h,x+w,y+h,color,1,cast_shadow,breakable))
231
+ self.line_list.append(Line(x+w,y,x+w,y+h,color,1,cast_shadow,breakable))
232
+
233
+ def Update(self):
234
+ if len(self.line_list)<4: return
235
+ self.line_list[0].x1 , self.line_list[0].y1 , self.line_list[0].x2 , self.line_list[0].y2 , self.line_list[0].c , self.line_list[0].parent , self.line_list[0].breakable = self.x , self.y, self.x+self.w, self.y , self.c , 1 , self.breakable
236
+
237
+ self.line_list[1].x1 , self.line_list[1].y1 , self.line_list[1].x2 , self.line_list[1].y2 , self.line_list[1].c , self.line_list[1].parent , self.line_list[1].breakable = self.x , self.y, self.x , self.y+self.h , self.c , 1 , self.breakable
238
+
239
+ self.line_list[2].x1 , self.line_list[2].y1 , self.line_list[2].x2 , self.line_list[2].y2 , self.line_list[2].c , self.line_list[2].parent , self.line_list[2].breakable = self.x , self.y+self.h , self.x+self.w , self.y+self.h , self.c , 1 , self.breakable
240
+
241
+ self.line_list[3].x1 , self.line_list[3].y1 , self.line_list[3].x2 , self.line_list[3].y2 , self.line_list[3].c , self.line_list[3].parent , self.line_list[3].breakable = self.x+self.w , self.y , self.x+self.w , self.y+self.h , self.c , 1 , self.breakable
242
+ self.rect.x = self.x
243
+ self.rect.y = self.y
244
+ self.rect.w = self.w
245
+ self.rect.h = self.h
246
+
247
+ def DrawFilled(self,renderer):
248
+ sdl2.SDL_SetRenderDrawColor(renderer,self.c.r , self.c.g , self.c.b , self.c.a)
249
+ sdl2.SDL_RenderFillRect(renderer,ctypes.byref(self.rect))
250
+ return self.rect
251
+
252
+ def remove(self):
253
+ to_remove = list(self.line_list)
254
+ self.line_list.clear()
255
+ for line in to_remove:
256
+ self.scene.remove(line)
257
+
258
+ class Scene2D:
259
+ def __init__(self):
260
+ self.object_list = []
261
+
262
+ def add(self,object):
263
+ if isinstance(object,Rect):
264
+ for line in object.line_list:
265
+ self.object_list.append(line)
266
+ self.object_list.append(object)
267
+
268
+ def remove(self,object):
269
+ if object in self.object_list:
270
+ object.remove()
271
+ self.object_list.remove(object)
272
+ object = None
273
+
274
+ def update(self):
275
+ for object in self.object_list:
276
+ if object in self.object_list:
277
+ object.Update()
278
+
279
+ def draw(self,renderer):
280
+ for obj in self.object_list:
281
+ obj.DrawFilled(renderer)
282
+
283
+ class Raycaster2D:
284
+ def __init__(self,light,scene):
285
+ self.light = light
286
+ self.object_list = scene.object_list
287
+ self.angle = 0
288
+ self.rad = 0
289
+ self.ray_len = light.r
290
+ self.start_angle = 0
291
+ self.end_angle = 0
292
+ self.endX = 0
293
+ self.endY = 0
294
+
295
+ def ray_object_intersect(self):
296
+ closest_dist = self.light.r
297
+ for obj in self.object_list:
298
+ if obj.cast_shadow:
299
+ if isinstance(obj,Circle):
300
+ ob_x , ob_y , ob_r = 0 , 0 , 0
301
+ ob_x , ob_y , ob_r = obj.x , obj.y , obj.r
302
+ dx, dy = ob_x - self.light.x, ob_y - self.light.y
303
+ b = -2 * (dx * math.cos(self.rad) + dy * math.sin(self.rad))
304
+ c = dx * dx + dy * dy - ob_r * ob_r
305
+ val = b * b - 4 * c
306
+ if val >= 0:
307
+ val_sq = math.sqrt(val)
308
+ front_dist = (-b - val_sq) /2
309
+ back_dist = (-b + val_sq) /2
310
+ dist = (back_dist if front_dist < 0 else front_dist)
311
+ if dist >= 0 and dist <= closest_dist:
312
+ closest_dist = dist
313
+
314
+ if isinstance(obj,Line):
315
+ dx = obj.x2 - obj.x1
316
+ dy = obj.y2 - obj.y1
317
+ sin_r = math.sin(self.rad)
318
+ cos_r = math.cos(self.rad)
319
+ den = dy*cos_r-dx*sin_r
320
+ u = ((obj.x1-self.light.x)*sin_r-(obj.y1-self.light.y)*cos_r)/(den+0.0001)
321
+ t = ((obj.x1-self.light.x)*dy-(obj.y1-self.light.y)*dx)/(den+0.0001)
322
+ if u >= 0 and u <= 1 and t > 0 and t <= closest_dist:
323
+ closest_dist = t
324
+ return closest_dist
325
+
326
+ def raycast(self,renderer,start=0,end=360,step=1):
327
+ sdl2.SDL_SetRenderDrawColor(renderer,self.light.c.r , self.light.c.g , self.light.c.b , self.light.c.a)
328
+ self.angle = start
329
+ self.start_angle = start
330
+ self.end_angle = end
331
+ while self.angle < self.end_angle:
332
+ self.rad = math.radians(self.angle)
333
+ self.ray_len = self.light.r
334
+ val = self.ray_object_intersect()
335
+ if val != None:
336
+ self.ray_len = val
337
+ self.endX = self.light.x + self.ray_len * math.cos(self.rad)
338
+ self.endY = self.light.y + self.ray_len * math.sin(self.rad)
339
+ sdl2.SDL_RenderDrawLineF(renderer, self.light.x, self.light.y, self.endX, self.endY)
340
+ self.angle += step
341
+
342
+ def BreakObject2D(scene,raycaster,angle):
343
+ if abs(raycaster.angle+angle) > 1:
344
+ return
345
+ else:
346
+ to_remove = []
347
+ buffer = 2
348
+ for i in range(len(scene.object_list)):
349
+ if scene.object_list[i].breakable:
350
+ if isinstance(scene.object_list[i],Rect):
351
+ min_x = min(scene.object_list[i].x , scene.object_list[i].x + scene.object_list[i].w)
352
+ max_x = max(scene.object_list[i].x , scene.object_list[i].x + scene.object_list[i].w)
353
+ min_y = min(scene.object_list[i].y , scene.object_list[i].y + scene.object_list[i].h)
354
+ max_y = max(scene.object_list[i].y , scene.object_list[i].y + scene.object_list[i].h)
355
+ if (min_y - buffer <= raycaster.endY <= max_y + buffer ) and (min_x - buffer <= raycaster.endX <= max_x + buffer):
356
+ to_remove.append(scene.object_list[i])
357
+ if isinstance(scene.object_list[i],Line):
358
+ min_x = min(scene.object_list[i].x1,scene.object_list[i].x2)
359
+ max_x = max(scene.object_list[i].x1,scene.object_list[i].x2)
360
+ min_y = min(scene.object_list[i].y1,scene.object_list[i].y2)
361
+ max_y = max(scene.object_list[i].y1,scene.object_list[i].y2)
362
+ if (min_x - buffer <= raycaster.endX <= max_x + buffer) and (min_y - buffer <= raycaster.endY <= max_y + buffer):
363
+ to_remove.append(scene.object_list[i])
364
+ if isinstance(scene.object_list[i],Circle):
365
+ dx = (raycaster.endX - scene.object_list[i].x)
366
+ dy = (raycaster.endY - scene.object_list[i].y)
367
+ r = scene.object_list[i].r
368
+ if dx * dx + dy * dy <= r * r:
369
+ to_remove.append(scene.object_list[i])
370
+ for obj in to_remove:
371
+ if obj in scene.object_list:
372
+ scene.remove(obj)
373
+
374
+ def CreatePlatform2D(scene,map_data,w,h,space,x_offset,y_offset,cast_shadow=True):
375
+ row = len(map_data)
376
+ col = len(map_data[0])
377
+ current_color = None
378
+ for y in range(row):
379
+ x = 0
380
+ while x < col:
381
+ if map_data[y][x]==1:
382
+ start_c = x
383
+ current_color = RED
384
+ while x < col and map_data[y][x]==1:
385
+ x += 1
386
+ combined_w = (x-start_c)*w
387
+ new_rect = Rect(x_offset+start_c*(w+space),y_offset+y*(h+space),combined_w,h,current_color,scene,cast_shadow,False)
388
+ scene.add(new_rect)
389
+ elif map_data[y][x]==2:
390
+ current_color = YELLOW
391
+ new_rect = Rect(x_offset+x*(w+space),y_offset+y*(h+space),w,h,current_color,scene,cast_shadow,True)
392
+ scene.add(new_rect)
393
+ x += 1
394
+ else:
395
+ x += 1
simple2d_3d/setup.py ADDED
@@ -0,0 +1,23 @@
1
+ import sdl2 , sys
2
+ def Init(title,w,h):
3
+ sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
4
+ window = sdl2.SDL_CreateWindow(title,sdl2.SDL_WINDOWPOS_UNDEFINED,sdl2.SDL_WINDOWPOS_UNDEFINED, w , h , sdl2.SDL_WINDOW_SHOWN | sdl2.SDL_WINDOW_RESIZABLE)
5
+ if not window:
6
+ print("Error : ",sdl2.SDL_GetError())
7
+ sdl2.SDL_Quit()
8
+ sys.exit(0)
9
+ renderer = sdl2.SDL_CreateRenderer(window,-1,sdl2.SDL_RENDERER_ACCELERATED | sdl2.SDL_RENDERER_PRESENTVSYNC)
10
+ if not renderer:
11
+ print("Error : ",sdl2.SDL_GetError())
12
+ sdl2.SDL_Quit()
13
+ sys.exit(0)
14
+ sdl2.SDL_SetRenderDrawBlendMode(renderer, sdl2.SDL_BLENDMODE_BLEND);
15
+ sdl2.SDL_GetWindowSize(window,w,h)
16
+ return window , renderer
17
+
18
+ def CleanUp(window , renderer):
19
+ if renderer:
20
+ sdl2.SDL_DestroyRenderer(renderer)
21
+ if window:
22
+ sdl2.SDL_DestroyWindow(window)
23
+ sdl2.SDL_Quit()
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: simple2d_3d
3
+ Version: 0.1.0
4
+ Summary: A lightweight, hardware-accelerated 2D-3D layout and engine.
5
+ Author: ProdeeptoSundar Roy
6
+ Project-URL: Homepage, https://github.com/rtumpa099-gif/Simple2D_3D
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.7
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: pysdl2
14
+ Dynamic: license-file
15
+
16
+ # Simple2D_3D
17
+ A lightweight, hardware-accelerated 2D-3D layout and engine.
@@ -0,0 +1,9 @@
1
+ simple2d_3d/__init__.py,sha256=xYdcK6tI184ZpLfC9DpbknT3MvkZeQVAQCK8p8me45I,592
2
+ simple2d_3d/colors.py,sha256=oa4TdMzN6QbZMg7oOVAULj-NRfnr--wLE98FJaLiXME,910
3
+ simple2d_3d/render.py,sha256=E_38TCrYBklElsp9wNvaZ0f8Ko-Y4Dz3maUmptp8EyM,13846
4
+ simple2d_3d/setup.py,sha256=bI7PkCKa6ejHbl6vn8WmJYKz1z9tAb6-oVF6PQs1dKk,797
5
+ simple2d_3d-0.1.0.dist-info/licenses/LICENSE,sha256=nImvLlK3J6DHaAeF9zZhAaPpex-FfCVsisr_6kpA1SE,1062
6
+ simple2d_3d-0.1.0.dist-info/METADATA,sha256=weOxIp0mR5j5GoD6XSsDKcwHKCzASeVAb_mvdmrOT7c,572
7
+ simple2d_3d-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
8
+ simple2d_3d-0.1.0.dist-info/top_level.txt,sha256=RSLeXzPvoYQcVyTPHZ-egVpv-QvnlURBL3eYNwGXMt0,12
9
+ simple2d_3d-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2026 ProdeeptoSundar Roy
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ simple2d_3d