Display animated content with SCNPlane - IOS

Hello,


In my scene, I am trying to create a plane, of which the surface displays animated contents. I tried doing so by creating a Core Animation Layer and then setting that layer as the content of the SCNPlane, as the code below shows.


var images = [CGImage]()
let count = CGImageSourceGetCount(source!)
    
for i in 0..<count {
     if let image = CGImageSourceCreateImageAtIndex(source!, i, nil) {
          images.append(image)
     }
}

let layer = CALayer()
layer.contents = images

let animation = CAKeyframeAnimation(keyPath: "contents")
animation.values = images
animation.repeatCount = .greatestFiniteMagnitude
animation.duration = 2
layer.add(animation, forKey: "key frame animation")

let imagePlane = SCNPlane(width: self.sceneView.bounds.width / 3000, height: self.sceneView.bounds.height / 3000)
imagePlane.firstMaterial?.diffuse.contents = layer
imagePlane.firstMaterial?.lightingModel = .constant

let wrapperNode = SCNNode(geometry: imagePlane)


However, the plane does not show up in my scene. I do not know what went wrong. Any advice would be greatly appreciated!


Thanks!

Replies

What happens if you change the size of the plane? And what is the position of the wrapper node?

Dividing by 3000 will make your plane quite small. I did the following where the material is set to transparent green and divisor is 300. I could see a green plane as in the attached image. (does image embedding work? I can see the image only when I edit the post).


   
     let imagePlane = SCNPlane(width: self.gameView.bounds.width / 300, height: self.gameView.bounds.height / 300  imagePlane.firstMaterial?.diffuse.contents =  NSColor.green.withAlphaComponent(0.5)/
     imagePlane.firstMaterial?.lightingModel = .constant

     let wrapperNode = SCNNode(geometry: imagePlane)
     wrapperNode.position = SCNVector3Make(0, 4.0, 0)
     scene.rootNode.addChildNode(wrapperNode)

I tried playing with the size of the plane. I don't think that is where the issue is, because if I set the content of the material as an UIImage, the image is displayed on the plane. Or like what you did, if I set the material content to a color, it would get displayed. The problem occurs when I set the contents of the plane as a CALayer in order to display animated content through an array of CGImages.


Currently, the node is at the root node. I just want to make sure I can see the content first.


I can't see the image.

Hi,


I see; I tried created your method in a iOS app using an animated PNG. The PNG file is being loaded but I get a crash in SceneKit. I am using Metal 2 as the renderer on an iPhone 6s running iOS 11 Beta 3.


#00x00000001959c0980 in C3DTextureGetIOSurface ()

#10x0000000195b4ab40 in -[SCNTextureSource metalTextureWithEngineContext:textureSampler:nextFrameTime:] ()

It just so happens what you are doing may be relevant for I project I am working on.

Not sure about your problem since your code too few. Perhaps some of your variants such as layer, animation... are auto released before running by Swift (I have seen that happened in my apps).


My solution to use 2D animations is different from you: use SKSpriteNode and wrapped it by SKScene then put all in a node. Works so well