admin管理员组

文章数量:1391947

so this is my problem and the solution that worked for me, for all to see... Obvs its rough and kinda hacky but maybe it'll save someone 8hrs from googling and shouting at their AI of choice

Im sorry if this isn't the format anyone was expecting on here, but i've totally had enough of the lack of documentation... as im sure a few of us have felt when playing around with swift/scenekit etc

Below is a complete example of how you might handle a Wave modifier in Blender by converting it to a shape‑key animation (using an MDD file), re‑importing that, exporting as USDC, converting to .scn, and finally loading/using it in SceneKit with custom materials. This is especially helpful for others who need to bake wave animations into SceneKit when direct baking doesn’t export (.abc OR .dae) in Blender 4.x.

  1. Blender Workflow (top level steps)

Put Subdivider & Wave Modifiers onto object and tweak as needed get it looking good and then export as an .MDD (Lightwave Point Cache - you may need to go to edit > preferences > Add On's to get it first)

Remove the modifiers from your object so its just the mesh (no modifiers)

Click on mesh you want and then goto File > Import > MDD it shoul now have some shape‑key‑based-keyframes

Clean-Up the whole file as needed (nice tidy up point) or just select only the objects you want & Export as a .USD (universal scene description)

open that randomFileName.usd with Xcode and Convert to .scn

Now you have a final .scn file containing the baked wave animation,

here is a picture, FULL disclosure i just dont have the energy anymore to make a proper example and i was only making subtle ripples in a circle pond above a square plane so in my screengrabs i have two sub‑meshes named “Base” (blue) and “Wave” (teal) which had the animation on it

blender export settigns and keyframes in timline

right so now in swift scenekit

func loadModel(named filename: String) -> SCNNode? {
    // Attempt to load an .scn file from the bundle
    if let scnURL = Bundle.main.url(forResource: filename, withExtension: "scn") {
        do {
            let scnScene = try SCNScene(url: scnURL, options: nil)
            let newRootNode = SCNNode()
       
            // If there's a top-level "Root" node, we skip that and attach its children’s children:
            for child in scnScene.rootNode.childNodes {
                print("Child name: \(child.name ?? "nil")")
                
                // For each child's child node
                for daughter in child.childNodes {
                    for son in daughter.childNodes {
                        newRootNode.addChildNode(son)
                    }
                }
            }
            print("Loaded .scn successfully")
            return newRootNode
            
        } catch {
            print("Failed to load .scn file: \(error)")
            return nil
        }
    }
    
    print("Could not find \(filename).scn in the bundle.")
    return nil
}

and then somethign like this where i had to access the geometry separately and attach a material to it in swift

 if let customNode = loadModel(named: "whirlpool") {
        // Position & orientation
        customNode.position.y = 0.0

        // For each child node in the loaded SCN
        for child in customNode.childNodes {
            if child.name == "Base" {
                // Create a material
                let mat1 = SCNMaterial()
                mat1.diffuse.contents = UIColor.red
                mat1.lightingModel = .lambert
                mat1.isDoubleSided = false
                child.geometry?.materials = [mat1]
                
            } else if child.name == "Wave" {
                print(child)
                let mat2 = SCNMaterial()
                mat2.diffuse.contents = UIColor.blue
                mat2.lightingModel = .lambert
                mat2.specular.contents = UIColor.white
                mat2.isDoubleSided = false
                child.geometry?.materials = [mat2]
            }
        }
        
        // Rotate so Z becomes up (or fix orientation)
        customNode.eulerAngles.x = -Float.pi / 2
        // Scale down
        customNode.scale = SCNVector3(x: 0.5, y: 0.5, z: 0.5)
        
        node = customNode
    } 



i realise thats a bad tutorial but as i said i lost 8 hrs and now cant be bothered, but if your trying this in the future i think you know at least some of this already and can fill in the gaps

good luck... happily listen to any changes or thoughts or other work aroudns in the future but for now this is all i can give

ripples from blender working in scenekit

本文标签: