2

When I display a node from a COLLADA file, the CPU usage goes up to 100%+.
Link to pic

I am not using the simulator, I am using my actual phone. The model consists of about 80k vertices.

Here is how I load the model:

// Add Character
func addModel(name:String)
{
    // Load COLLADA Model
    if let myScene = SCNScene(named: "Assets.scnassets/"+name+"/"+name+".dae")
    {
        // Recurse through all the child nodes in the model and add to modelNode
        for node in myScene.rootNode.childNodes as [SCNNode]
        {
            modelNode.addChildNode(node)
        }

        // Add modelNode to scene
        self.rootNode.addChildNode(modelNode)
    }
    else
    {
        print("Error loading model: "+name)
    }
}

The model is 122MB and can be found here:
Link to zip

I have tried with different models, but CPU goes nuts on each one of them. They are all about 122MB (which sounds large) and about 80k vertices.

Update
Tried to lower the poly count in SceneKit. In blender i lowered vertices from 20k to 5k (see here). But when I load the model in SceneKit the poly count is still the same (68k). I also tried converting the model and the animations to .SCN instead. This resulted in much lower file size, however the same poly count and CPU usage.
Pictures of showStatistics

I think what I need to do is lower the poly count, not so much the file size (don't think that would harm though).

Update 2 Now I actually managed to lower the poly count to about 48k. Still lagging. If I remove the texture, the CPU is much lower.

Fredrik
  • 3,027
  • 8
  • 33
  • 66

1 Answers1

2

I'm not positive this is your usage issue but your method of loading your file could be streamlined.

You don't need to add each individual node from your DAE file to your modelNode. Ideally, your Collada model will have its own root node with a unique name. Just add that node to modelNode and all its children will be included. In the sample below, lyso_ribbons is the name of the root node in the DAE as well as the name of the DAE file itself.

guard let lysoRibbons = SCNScene(named: "lyso_ribbons") 
    else { print("Couldn't find molecule in dictionary  (lysoRibbons)")
        return  }
let modelNode = lysoRibbons.rootNode.childNodeWithName("lyso_ribbons", recursively: false)!

All the child nodes that tagged along with the root are still accessible by name via childNodeWithName. You can inspect your DAE's scene graph in the editor window, just click on it in the navigator panel and, within the editor, click on the small square far lower left of the editor window. If, for some reason, your DAE model is lacking a root node you can create one here and move all other nodes into it. Also see: Transform and Rotate in Scenekit

You can create nodes in the left-hand panel of the editor window displaying your DAE file. Click on the + sign, far lower left of the panel. Drag that <untitled> object to the top, just under "Scene graph". Then group-select all other nodes and drag them into this new object. Give the new object a unique name. You'll notice the new node has a grayed icon meaning it has no geometry of its own.

A better way to do this is to plan ahead when creating your Collada model using nulls, with unique names, to organize your geometry nodes into meaningful sub-groups. The nulls will then be imported as parent nodes of those sub-groups. Place all nodes into one master null that will become the root for your model.

Community
  • 1
  • 1
bpedit
  • 1,176
  • 8
  • 22
  • Where do you mean with "If, for some reason, your DAE model is lacking a root node you can create one **here**"? I do not have a parent node for all the children in the dae-file. – Fredrik Aug 09 '16 at 14:35
  • I've added to the answer above. If you created the DAE yourself, you might consider revising in your modeling software, as suggested in the last paragraph, and resaving the file. I'm not sure how this works in other 3-D software but this is how I do it in Cinema 4D. – bpedit Aug 09 '16 at 15:21
  • But isn't this what I basically do by adding all the children to a parent (modelNode)? The **modelNode** only contains the children. – Fredrik Aug 09 '16 at 15:35
  • Sure, same end result, but why iterate through all nodes when you can just add the root? Like I say, this may not solve your issue but it's a cleaner, more compact way of getting your DAE into code. If your model is only a few nodes but rife with vertexes, it probably won't make a difference in the CPU usage. However, you posted your loading technique so that's what I focused on. – bpedit Aug 09 '16 at 16:28
  • It doesn't seem to affect the CPU. If i load everything in the scene except the model, the CPU stays at <10%. I added the .DAE file in the question. – Fredrik Aug 10 '16 at 15:19
  • That's a lot of model!. One avenue to consider is to reduce the model's polygon count, assuming it's one you've made. You might keep the count a bit higher in areas of focus, say the face. Like most 3-D renderers, SceneKit will smooth transitions across polygon edges. This means a coarser poly structure will mostly only be noticeable on the silhouette edges. – bpedit Aug 10 '16 at 16:24
  • That sounds about right. About what size "should" a model be? – Fredrik Aug 10 '16 at 17:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/120626/discussion-between-bpedit-and-fredrik-l). – bpedit Aug 10 '16 at 18:46