
アクロバットのインサイドループっぽく動くiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController () <SCNSceneRendererDelegate>
@property (nonatomic, weak) SCNView *sceneView;
@property (nonatomic) BOOL turn;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createCamera];
}
– (void)setupScene {
SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];
sv.scene = [SCNScene scene];
sv.backgroundColor = [UIColor colorWithHue:0.5 saturation:0.2 brightness:1 alpha:1];
sv.allowsCameraControl = YES;
sv.autoenablesDefaultLighting = YES;
sv.scene.physicsWorld.gravity = SCNVector3Make(0, 0, 0);
sv.delegate = self;
[self.view addSubview:sv];
self.sceneView = sv;
}
– (void)createPlane {
SCNNode *plane = [SCNNode node];
plane.position = SCNVector3Make(-10, –5, 0);
[self.sceneView.scene.rootNode addChildNode:plane];
SCNBox *body = [SCNBox boxWithWidth:2 height:0.2 length:0.2 chamferRadius:0];
body.firstMaterial.diffuse.contents = [UIColor whiteColor];
SCNNode *bodyNode = [SCNNode nodeWithGeometry:body];
[plane addChildNode:bodyNode];
for (int i=0; i<2; i++) {
SCNBox *wing = [SCNBox boxWithWidth:0.5 height:0.04 length:1 chamferRadius:0];
wing.firstMaterial.diffuse.contents = [UIColor blueColor];
SCNNode *wingNode =[SCNNode nodeWithGeometry:wing];
wingNode.position = SCNVector3Make(0.2, –0.04, i==0 ? 0.5 : –0.5);
wingNode.rotation = SCNVector4Make(0, 1, 0, i==0 ? –0.3 : 0.3);
[plane addChildNode:wingNode];
}
for (int i=0; i<3; i++) {
SCNBox *tail = [SCNBox boxWithWidth:0.2 height:0.4 length:0.02 chamferRadius:0];
tail.firstMaterial.diffuse.contents = [UIColor blueColor];
SCNNode *tailNode =[SCNNode nodeWithGeometry:tail];
tailNode.pivot = SCNMatrix4MakeTranslation(0, –0.2, 0);
tailNode.pivot = SCNMatrix4Rotate(tailNode.pivot, –0.4, 0, 0, 1);
tailNode.position = SCNVector3Make(-0.9, 0.01, 0);
switch (i) {
case 0:
tailNode.rotation = SCNVector4Make(1, 0, 0, M_PI * 0.5);
break;
case 1:
tailNode.rotation = SCNVector4Make(1, 0, 0, –M_PI * 0.5);
break;
default:
break;
}
[plane addChildNode:tailNode];
}
plane.name = @”plane”;
plane.physicsBody = [SCNPhysicsBody dynamicBody];
plane.physicsBody.damping = 0.9;
plane.physicsBody.angularDamping = 0.9;
plane.physicsBody.angularVelocityFactor = SCNVector3Make(0, 0, 1);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[plane removeFromParentNode];
});
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.position = SCNVector3Make(0, 0, 15);
[self.sceneView.scene.rootNode addChildNode:camera];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
SCNNode *plane = [self.sceneView.scene.rootNode childNodeWithName:@”plane” recursively:NO];
if (!plane) {
[self createPlane];
return;
}
self.turn = YES;
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
self.turn = NO;
}
– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time {
SCNNode *plane = [self.sceneView.scene.rootNode childNodeWithName:@”plane” recursively:NO];
SCNVector3 o = plane.presentationNode.position;
if (self.turn) {
SCNVector3 vy = [plane.presentationNode convertPosition:SCNVector3Make(5, 5, 0) toNode:self.sceneView.scene.rootNode];
vy = SCNVector3Make(vy.x – o.x, vy.y – o.y, 0);
SCNVector3 atPosition = [plane.presentationNode convertPosition:SCNVector3Make(0.35, 0, 0) toNode:self.sceneView.scene.rootNode];
atPosition = SCNVector3Make(atPosition.x – o.x, atPosition.y – o.y, 0);
[plane.physicsBody applyForce:SCNVector3Make(vy.x, vy.y, 0) atPosition:atPosition impulse:NO];
}
SCNVector3 vx = [plane.presentationNode convertPosition:SCNVector3Make(10, 0, 0) toNode:self.sceneView.scene.rootNode];
vx = SCNVector3Make(vx.x – o.x, vx.y – o.y, 0);
[plane.physicsBody applyForce:vx impulse:NO];
}
@end