Improve struct creation helper methods by auto converting arguments: (#119)
* None to ffi.NULL * array and ndarray to buffer, and keep weakref so it doesn't get GCed This makes it possible to create Mesh structs without too much faffing.
This commit is contained in:
parent
ef3681fc5b
commit
33dce4ecfd
2 changed files with 139 additions and 3 deletions
120
examples/extra/mesh_creation.py
Normal file
120
examples/extra/mesh_creation.py
Normal file
|
@ -0,0 +1,120 @@
|
|||
from array import array
|
||||
import pyray as pr
|
||||
|
||||
W, H = 640, 480
|
||||
|
||||
|
||||
def make_cube(width, height, length):
|
||||
vertices = array('f', [
|
||||
-width / 2, -height / 2, length / 2,
|
||||
width / 2, -height / 2, length / 2,
|
||||
width / 2, height / 2, length / 2,
|
||||
-width / 2, height / 2, length / 2,
|
||||
-width / 2, -height / 2, -length / 2,
|
||||
-width / 2, height / 2, -length / 2,
|
||||
width / 2, height / 2, -length / 2,
|
||||
width / 2, -height / 2, -length / 2,
|
||||
-width / 2, height / 2, -length / 2,
|
||||
-width / 2, height / 2, length / 2,
|
||||
width / 2, height / 2, length / 2,
|
||||
width / 2, height / 2, -length / 2,
|
||||
-width / 2, -height / 2, -length / 2,
|
||||
width / 2, -height / 2, -length / 2,
|
||||
width / 2, -height / 2, length / 2,
|
||||
-width / 2, -height / 2, length / 2,
|
||||
width / 2, -height / 2, -length / 2,
|
||||
width / 2, height / 2, -length / 2,
|
||||
width / 2, height / 2, length / 2,
|
||||
width / 2, -height / 2, length / 2,
|
||||
-width / 2, -height / 2, -length / 2,
|
||||
-width / 2, -height / 2, length / 2,
|
||||
-width / 2, height / 2, length / 2,
|
||||
-width / 2, height / 2, -length / 2
|
||||
])
|
||||
|
||||
texcoords = array('f', [
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
1.0, 1.0,
|
||||
0.0, 1.0,
|
||||
1.0, 0.0,
|
||||
1.0, 1.0,
|
||||
0.0, 1.0,
|
||||
0.0, 0.0,
|
||||
0.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
1.0, 1.0,
|
||||
1.0, 1.0,
|
||||
0.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
1.0, 0.0,
|
||||
1.0, 1.0,
|
||||
0.0, 1.0,
|
||||
0.0, 0.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
1.0, 1.0,
|
||||
0.0, 1.0])
|
||||
|
||||
normals = array('f', [
|
||||
0.0, 0.0, 1.0,
|
||||
0.0, 0.0, 1.0,
|
||||
0.0, 0.0, 1.0,
|
||||
0.0, 0.0, 1.0,
|
||||
0.0, 0.0, -1.0,
|
||||
0.0, 0.0, -1.0,
|
||||
0.0, 0.0, -1.0,
|
||||
0.0, 0.0, -1.0,
|
||||
0.0, 1.0, 0.0,
|
||||
0.0, 1.0, 0.0,
|
||||
0.0, 1.0, 0.0,
|
||||
0.0, 1.0, 0.0,
|
||||
0.0, -1.0, 0.0,
|
||||
0.0, -1.0, 0.0,
|
||||
0.0, -1.0, 0.0,
|
||||
0.0, -1.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
-1.0, 0.0, 0.0,
|
||||
-1.0, 0.0, 0.0,
|
||||
-1.0, 0.0, 0.0,
|
||||
-1.0, 0.0, 0.0
|
||||
])
|
||||
|
||||
indices = array('h',
|
||||
sum([[4 * k, 4 * k + 1, 4 * k + 2, 4 * k, 4 * k + 2, 4 * k + 3] for k in range(0, 6)], []))
|
||||
|
||||
print(vertices, indices)
|
||||
|
||||
return (pr.Mesh(24, 12, vertices, texcoords,
|
||||
None, normals, None, None, indices,
|
||||
None, None, None, None, 0, None))
|
||||
|
||||
|
||||
pr.init_window(W, H, "Mesh creation")
|
||||
|
||||
msh = make_cube(3, 4, 40)
|
||||
pr.upload_mesh(msh, False)
|
||||
matdefault = pr.load_material_default()
|
||||
eye = pr.matrix_identity()
|
||||
|
||||
camera = pr.Camera3D((30.0, 20.0, 30.0), (0.0, 0.0, 0.0), (0.0, 1.0, 0.0), 70.0,
|
||||
pr.CameraProjection.CAMERA_PERSPECTIVE)
|
||||
|
||||
# Export so we can inspect it
|
||||
pr.export_mesh(msh, "test-cube.obj")
|
||||
|
||||
while not pr.window_should_close():
|
||||
pr.update_camera(camera, pr.CameraMode.CAMERA_ORBITAL)
|
||||
pr.begin_drawing()
|
||||
pr.clear_background(pr.BLACK)
|
||||
pr.begin_mode_3d(camera)
|
||||
pr.draw_grid(10, 5.0)
|
||||
pr.draw_mesh(msh, matdefault, eye)
|
||||
pr.end_mode_3d()
|
||||
pr.end_drawing()
|
||||
pr.close_window()
|
|
@ -11,6 +11,8 @@
|
|||
# available at https://www.gnu.org/software/classpath/license.html.
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
||||
import weakref
|
||||
from array import array
|
||||
|
||||
from raylib import rl, ffi
|
||||
from raylib.colors import *
|
||||
|
@ -43,7 +45,7 @@ def makefunc(a):
|
|||
def func(*args):
|
||||
modified_args = []
|
||||
for (c_arg, arg) in zip(ffi.typeof(a).args, args):
|
||||
#print("arg:",str(arg), "c_arg.kind:", c_arg.kind, "c_arg:", c_arg, "type(arg):",str(type(arg)))
|
||||
# print("arg:",str(arg), "c_arg.kind:", c_arg.kind, "c_arg:", c_arg, "type(arg):",str(type(arg)))
|
||||
if c_arg.kind == 'pointer':
|
||||
if type(arg) == str:
|
||||
arg = arg.encode('utf-8')
|
||||
|
@ -53,7 +55,7 @@ def makefunc(a):
|
|||
arg = ffi.new("int *", arg)
|
||||
elif type(arg) is float:
|
||||
arg = ffi.new("float *", arg)
|
||||
elif type(arg) is list and str(c_arg) == "<ctype 'char * *'>":
|
||||
elif type(arg) is list and str(c_arg) == "<ctype 'char * *'>":
|
||||
arg = [ffi.new("char[]", x.encode('utf-8')) for x in arg]
|
||||
elif str(type(arg)) == "<class '_cffi_backend.__CDataOwn'>" and "*" not in str(arg): # CPython
|
||||
arg = ffi.addressof(arg)
|
||||
|
@ -74,10 +76,24 @@ def makefunc(a):
|
|||
|
||||
return func
|
||||
|
||||
global_weakkeydict = weakref.WeakKeyDictionary()
|
||||
|
||||
def makeStructHelper(struct):
|
||||
def func(*args):
|
||||
return ffi.new(f"struct {struct} *", args)[0]
|
||||
# print(struct, args)
|
||||
modified_args = []
|
||||
for (field, arg) in zip(ffi.typeof(struct).fields, args):
|
||||
# print("arg:", str(arg), "field:", field[1], "field type:", field[1].type, "type(arg):", str(type(arg)))
|
||||
if arg is None:
|
||||
arg = ffi.NULL
|
||||
elif (field[1].type.kind == 'pointer'
|
||||
and (str(type(arg)) == "<class 'numpy.ndarray'>"
|
||||
or isinstance(arg, (array, bytes, bytearray, memoryview)))):
|
||||
arg = ffi.from_buffer(field[1].type, arg)
|
||||
modified_args.append(arg)
|
||||
s = ffi.new(f"struct {struct} *", modified_args)[0]
|
||||
global_weakkeydict[s] = modified_args
|
||||
return s
|
||||
|
||||
return func
|
||||
|
||||
|
|
Reference in a new issue