
秤のプレートに箱を落とすiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController () <SCNSceneRendererDelegate>
@property (nonatomic, weak) SCNView *sceneView;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createPlate];
[self createLabel];
[self createCamera];
}
– (void)setupScene {
SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];
sv.delegate = self;
sv.scene = [SCNScene scene];
sv.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1];
sv.autoenablesDefaultLighting = YES;
[self.view addSubview:sv];
self.sceneView = sv;
}
– (void)createPlate {
SCNCylinder *plate = [SCNCylinder cylinderWithRadius:20 height:1];
plate.firstMaterial.diffuse.contents = [UIColor colorWithWhite:0.4 alpha:1];
SCNNode *plateNode = [SCNNode nodeWithGeometry:plate];
plateNode.name = @”plate”;
plateNode.physicsBody = [SCNPhysicsBody staticBody];
[self.sceneView.scene.rootNode addChildNode:plateNode];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
SCNBox *box = [SCNBox boxWithWidth:3 height:3 length:3 chamferRadius:0];
box.firstMaterial.diffuse.contents = [UIColor colorWithHue:arc4random_uniform(10) * 0.1 saturation:0.5 brightness:1 alpha:1];
SCNNode *boxNode = [SCNNode nodeWithGeometry:box];
boxNode.name = @”box”;
boxNode.position = SCNVector3Make(((int)arc4random() % 8) – 4, 20, ((int)arc4random() % 8) – 4);
boxNode.physicsBody = [SCNPhysicsBody dynamicBody];
boxNode.physicsBody.restitution = 0.6;
[self.sceneView.scene.rootNode addChildNode:boxNode];
}
– (void)createLabel {
SCNText *text = [SCNText textWithString:@”0kg” extrusionDepth:1];
text.firstMaterial.diffuse.contents = [UIColor orangeColor];
text.alignmentMode = kCAAlignmentCenter;
text.font = [UIFont systemFontOfSize:5];
SCNNode *textNode = [SCNNode nodeWithGeometry:text];
textNode.name = @”text”;
textNode.position = SCNVector3Make(0, –5, 20);
[self.sceneView.scene.rootNode addChildNode:textNode];
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.position = SCNVector3Make(0, 5, 70);
[self.sceneView.scene.rootNode addChildNode:camera];
}
– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time {
SCNNode *plate = [self.sceneView.scene.rootNode childNodeWithName:@”plate” recursively:NO];
float weight = 0;
NSMutableArray *sortedBox = [[[[self.sceneView.scene.rootNode childNodes] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@”name == %@”, @”box”]] sortedArrayUsingComparator:^NSComparisonResult(SCNNode *n1, SCNNode *n2) {
return n1.presentationNode.position.y > n2.presentationNode.position.y;
}] mutableCopy];
NSMutableArray *hits = [NSMutableArray array];
[hits addObject:plate];
for (SCNNode *n in sortedBox) {
NSArray *contacts = [self.sceneView.scene.physicsWorld contactTestWithBody:n.physicsBody options:@{SCNPhysicsTestSearchModeKey : SCNPhysicsTestSearchModeAll}];
for (SCNPhysicsContact *c in contacts) {
if (c && [hits containsObject:c.nodeB]) {
weight += n.physicsBody.mass;
[hits addObject:n];
break;
}
}
}
NSString *s = [NSString stringWithFormat:@”%.0fkg”, weight];
SCNText *t = (SCNText *)[self.sceneView.scene.rootNode childNodeWithName:@”text” recursively:NO].geometry;
if (![t.string isEqual:s]) {
t.string = s;
}
}
@end