iPhone 3Dルーレット

SceneKitでルーレットに見える。。。ようなiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNScene *scene;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self createScene];

    [self createRoulette];

    [self createCamera];

    [self createLight];

}

– (void)createScene

{

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

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

    sv.backgroundColor = [UIColor colorWithHue:0.2 saturation:0.4 brightness:1 alpha:1];

    sv.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));

    sv.scene = [SCNScene scene];

    [self.view addSubview:sv];

    

    self.scene = sv.scene;

}

– (void)createRoulette

{

    SCNBox *base = [SCNBox boxWithWidth:20 height:1 length:20 chamferRadius:1];

    base.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.3 saturation:0.5 brightness:1 alpha:1];

    SCNNode *baseNode = [SCNNode nodeWithGeometry:base];

    baseNode.physicsBody = [SCNPhysicsBody staticBody];

    baseNode.physicsBody.friction = 0;

    [self.scene.rootNode addChildNode:baseNode];

    

    SCNCylinder *spindle = [SCNCylinder cylinderWithRadius:0.2 height:8];

    spindle.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.3 saturation:0.5 brightness:1 alpha:1];

    SCNNode *spindleNode = [SCNNode nodeWithGeometry:spindle];

    spindleNode.name = @”spindle”;

    spindleNode.position = SCNVector3Make(0, 1, 0);

    spindleNode.physicsBody = [SCNPhysicsBody staticBody];

    spindleNode.physicsBody.friction = 0;

    [self.scene.rootNode addChildNode:spindleNode];

    

    SCNTube *turnTable = [SCNTube tubeWithInnerRadius:0.21 outerRadius:9.1 height:0.3];

    turnTable.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.1 saturation:0.4 brightness:1 alpha:1];

    SCNNode *turnTableNode = [SCNNode nodeWithGeometry:turnTable];

    turnTableNode.name = @”turnTable”;

    turnTableNode.position = SCNVector3Make(0, 1, 0);

    turnTableNode.physicsBody = [SCNPhysicsBody dynamicBody];

    turnTableNode.physicsBody.physicsShape = [SCNPhysicsShape shapeWithGeometry:turnTable options:@{SCNPhysicsShapeTypeKey:SCNPhysicsShapeTypeConcavePolyhedron}];

    turnTableNode.physicsBody.rollingFriction = 0.5;

    turnTableNode.physicsBody.angularDamping = 0.2;

    turnTableNode.physicsBody.friction = 1.0;

    turnTableNode.physicsBody.velocityFactor = SCNVector3Make(0, 1, 0);

    [self.scene.rootNode addChildNode:turnTableNode];

    

    

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

        float x = 8 * cos(i * M_PI / 10.0) – 0.5;

        float z = 8 * sin(i * M_PI / 10.0) + 0.5;

        SCNText *t = [SCNText textWithString:[NSString stringWithFormat:@”%d”, i+1] extrusionDepth:0.1];

        t.firstMaterial.diffuse.contents = [UIColor darkGrayColor];

        t.font = [UIFont systemFontOfSize:1];

        SCNNode *textNode = [SCNNode nodeWithGeometry:t];

        textNode.transform = SCNMatrix4Rotate(textNode.transform, –M_PI/2.0, 1, 0, 0);

        textNode.transform = SCNMatrix4Translate(textNode.transform, x, 0.5, z);

        

        [turnTableNode addChildNode:textNode];

        

        SCNBox *bar = [SCNBox boxWithWidth:1 height:0.2 length:0.2 chamferRadius:1];

        bar.firstMaterial.diffuse.contents = [UIColor redColor];

        SCNNode *barNode = [SCNNode nodeWithGeometry:bar];

        barNode.transform = SCNMatrix4Translate(barNode.transform, 7.7, 0.1, 0);

        barNode.transform = SCNMatrix4Rotate(barNode.transform, (i + 0.5) * M_PI/10.0, 0, 1, 0);

        [turnTableNode addChildNode:barNode];

        

    }

    

    SCNTube *outer = [SCNTube tubeWithInnerRadius:8.8 outerRadius:9 height:1];

    outer.firstMaterial.diffuse.contents = [UIColor lightGrayColor];

    SCNNode *outerNode = [SCNNode nodeWithGeometry:outer];

    outerNode.position = SCNVector3Make(0, 4, 0);

    outerNode.physicsBody = [SCNPhysicsBody dynamicBody];

    outerNode.physicsBody.physicsShape = [SCNPhysicsShape shapeWithGeometry:outer options:@{SCNPhysicsShapeTypeKey:SCNPhysicsShapeTypeConcavePolyhedron}];

    outerNode.physicsBody.friction = 1.0;

    outerNode.physicsBody.velocityFactor = SCNVector3Make(0, 1, 0);

    outerNode.physicsBody.mass = 1000;

    [self.scene.rootNode addChildNode:outerNode];

    

    

    SCNTube *inner = [SCNTube tubeWithInnerRadius:6.6 outerRadius:6.8 height:1];

    inner.firstMaterial.diffuse.contents = [UIColor lightGrayColor];

    SCNNode *innerNode = [SCNNode nodeWithGeometry:inner];

    innerNode.position = SCNVector3Make(0, 2, 0);

    innerNode.physicsBody = [SCNPhysicsBody staticBody];

    innerNode.physicsBody.physicsShape = [SCNPhysicsShape shapeWithGeometry:outer options:@{SCNPhysicsShapeTypeKey:SCNPhysicsShapeTypeConcavePolyhedron}];

    innerNode.physicsBody.friction = 1.0;

    innerNode.physicsBody.velocityFactor = SCNVector3Make(0, 1, 0);

    [self.scene.rootNode addChildNode:innerNode];

    

}

– (void)createCamera

{

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, 20, 20);

    [self.scene.rootNode addChildNode:camera];

    

    SCNNode *target = [self.scene.rootNode childNodeWithName:@”spindle” recursively:NO];

    camera.constraints = @[[SCNLookAtConstraint lookAtConstraintWithTarget:target]];

}

– (void)createLight

{

    SCNLight *light = [SCNLight light];

    light.type = SCNLightTypeOmni;

    SCNNode *lightNode = [SCNNode node];

    lightNode.position = SCNVector3Make(0, 80, 80);

    lightNode.light = light;

    [self.scene.rootNode addChildNode:lightNode];

}

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

{

    SCNNode *turnTable = [self.scene.rootNode childNodeWithName:@”turnTable” recursively:NO];

    turnTable.physicsBody.angularVelocity = SCNVector4Make(0, 5, 0, 1);

    

    SCNSphere *ball = [SCNSphere sphereWithRadius:0.5];

    ball.firstMaterial.diffuse.contents = [UIColor yellowColor];

    SCNNode *ballNode = [SCNNode nodeWithGeometry:ball];

    ballNode.position = SCNVector3Make(8, 2, 0);

    ballNode.physicsBody = [SCNPhysicsBody dynamicBody];

    [self.scene.rootNode addChildNode:ballNode];

    

    ballNode.physicsBody.velocity = SCNVector3Make(-1, 0, 35);

}

– (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end