SCNVector3 could it be done, in ASObjC

I’m doing some code in SceneKit and wonder if SCNVector3 could it be done in ASObjC ??

The code I have is a translation from swift, I try to use SCNVector3Make() but no luck…

use framework "SceneKit"

func sceneSetup() {
    // 1
    let scene = SCNScene()

    // 2
    let BoxGeometry = SCNBox(width: 0.9, height: 0.9, length: 0.9, chamferRadius: 0.0)

    BoxGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
    let cube = SCNNode(geometry: BoxGeometry)
    cube.position = SCNVector3(x: 0, y: 0, z: -1)

    // 3
    sceneView.scene = scene
    sceneView.autoenablesDefaultLighting = true
    sceneView.allowsCameraControl = true

on sceneSetup()
	set scene to current application's SCNScene()'s scene()
	set BoxGeometry to current application's SCNBox's boxWithWidth:0.9 height:0.9 |length|:0.9 chamferRadius:0.0
	BoxGeometry's setValue:(current application's NSColor's redColor()) forKeyPath:"firstMaterial.diffuse.contents"
	set cube to current application's SCNNode's nodeWithGeometry:BoxGeometry
	scene's setValue:cube forKeyPath:"rootNode.addChildNode"
	-- Subclass of NSView
	sceneView's setScene:scene
	sceneView's setAutoenablesDefaultLighting:true
	sceneView's setAllowsCameraControl:true
end sceneSetup

it looks like SCNVector3 is a struct, so you can try using a record. Something like {x:0.0, y:0.0, z:0.0}.

Thanks Shane… your suggestion was working. But I also find other issue on my code
there I thought its was SCNBox I will set the position. But its the boxNode I set the position.
I figure it out when the return error said wrong instance.

set theBox to current application's SCNBox's boxWithWidth:5 height:5 |length|:5 chamferRadius:0.0
	theBox's setValue:(current application's NSColor's colorWithRed:0.175 green:0.615 blue:0.859 alpha:1.0) forKeyPath:"firstMaterial.diffuse.contents"
	-- The number of subdivisions SceneKit uses to smooth the geometry’s surface at render time.
	theBox's setValue:1.4 forKeyPath:"firstMaterial.diffuse.intensity"
	theBox's setSubdivisionLevel:0.3
	set boxNode to current application's SCNNode's nodeWithGeometry:theBox
	boxNode's setPosition:{x:0.0, y:0.0, z:15.0}
	theScene's rootNode's addChildNode:boxNode

When you say: it looks like a struct do you mean this: <arg type64='{SCNVector3=ddd}
in the bridgesupport file.

I mean when you look up the docs it says it’s a struct :grinning:.

Structs like NSRect are handled in ASObjC by passing records, using the component names as labels. I’m assuming the same happens here, although it’s not guaranteed. The best thing to do is to try to find a way of returning one.

1 Like

I did check the documentation and it looks like your suggestion to send a record works.

use framework "SceneKit"

set theScene to current application's SCNScene's scene()
set theCamera to current application's SCNCamera's camera()

set cameraNode to current application's SCNNode's node()
cameraNode's setCamera:theCamera
cameraNode's setPosition:{x:0.0, y:0.0, z:30.0}
cameraNode's setRotation:{x:0.0, y:0.0, z:0.0, w:0.0}
cameraNode's setScale:{x:0.0, y:0.0, z:0.0}
theScene's setValue:cameraNode forKeyPath:"rootNode.addChildNode"

But… its not like NSMakeRect()…
This do not work,
cameraNode’s setPosition:(current application’s SCNVector3Make(0.0, 0.0, 0.0))
Its not included in bridgesupport file, NSMakeRect does…

I could rotate the camera 45 degress
cameraNode’s setEulerAngles:{x:0.0 * pi / 180, y:0.0 * pi / 180, z:45.0 * pi / 180}

Its good to know its possible to use records… thanks.

Functions like NSMake() have to be supported directly, but the way records are bridged is generic, so should work for most (any?) struct. (Note that this wasn’t always so.)

That said, functions like NSRect() are fairly pointless – all they do is return a record you can make yourself.

i understand what you mean… its more of a taste and function :wink:

use framework "Foundation"

set {x, y, width, height} to {0, 0, 1024, 720}
set {theOrigin, theSize} to {{x:x, y:y}, {width:width, height:height}}
set theWidth to theSize's width
set theHeight to theSize's height
log theWidth
log theHeight

set x of theOrigin to 50
set y of theOrigin to 50
log x
log y
set theFrame to {theOrigin's x, theOrigin's y, theSize's width, theSize's height}
log theFrame
log {theOrigin, theSize}