iOS.Lover
iOS.Lover

Reputation: 6051

Change SCNScene's sceneNamed programmatically

I am trying to change a current sceneNamed with code but it seems my method has some problems. First, the new scene will be changed but I have to touch or rate the object to changing process happens.Second, it seems childNodeWithName doesn't change at all ! Here is my code :

    - (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];
}

Here is a source code : https://www.dropbox.com/s/rrvbxmrb9wcrnoj/3D%20Objects%20Change.zip?dl=0

The code in the Dropbox version is not what I posted above. Here is the Dropbox version:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

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

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)load3DObjectName:(NSString*)name nodeName:(NSString*)nodeName zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad{
    SCNScene * scene = [SCNScene sceneNamed:name];
    // retrieve the ship node
    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);
    }
    _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:-40 zPad:-40];
}

Upvotes: 1

Views: 418

Answers (2)

Hashmat Khalil
Hashmat Khalil

Reputation: 1816

So I have take a look at your project. here is the issue: you don't have camera in you scenes. So I put camera for your each scenes manually at the same distance, and moved the nodes as desired. here is what it looks like now:

- (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];
}

and I also changed the your object positions for testing purposes:

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

and this one as well:

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

and last but not least, the screen shots: cube sphere

Upvotes: 1

Hal Mueller
Hal Mueller

Reputation: 7646

It looks to me like your second round of code works fine. I notice that you're loading different scenes/nodes in the Dropbox sample than you are in the code you posted first. So that makes me think there's something in your DAE file that isn't what you expect it to be. Check for node names that are missing or misspelled. Add NSAssert calls after your childNodeWithName: and sceneNamed: calls, to make sure that you really did successfully load the scene and find the child node.

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);

If the NSAsserts fail, use your 3D editing tool to fix your Collada file.

Note also that when you replace the3DView.scene (aside: please don't bang instance variables directly, use accessor methods instead!), you're replacing the camera and lighting too. So you should expect a jerk in the camera positioning. Maybe you want to animate this? Or remove/replace nodes for the objects, without messing with camera and lighting?

When I run the code you posted to Dropbox, I see a screen full of red. When I zoom away, and rotate the camera, it looks like this:

enter image description here

After I tap the "Button" button, I see this:

enter image description here

Upvotes: 0

Related Questions