SceneKit: imported dae file not copied to app bundle
It’s simple!
I was seeing a bunch of warnings like:
scntool: warning: Could not load ModelIO.framework ((null)) (etc)
which led me to this StackOverflow post which solved it for me.
In short: check in Xcode Preferences -> Locations. For me, the “Command Line Tools” had nothing selected (somehow!), so selecting a value there (in my case, Xcode 10.1), then doing a clean build, fixed the issue.
Mixed topology (quad/tri) with ModelIO
I reported this as a bug at Apple Bug Reporter on 25th of November, bug id: 35687088
Summary: SCNSceneSourceLoadingOptionPreserveOriginalTopology does not actually preserve the original topology. Instead, it converts the geometry to all quads, messing up the 3D model badly. Based on its name it should behave exactly like preserveTopology of Model IO asset loading.
Steps to Reproduce: Load an OBJ file that has both triangles and polygons using SCNSceneSourceLoadingOptionPreserveOriginalTopology and load the same file into an MDLMesh using preserveTopology of ModelIO. Notice how it only works properly for the latter. Even when you create a new SCNGeometry based on the MDLMesh, it will "quadify" the mesh again to contain only quads (while it should support 3-gons and up).
On December 13th I received a reply with a request for sample code and assets, which I supplied 2 days later. I have not received a reply since (hopefully because they are just busy from catching up from the holiday season...).
As I mentioned in my bug report's summary, loading the asset with Model I/O does work properly, but then when you create a SCNNode based on that MDLMesh it ends up messing up the geometry again.
In my case the OBJ files I load have a known format as they are always files also exported with my app (no normals, colors, UV). So what I do is load the information of the MDLMesh (buffers, facetopology etc) manually into arrays, from which I then create a SCNGeometry manually. I don't have a complete separate piece of code of that for you as it is a lot and mixed with a lot of code specific to my app, and it's in Objective C. But to illustrate:
NSError *scnsrcError;
MDLAsset *asset = [[MDLAsset alloc] initWithURL:objURL vertexDescriptor:nil bufferAllocator:nil preserveTopology:YES error:&scnsrcError];
NSLog(@"%@", scnsrcError.localizedDescription);
MDLMesh * newMesh = (MDLMesh *)[asset objectAtIndex:0];
for (MDLSubmesh *faces in newMesh.submeshes) {
//MDLSubmesh *faces = newMesh.submeshes.firstObject;
MDLMeshBufferData *topo = faces.topology.faceTopology;
MDLMeshBufferData *vertIx = faces.indexBuffer;
MDLMeshBufferData *verts = newMesh.vertexBuffers.firstObject;
int faceCount = (int)faces.topology.faceCount;
int8_t *faceIndexValues = malloc(faceCount * sizeof(int8_t));
memcpy(faceIndexValues, topo.data.bytes, faceCount * sizeof(int8_t));
int32_t *vertIndexValues = malloc(faces.indexCount * sizeof(int32_t));
memcpy(vertIndexValues, vertIx.data.bytes, faces.indexCount * sizeof(int32_t));
SCNVector3 *vertValues = malloc(newMesh.vertexCount * sizeof(SCNVector3));
memcpy(vertValues, verts.data.bytes, newMesh.vertexCount * sizeof(SCNVector3));
....
....
}
In short, the preserveTopology option in SceneKit isn't working properly. To get from the working version in Model I/O to SceneKit I basically had to write my own converter.
Related Topics
Combining Two Conditions in Nspredicate
"Nsurl" Is Not Implicitly Convertible to "Url"; Did You Mean to Use "As" to Explicitly Convert
Swift: How to Disable User Interaction While Touch Action Is Being Carried Out
How to Loop Through All MAC Desktop Spaces
How to Position Child Skspritenodes Inside Their Parents
Nsurlsession/Nsurlconnection Http Load Failed (Kcfstreamerrordomainssl, -9802)
What Is the Swift 3 Equivalent of Nsurl.Urlbyappendingpathcomponent()
Get Path to Swift Script from Within Script
Swift Await/Async - How to Wait Synchronously for an Async Task to Complete
Facebookshare Causing Compiler Error After Update
Swiftui: How to Iterate Over an Array of Bindable Objects
Check for Launching from Uilocalnotification in Swift
Need Self to Set All Constants of a Swift Class in Init
Adding Nscoding as an Extension
How to Get the Edited Image from Uiimagepickercontroller in Swift
Cancelling an Alamofire Request Wrapped in Nsoperation Causes Multiple Kvo