Nanite Assembly help please!


I’ve been working on getting a USDA file over from Plant Factory into UE as a Nanite Assembly.

By hand editing the USDA from PF I have managed to get a trunk/branch mesh and instanced leaf geometry into UE, all as a Nanite Assembly. This is great.

I am hitting a roadblock however using unreal:naniteAssembly:meshAssetPathto specify an asset that’s already inside of unreal as the instanced mesh.

I have it working for a non-instanced object in the USDA file (the trunk), which is great, but using the workflow/syntax for the instanced parts results in an error on import.

I was hoping someone could take a look at my USDA file, and point out what I am doing wrong!

Below is just a very cut down example file, I figured I would start with just something super basic - a leaf card instanced 4 times as a test, then when I have that working, I can do the same thing on the larger, more cumbersome full tree files.

#usda 1.0
(
“File Generated by USD Exporter of PlantFactory 1 produced by e-on software (Bentley)”
customLayerData = {
string “Original Save Path” = “E:/personal/doug_fir/USD_tests/basic_instancing_replace.usd”
string PF_SCENEPATH = “Untitled”
}
defaultPrim = “World”
metersPerUnit = 1
upAxis = “Z”
)

def Xform “World” (
kind = “assembly”
apiSchemas = [“NaniteAssemblyRootAPI”]
)
{
def Xform “Geometry”
{
float3 xformOp:scale = (1, 1, 1)
uniform token
 xformOpOrder = [“xformOp:scale”]

    def PointInstancer "Inst"
    {
        quath[] orientations = [(0.353516, 0.612305, 0.612305, 0.353516), (-0.612305, 0.353516, -0.353516, 0.612305), (-0.612305, 0.353516, -0.353516, 0.612305), (0.353516, 0.612305, 0.612305, 0.353516)]
        point3f[] positions = [(0, 0, 7.7113247), (0, 0, 1.7113248), (0, 0, 5.7113247), (0, 0, 3.711325)]
        int[] protoIndices = [0, 0, 0, 0]
        rel prototypes = </World/Geometry/Inst/Untitled_Instantiation>
        float3[] scales = [(-1, -1, -1), (1, 1, 1), (1, 1, 1), (-1, -1, -1)]

        def Xform "Untitled_Instantiation" (
        kind = "component"
        apiSchemas = ["NaniteAssemblyExternalRefAPI"]
        )
        {
        uniform token unreal:naniteAssembly:meshAssetPath = "/Game/USD_Tests_02/SM_DouglasFir_BranchCluster_01"
        }
    }
}

}

Hi there. Are you using the legacy USD Importer or the (newer) Interchange USD importer?

I did get an error with the legacy importer, which has limited Nanite Assembly support. However I was able to get your example file to work using the Interchange importer.

This is the exact file I used:

#usda 1.0
(
    defaultPrim = "World"
    metersPerUnit = 1
    upAxis = "Z"
)

def Xform "World" (
    kind = "assembly"
    apiSchemas = ["NaniteAssemblyRootAPI"]
)
{
    def Xform "Geometry"
    {
        float3 xformOp:scale = (1, 1, 1)
        uniform token[] xformOpOrder = ["xformOp:scale"]

        def PointInstancer "Inst"
        {
            quath[] orientations = [(0.353516, 0.612305, 0.612305, 0.353516), (-0.612305, 0.353516, -0.353516, 0.612305), (-0.612305, 0.353516, -0.353516, 0.612305), (0.353516, 0.612305, 0.612305, 0.353516)]
            point3f[] positions = [(0, 0, 7.7113247), (0, 0, 1.7113248), (0, 0, 5.7113247), (0, 0, 3.711325)]
            int[] protoIndices = [0, 0, 0, 0]
            rel prototypes = </World/Geometry/Inst/Untitled_Instantiation>
            float3[] scales = [(-1, -1, -1), (1, 1, 1), (1, 1, 1), (-1, -1, -1)]

            def Xform "Untitled_Instantiation" (
                kind = "component"
                apiSchemas = ["NaniteAssemblyExternalRefAPI"]
            )
            {
                uniform token unreal:naniteAssembly:meshAssetPath = "/Game/Path/To/Your/SM_Mesh"
            }
        }
    }
}

Note you might see a couple of bogus warnings in the output log along the lines of:

LogInterchangePipeline: Warning: Failed to create mesh-to-mesh factory node dependency ‘\Mesh/World_2191436871’ → ‘/Game/Path/To/Your/SM_Mesh’ - target not found.

However the resulting static mesh nanite assembly should still be correctly referencing the mesh specified by unreal:naniteAssembly:meshAssetPath (we will look into getting the erroneous warnings fixed!)

Let me know if you still have problems with the above.

Antony

Ah ha! I didn’t have the newer interchange USD plugin enabled! I’ve turned that on, and will try again.

Thx!

This fixed it, thanks so much @Ant_Carysforth!!!

1 Like