Search code examples
iosscenekit

Rotate my SceneKit material


I'm taking images with AVCapturePhotoOutput and then using their JPEG representation as the texture on a SceneKit SCNPlane that is the same aspect ratio as the image:

let image = UIImage(data: dataImage!)
let rectangle = SCNPlane(width:9, height:12)
let rectmaterial = SCNMaterial()
rectmaterial.diffuse.contents = image
rectmaterial.isDoubleSided = true
rectangle.materials = [rectmaterial]
let rectnode = SCNNode(geometry: rectangle)
let pos = sceneSpacePosition(inFrontOf: self.pictCamera, atDistance: 16.5)  // 16.5 is arbitrary, but makes the rectangle the same size as the camera
rectnode.position = pos
rectnode.orientation = self.pictCamera.orientation
pictView.scene?.rootNode.addChildNode(rectnode)

sceneSpacePosition is a bit of code that can be found here on SO that maps CoreMotion into SceneKit orientation. It is used to place the rectangle, which does indeed appear at the right location with the right size. All very cool.

The problem is that the image is rotated 90 degrees to the rectangle. So I did the obvious:

rectmaterial.diffuse.contentsTransform = SCNMatrix4MakeRotation(Float.pi / 2, 0, 0, 1)

This does not work property; the resulting image is unrecognizable. It appears that one small part of the image has been stretched to a huge size. I thought it might be the axis, but I tried all three with the same result.

Any ideas?


Solution

  • You are rotating on the upper left corner as suggested by Alain T. If you move your image down, you may get the rotation you were expecting.

    Try this:

    let translation = SCNMatrix4MakeTranslation(0, -1, 0)
    let rotation = SCNMatrix4MakeRotation(Float.pi / 2, 0, 0, 1)
    let transform = SCNMatrix4Mult(translation, rotation)
    rectmaterial.diffuse.contentsTransform = transform