Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
SceneKit SCNNode simd... properties
-
Greetings!
Does anybody have a working example of using the node’s simd... methods?
E.g., I seem to be unable to get the simdScale, regardless if I try to use the default encoding or supply restype and argtypes.
See:
from objc_util import * from ctypes import * load_framework('SceneKit') simd_float3 = c_float * 3 SCNNode = ObjCClass('SCNNode') aNode = SCNNode.alloc().init() p5 = aNode.simdScale(restype=simd_float3, argtypes=[]) print('p5[0]= ', p5[0]) #results in p5[0]= -8.552001213509498e-39, should be 1.0
I have tried a few variations, including restype as c_void_p, but nothing doing. The counterpart properties (aNode.scale()...) work as advertised.
Thanks in advance, Peter
-
Do p5[1], p5[2] show valid values?
The problem I suspect is that a simd variable wants to be aligned on 16 byte(?) boundaries. The way you did it probably only guarantees 4 or maybe 8 byte alignment.
One workaround would be to implement something like this
https://stackoverflow.com/questions/8658813/control-memory-alignment-in-python-ctypesBasically, you alloc your vector, larger than you need, check alignment, then offset into it.
-
Other values are also wrong. I will look later at your proposal, I am now not at my desk. But thanks!
-
@JonB : With the proposed function ctypes_alloc_aligned I can get an aligned memory chunk but I cannot tell simdScale to write the result into it, methinks.
-
Oh, right, simdScale would be allocating the memory and providing it to you, so would already be aligned.
Can you try restype=c_uint32*3 ? Then print p5[0], p5[1], p5[2].
Also, can you print (node.simdScale.encoding).
Out of curiosity, why do you want to use the simd versions of functions? You won't be able to do any vectorised math with them in pythonista/ctypes (maybe with numpy), or make use of any of the little short cuts that vector types allow. I'd think that SCNVector3, etc would work fine in most cases.
-
Here:
from objc_util import * from ctypes import * import ctypes lb = 24 def printHex(buf): print( ":".join("{:02x}".format(c) for c in buf)) load_framework('SceneKit') simd_float3 = c_uint32 * 3 SCNNode = ObjCClass('SCNNode') aNode = SCNNode.alloc().init() p5 = aNode.simdScale(restype=simd_float3, argtypes=[]) buf = string_at(byref(p5), lb) printHex(buf) print('p5[0]-[2] = ', p5[0], p5[1], p5[2]) #results in: #80:0d:52:80:02:00:00:00:dc:26:de:01:00:00:00:00:00:00:00:00:00:00:00:00 # #p5[0]-[2] = 2152861056 2 31336156
encoding: b'16@0:8' i.e., restype: void/int
The first 8 bytes of the result buffer looks like an address, if (for curiosity) you invoke ObjCInstance on it it returns the Node object aNode. Why???
The only reason I am trying to make the simd properties work is that the old ones might get phased out at some point in the future. Of course until then I can simply redirect the simd calls to the non-simd siblings.