How to load a gif animation in ARSession using ARKit-Scenekit?

I am working on an application using ARKit-Scenekit. I am able to render my 3D object, create overlay etc. I want to load a gif animation like a overlay in ARSession on tap of one of my child nodes. Is this possible?

I tried adding SKScene as a overlay to my SCNScene like below, and it looks good.

informationOverlay = InformationOverlayScene(size: self.sceneView.frame.size) self.sceneView.overlaySKScene = informationOverlay

But how to load this gif file in SKScene or SCNNode?

Replies

For me, I used some free websites to convert the gif file into multi-frame-images, then store them as an atlas, load them into a SKTextureAtlas, use SKAction to run those frames as an animation within a SKSpriteNode. Now you can use that sprite node to work as an overlay or as a material for ScnNode.



That way works well in my app (ARDraw)

SpriteKit currently does not support loading of animated .gif (nor .apng). At the moment, you use Image I/O to turn gif frames into individual UIImages, and from there into SKSpriteNodes or SKTextures. The example (in Objective-C but the Swift version is symantically equivalent):


NSURL* url = [NSURL fileURLWithPath:self.filename];
numberOfImages = (int)CGImageSourceGetCount( imgSrc );
for( int i = 0; i < numberOfImages; ++i ) {
     @autoreleasepool {             
          CGImageRef cgImage = CGImageSourceCreateImageAtIndex( imgSrc, i, nil );               
          UIImage* frame = [UIImage imageWithCGImage:cgImage];
          CGImageRelease( cgImage );
          [self.images addObject:result];
     }
}
CFRelease( imgSrc );

I followed CALayer approach to solve this. Upon tapping a child node i am displaying a gif image by creating animation using CALayer and loading it in diffuse.contents

let animation : CAKeyframeAnimation = createGIFAnimation(url: gifImageURL!)!

let layer = CALayer()

layer.bounds = CGRect(x: 0, y: 0, width:600, height:200)

layer.add(animation, forKey: "contents")

let newMaterial = SCNMaterial()

newMaterial.isDoubleSided = true

newMaterial.diffuse.contents = layer

let plane = SCNPlane(width: 5, height: 5)

plane.materials = [newMaterial]

let node = SCNNode(geometry: plane)

self.sceneView.scene.rootNode.addChildNode(node)

I am able to render the gif image in SCNNode but it is displaying only half of it(Right bottom most portion of gif is only visible). I tried below steps to rectify this but still in vain

  • Changing Plane's width/height
  • Changing the bounds of CALayer
  • Tried with different sizes of gif image