iPhoneカメラ円周

カメラを円周上にまわすPhoneアプリのサンプルコードを描いてみます

#import “ViewController.h”

@import SceneKit;

@import SpriteKit;

@interface ViewController () <SCNSceneRendererDelegate>

@property (nonatomic, weak) SCNScene *scene;

@property (nonatomic, weak) SCNView *sceneView;

@property (nonatomic, weak) SKView *spriteView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createObjects];

    [self createCamera];

    [self createCameraController];

}

– (void)setupScene {

    float w = CGRectGetMaxX(self.view.bounds);

    SCNView *sceneView = [[SCNView alloc] initWithFrame:CGRectMake(0, 0, w, w)];

    sceneView.backgroundColor = [UIColor colorWithRed:239.0/255.0 green:236.0/255.0 blue:202.0/255.0 alpha:1];

    sceneView.scene = [SCNScene scene];

    sceneView.delegate = self;

    [self.view addSubview:sceneView];

    

    self.scene = sceneView.scene;

    self.sceneView = sceneView;

    

    SKView *spriteView = [[SKView alloc] initWithFrame:CGRectMake(0, w, w, CGRectGetMaxY(self.view.bounds) – w)];

    [self.view addSubview:spriteView];

    SKScene *skscene = [SKScene sceneWithSize:spriteView.frame.size];

    skscene.backgroundColor = [UIColor colorWithRed:167.0/255.0 green:163.0/255.0 blue:126.0/255.0 alpha:1];

    [spriteView presentScene:skscene];

    self.spriteView = spriteView;

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.name = @”camera”;

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, 5, 40);

    [self.scene.rootNode addChildNode:camera];

    

    camera.constraints = @[[SCNLookAtConstraint lookAtConstraintWithTarget:[self.scene.rootNode childNodeWithName:@”center” recursively:false]]];

}

– (void)createObjects {

    for (int i=0; i<20; i++) {

        float dAngle = M_PI / 5.0;

        float x = 10 * cos(dAngle * i);

        float z = 10 * sin(dAngle * i);

        SCNSphere *ball = [SCNSphere sphereWithRadius:2];

        ball.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.05 * i saturation:0.7 brightness:1 alpha:1];

        SCNNode *ballNode = [SCNNode nodeWithGeometry:ball];

        ballNode.position = SCNVector3Make(x, i – 8, z);

        [self.scene.rootNode addChildNode:ballNode];

    }

    

    SCNCylinder *c = [SCNCylinder cylinderWithRadius:0.2 height:30];

    c.firstMaterial.diffuse.contents = [UIColor colorWithRed:0/255.0 green:47.0/255.0 blue:47.0/255.0 alpha:1];

    SCNNode *cNode = [SCNNode nodeWithGeometry:c];

    cNode.name = @”center”;

    [self.scene.rootNode addChildNode:cNode];

    

    [cNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByAngle:0.1 aroundAxis:SCNVector3Make(0, 1, 0) duration:1.0]]];

}

– (void)createCameraController {

    SKShapeNode *line = [SKShapeNode shapeNodeWithCircleOfRadius:100];

    line.position = CGPointMake(CGRectGetMidX(self.spriteView.bounds), CGRectGetMidY(self.spriteView.bounds));

    line.fillColor = [UIColor clearColor];

    line.strokeColor = [UIColor colorWithRed:0/255.0 green:47.0/255.0 blue:47.0/255.0 alpha:1];

    line.lineWidth = 5;

    [self.spriteView.scene addChild:line];

    

    UIColor *color = [UIColor colorWithRed:4.0/255.0 green:99.0/255.0 blue:128.0/255.0 alpha:1];

    SKNode *cameraMark = [SKNode node];

    cameraMark.name = @”mark”;

    cameraMark.position = CGPointMake(line.position.x100, line.position.y);

    

    SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:color size:CGSizeMake(30, 20)];

    [cameraMark addChild:body];

    SKShapeNode *lens = [SKShapeNode shapeNodeWithEllipseInRect:CGRectMake(20, –10, 10, 20)];

    lens.fillColor = color;

    lens.strokeColor = [UIColor clearColor];

    [cameraMark addChild:lens];

    [self.spriteView.scene addChild:cameraMark];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    

    SKNode *mark = [self.spriteView.scene childNodeWithName:@”mark”];

    CGPoint p = CGPointMake(CGRectGetMidX(self.spriteView.bounds), CGRectGetMidY(self.spriteView.bounds));

    float s = mark.zRotation + M_PI;

    float e = s – M_PI / 2.0;

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:p radius:100 startAngle:s endAngle:e clockwise:NO];

    [mark runAction:[SKAction followPath:path.CGPath asOffset:NO orientToPath:YES duration:1.0] completion:^{

        mark.zRotation = e – M_PI;

    }];

    

}

– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time

{

    SKNode *mark = [self.spriteView.scene childNodeWithName:@”mark”];

    SCNNode *camera = [self.scene.rootNode childNodeWithName:@”camera” recursively:false];

    camera.constraints = nil;

    camera.position = SCNVector3Make(40.0 * cos(mark.zRotation), 0, 40.0 * sin(mark.zRotation));

    camera.constraints = @[[SCNLookAtConstraint lookAtConstraintWithTarget:[self.scene.rootNode childNodeWithName:@”center” recursively:false]]];

}

@end