Изменить сцену SCNScene

Я пытаюсь изменить ток sceneNamed с кодом, но, похоже, у моего метода есть некоторые проблемы. Во-первых, новая сцена будет изменена, но я должен коснуться или оценить объект, чтобы произошел процесс изменения. Во-вторых, кажется childNodeWithName не меняется вообще! Вот мой код:

    - (void)load3DObjectName:(NSString*)name nodeName:(NSString*)nodeName zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad{

        SCNScene * scene = [SCNScene sceneNamed:name];
        // retrieve the ship node
        SCNNode *trex = [scene.rootNode childNodeWithName:nodeName recursively:YES];


        if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {

             trex.position = SCNVector3Make(0, 0, positioniPhone);

        } else {

             trex.position = SCNVector3Make(0, 0, positioniPad);
        }



        _the3DScence.scene = scene;
        _the3DScence.autoenablesDefaultLighting = YES;
        _the3DScence.allowsCameraControl = YES;
        _the3DScence.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00];
    }



// Load default object :

- (void)viewDidLoad {

    [self load3DObjectName:@"cube.dae" nodeName:@"cube1" zPhone:-40 zPad:-30];

}

//Trying to change the 3D object with button:
- (IBAction)nextObject:(id)sender {

    [self load3DObjectName:@"redCube.dae" nodeName:@"cube2" zPhone:-40 zPad:-30];

}

- (IBAction)changeIt:(id)sender {

     [self load3DObjectName:@"dayere.dae" nodeName:@"Sphere" zPhone:-40 zPad:-40];
}

Вот исходный код: https://www.dropbox.com/s/rrvbxmrb9wcrnoj/3D%20Objects%20Change.zip?dl=0

Код в версии Dropbox не тот, что я выложил выше. Вот версия Dropbox:

- (void) viewDidLoad {
    [super viewDidLoad];
    // Выполнить любую дополнительную настройку после загрузки представления, как правило, из кончика.

    [self load3DObjectName:@"cube.dae" имя_узла:@"Cube" zPhone:-40 zPad:-40];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Утилизировать любые ресурсы, которые могут быть воссозданы.
}

- (void)load3DObjectName:(NSString*)name имя_узла: (NSString *) имя_узла zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad{
    SCNScene * scene = [SCNScene sceneNamed:name];
    // получить узел корабля
    SCNNode *node = [scene.rootNode childNodeWithName:nodeName recursively:YES];

    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
        node.position = SCNVector3Make(0, 0, positioniPhone);
    } 
    еще {
        node.position = SCNVector3Make(0, 0, positioniPad);
    }
    _the3DView.scene = сцена;
    _the3DView.autoenablesDefaultLighting = YES;
    _the3DView.allowsCameraControl = YES;
    _the3DView.backgroundColor = [UIColor colorWithRed:0,92 зеленый: 0,92 синий: 0,92 альфа:1,00];
}

- (IBAction)changeIt:(id) отправитель {
     [self load3DObjectName:@"dayere.dae" nodeName:@"Sphere" zPhone:-40 zPad:-40];
}

2 ответа

Решение

Итак, я взглянул на ваш проект. вот проблема: у вас нет камеры в ваших сценах. Поэтому я поместил камеру для каждой сцены вручную на одинаковом расстоянии и переместил узлы по желанию. вот как это выглядит сейчас:

- (void)load3DObjectName:(NSString*)name nodeName:(NSString*)nodeName zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad
{
SCNScene * scene = [SCNScene sceneNamed:name];
SCNNode *node = [scene.rootNode childNodeWithName:nodeName recursively:YES];

if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
    node.position = SCNVector3Make(0, 0, positioniPhone);

} else {

    node.position = SCNVector3Make(0, 0, positioniPad);
}

SCNCamera *cam = [[SCNCamera alloc] init];
cam.xFov = 35;
cam.yFov = 35;
cam.zFar = 5000;
cam.zNear = 0;
SCNNode *camNode = [[SCNNode alloc] init];
camNode.camera = cam;

camNode.position = SCNVector3Make(0, 0, 400);

[scene.rootNode addChildNode:camNode];

_the3DView.pointOfView = camNode;

_the3DView.scene = scene;
_the3DView.autoenablesDefaultLighting = YES;
_the3DView.allowsCameraControl = YES;
_the3DView.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00];
}

и я также изменил позиции вашего объекта для целей тестирования:

- (IBAction)changeIt:(id)sender
{
 [self load3DObjectName:@"dayere.dae" nodeName:@"Sphere" zPhone:-340 zPad:-340];
}

и этот тоже:

- (void)viewDidLoad
{
   [super viewDidLoad];
   [self load3DObjectName:@"cube.dae" nodeName:@"Cube" zPhone:-40 zPad:-40];
}

и, наконец, снимки экрана: куб сфера

Мне кажется, что ваш второй раунд кода работает нормально. Я заметил, что вы загружаете разные сцены / узлы в образце Dropbox, чем в коде, который вы опубликовали первым. Так что это заставляет меня думать, что в вашем файле DAE есть что-то, что не соответствует вашим ожиданиям. Проверьте имена узлов, которые отсутствуют или написаны с ошибками. добавлять NSAssert звонки после вашего childNodeWithName: а также sceneNamed: вызовы, чтобы убедиться, что вы действительно успешно загрузили сцену и нашли дочерний узел.

SCNScene * scene = [SCNScene sceneNamed:name];
NSAssert(scene, @"failed to load scene named %@", name);
// retrieve the ship node
SCNNode *node = [scene.rootNode childNodeWithName:nodeName recursively:YES];
NSAssert(node, @"couldn't fine child node named %@", nodeName);

В случае сбоя NSAsserts используйте инструмент 3D-редактирования, чтобы исправить файл Collada.

Обратите внимание, что при замене the3DView.scene (в сторону: пожалуйста, не бейте переменные экземпляра напрямую, вместо этого используйте методы доступа!), вы заменяете камеру и освещение тоже. Таким образом, вы должны ожидать рывок в позиционировании камеры. Может быть, вы хотите оживить это? Или удалить / заменить узлы для объектов, не мешая с камерой и освещением?

Когда я запускаю код, который вы разместили в Dropbox, я вижу экран, полный красного цвета. Когда я уменьшаю масштаб и поворачиваю камеру, это выглядит так:

После того, как я нажимаю кнопку "Кнопка", я вижу это:

Другие вопросы по тегам