
商品を3Dでくるっと見せるショーケースっぽいiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController () <SCNSceneRendererDelegate>
@property (nonatomic, weak) SCNView *sceneView;
@property (nonatomic, weak) SCNScene *scene;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor lightGrayColor];
[self setupScene];
[self createShowcase];
[self createItems];
[self createCamera];
[self createLight];
}
– (void)setupScene {
float w = CGRectGetMaxX(self.view.bounds);
SCNView *sv = [[SCNView alloc] initWithFrame:CGRectMake(0, 0, w, w)];
sv.backgroundColor = [UIColor colorWithRed:125.0/255.0 green:138.0/255.0 blue:46.0/255.0 alpha:1];
sv.scene = [SCNScene scene];
sv.delegate = self;
[self.view addSubview:sv];
self.scene = sv.scene;
self.sceneView = sv;
}
– (void)createShowcase {
for (int i=0; i<3; i++) {
SCNCylinder *disk = [SCNCylinder cylinderWithRadius:2 height:0.2];
disk.firstMaterial.diffuse.contents = [UIColor whiteColor];
SCNNode *diskNode = [SCNNode nodeWithGeometry:disk];
diskNode.name = [NSString stringWithFormat:@”disk%d”, i];
diskNode.position = SCNVector3Make(i * 8 – 8, –10, 0);
[self.scene.rootNode addChildNode:diskNode];
}
SCNCylinder *mainDisk = [SCNCylinder cylinderWithRadius:8 height:0.2];
mainDisk.firstMaterial.diffuse.contents = [UIColor whiteColor];
SCNNode *maindiskNode = [SCNNode nodeWithGeometry:mainDisk];
maindiskNode.name = @”mainDisk”;
[self.scene.rootNode addChildNode:maindiskNode];
}
– (void)createItems {
SCNBox *box = [SCNBox boxWithWidth:4 height:4 length:4 chamferRadius:0];
box.firstMaterial.diffuse.contents = [UIColor colorWithRed:201.0/255.0 green:215.0/255.0 blue:135.0/255.0 alpha:1];
SCNTorus *ball = [SCNTorus torusWithRingRadius:2 pipeRadius:1];
ball.firstMaterial.diffuse.contents = [UIColor colorWithRed:255.0/255.0 green:192.0/255.0 blue:169.0/255.0 alpha:1];
SCNPyramid *pyramid = [SCNPyramid pyramidWithWidth:4 height:4 length:4];
pyramid.firstMaterial.diffuse.contents = [UIColor colorWithRed:255.0/255.0 green:133.0/255.0 blue:152.0/255.0 alpha:1];
NSArray *geometories = @[box, ball, pyramid];
for (int i=0; i<3; i++) {
SCNNode *disk = [self.scene.rootNode childNodeWithName:[NSString stringWithFormat:@”disk%d”, i] recursively:false];
SCNNode *item = [SCNNode nodeWithGeometry:geometories[i]];
item.name = @”item”;
item.position = SCNVector3Make(disk.position.x, disk.position.y + 3, disk.position.z);
[self.scene.rootNode addChildNode:item];
}
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.position = SCNVector3Make(0, 2, 25);
[self.scene.rootNode addChildNode:camera];
}
– (void)createLight {
SCNLight *light = [SCNLight light];
light.type = SCNLightTypeOmni;
SCNNode *lightNode = [SCNNode node];
lightNode.light = light;
lightNode.position = SCNVector3Make(0, 20, 60);
[self.scene.rootNode addChildNode:lightNode];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInView:self.sceneView];
NSArray *hits = [self.sceneView hitTest:p options:nil];
for (SCNHitTestResult *hit in hits) {
if ([hit.node.name isEqual:@”item”]) {
hit.node.physicsBody = [SCNPhysicsBody dynamicBody];
[hit.node.physicsBody applyForce:SCNVector3Make(0, 5, 0) impulse:YES];
[hit.node.physicsBody applyTorque:SCNVector4Make(0, 1, 0, 2.0) impulse:YES];
[self showMainDisk:hit.node.geometry.copy];
}
}
}
– (void)showMainDisk:(SCNGeometry*)geometory {
SCNNode *old = [self.scene.rootNode childNodeWithName:@”mainItem” recursively:NO];
if (old) {
[old removeFromParentNode];
}
SCNNode *mainItem = [SCNNode nodeWithGeometry:geometory];
mainItem.name = @”mainItem”;
mainItem.scale = SCNVector3Make(2.2, 2.2, 2.2);
mainItem.position = SCNVector3Make(0, 8.0, 0);
[mainItem runAction:[SCNAction repeatActionForever:[SCNAction sequence:@[[SCNAction rotateByX:0 y:1 z:0 duration:0.5], [SCNAction rotateByX:1 y:0 z:0 duration:0.5]]]]];
[self.scene.rootNode addChildNode:mainItem];
}
– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time
{
[self.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop) {
if ([child.name isEqual:@”item”]) {
if (child.presentationNode.position.y < –10 && child.physicsBody) {
child.physicsBody = nil;
[child runAction:[SCNAction moveTo:SCNVector3Make(child.position.x, –7, child.position.z) duration:0.5]];
}
}
}];
}
@end