Изменить сцену 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, я вижу экран, полный красного цвета. Когда я уменьшаю масштаб и поворачиваю камеру, это выглядит так:
После того, как я нажимаю кнопку "Кнопка", я вижу это: