6

私は SceneKit の使い方を学ぼうとしています。例として、SDK を使用して太陽系を構築しようと考えました。SCNode オブジェクトを追加して、パターンや照明などのマテリアル プロパティを構成できます。また、惑星を回転させることはできますが、特定の経路に沿って惑星を「回転」させる方法がわかりません。

これまでの私のコードは次のようになります。

// create a new scene
SCNScene *scene = [SCNScene scene];

// create and add a camera to the scene
SCNNode *cameraNode = [SCNNode node];
cameraNode.camera = [SCNCamera camera];
[scene.rootNode addChildNode:cameraNode];

// place the camera
cameraNode.position = SCNVector3Make(0, 0, 2);

// create and add a 3d sphere - sun to the scene
SCNNode *sphereNode = [SCNNode node];
sphereNode.geometry = [SCNSphere sphereWithRadius:0.3];
[scene.rootNode addChildNode:sphereNode];

// create and configure a material
SCNMaterial *material = [SCNMaterial material];
material.diffuse.contents = [NSImage imageNamed:@"SunTexture"];
material.specular.contents = [NSColor whiteColor];
material.specular.intensity = 0.2;
material.locksAmbientWithDiffuse = YES;

// set the material to the 3d object geometry
sphereNode.geometry.firstMaterial = material;

// create and add a 3d sphere - earth to the scene
SCNNode *earthNode = [SCNNode node];
earthNode.geometry = [SCNSphere sphereWithRadius:0.15];
NSLog(@"Sun position = %f, %f, %f", sphereNode.position.x, sphereNode.position.y, sphereNode.position.z);
earthNode.position = SCNVector3Make(0.7, 0.7, 0.7);
NSLog(@"Earth position = %f, %f, %f", earthNode.position.x, earthNode.position.y, earthNode.position.z);
//earthNode.physicsBody = [SCNPhysicsBody dynamicBody];
[scene.rootNode addChildNode:earthNode];

SCNMaterial *earthMaterial = [SCNMaterial material];
earthMaterial.diffuse.contents = [NSImage imageNamed:@"EarthTexture"];

earthNode.geometry.firstMaterial = earthMaterial;

AppleDocs のどこかで、ルート ノードではなく太陽の座標系に惑星を追加する必要があることを読みましたが、とにかくそれを正しく理解しているかどうかはわかりません。

これを行う方法を教えてください。

4

1 に答える 1

14

SceneKit はパスに沿ったアニメーション API を提供しません。ただし、太陽系のようなものを設定するにはいくつかの方法があります。

  1. オーラリーを見たことがありますか?これは、SCNNodeのドキュメントで言及されているモデルです。これは、「シーン グラフの概要」スライドでWWDC プレゼンテーションが行うことでもあります。秘訣は、1 つのノードを使用して、太陽の周りの惑星の公転の参照フレームを表すことです。天球儀で惑星を保持するアーマチュアのように、このノードを中心軸を中心に回転させると、接続する子ノード円形のパスをたどります。これに関連するコードはASCSceneGraphSummary.m、そのサンプル コード プロジェクトにあります (ここではノード階層のセットアップのみを示すように要約されています)。

    // Sun
    _sunNode = [SCNNode node];
    _sunNode.position = SCNVector3Make(0, 30, 0);
    [self.contentNode addChildNode:_sunNode];
    
    // Earth-rotation (center of rotation of the Earth around the Sun)
    SCNNode *earthRotationNode = [SCNNode node];
    [_sunNode addChildNode:earthRotationNode];
    
    // Earth-group (will contain the Earth, and the Moon)
    _earthGroupNode = [SCNNode node];
    _earthGroupNode.position = SCNVector3Make(15, 0, 0);
    [earthRotationNode addChildNode:_earthGroupNode];
    
    // Earth
    _earthNode = [_wireframeBoxNode copy];
    _earthNode.position = SCNVector3Make(0, 0, 0);
    [_earthGroupNode addChildNode:_earthNode];
    
    // Moon-rotation (center of rotation of the Moon around the Earth)
    SCNNode *moonRotationNode = [SCNNode node];
    [_earthGroupNode addChildNode:moonRotationNode];
    
    // Moon
    _moonNode = [_wireframeBoxNode copy];
    _moonNode.position = SCNVector3Make(5, 0, 0);
    [moonRotationNode addChildNode:_moonNode];
    
  2. 3D 空間でモデル化した特定のパスをたどるアニメーションを作成することはできませんが、3D 空間の複数の位置間を補間するキーフレーム アニメーションを作成することはできます。以下の (テストされていない) コードは、xz 平面内の正方形の周りにノードを移動します...さらにポイントを追加して、より丸い形状を取得します。

    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPaths:@"position"];
    anim.values = @[
        [NSValue valueWithSCNVector3:SCNVector3Make(0, 0, 1)],
        [NSValue valueWithSCNVector3:SCNVector3Make(1, 0, 0)],
        [NSValue valueWithSCNVector3:SCNVector3Make(0, 0, -1)],
        [NSValue valueWithSCNVector3:SCNVector3Make(-1, 0, 0)],
    ];
    [node addAnimation:anim forKey:"orbit"];
    
  3. 物理を使おう!このSCNPhysicsFieldクラスは放射状重力をモデル化するため、重力場をシーンにドロップし、惑星の物理体をいくつか追加し、座って太陽系が激変して自らを破壊し、生き返るのを見ることができます! ここで現実的な動作を得るには、多くの試行錯誤が必要です。各惑星の接線方向の初速度を、期待される軌道に接するように設定し、その速度を微調整して正しく設定する必要があります。私たちの太陽系のエフェメリス データを調査すると役立つかもしれません。

于 2014-06-20T17:30:06.090 に答える