Forum Archive

SceneKit SCNNode simd... properties

pulbrich

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

JonB

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-ctypes

Basically, you alloc your vector, larger than you need, check alignment, then offset into it.

pulbrich

Other values are also wrong. I will look later at your proposal, I am now not at my desk. But thanks!

pulbrich

@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.

JonB

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.

pulbrich

@JonB

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.