Ejemplo n.º 1
0
 /// <summary>
 /// Handles post process on all assets within Unity Editor. Finds all meshes and creates
 /// a Unity prefab allowing easy instation at runtime. For more information about this Unity
 /// Message Handle: http://docs.unity3d.com/ScriptReference/AssetPostprocessor.OnPostprocessAllAssets.html
 /// </summary>
 /// <param name="importedAssets">List of paths to assets that have been imported</param>
 /// <param name="deletedAssets">List of paths to assets that have been deleted</param>
 /// <param name="movedAssets">List of paths to assets that have been moved</param>
 /// <param name="movedFromAssetPaths">List of paths to assets that have been moved from paths</param>
 static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
 {
     if (importedAssets.Length > 0)
     {
         FileType type = FileType.UNKNOWN;
         foreach (string assetPath in importedAssets)
         {
             string filename = FileManagerImpl.GetFileName(assetPath, false);
             type = FileManagerImpl.GetFileType(assetPath);
             UnityEngine.Object asset = AssetDatabase.LoadMainAssetAtPath(assetPath);
             // Creating prefab here will cause this function to be invoked again causing an infinite loop of
             // assets being generated. Proper Check of the Object is of type GameObject, isn't part of a prefab
             // and that the asset is a proper model that can become a prefab.
             if (asset.GetType() == typeof(GameObject) &&
                 PrefabUtility.GetPrefabParent(asset) == null &&
                 PrefabUtility.GetPrefabType(asset) == PrefabType.ModelPrefab)
             {
                 // To properly create a prefab of the object we need to instantiate it into
                 // the game world and save that object as a prefab.
                 GameObject go = GameObject.Instantiate <GameObject>((GameObject)asset);
                 go.name = asset.name; // remove the (clone) within the name.
                 PrefabUtility.CreatePrefab(string.Format(prefabItemPathFormat, go.name), go);
                 GameObject.DestroyImmediate(go);
             }
             else if (type == FileType.URDF || type == FileType.XACRO)
             {
                 string prefabName = CreateUrdfRobot(assetPath);
                 if (!String.IsNullOrEmpty(prefabName))
                 {
                     UrdfItemModel item = new UrdfItemModel();
                     item.name           = filename;
                     item.urdfFilename   = assetPath;
                     item.prefabFilename = prefabName;
                     item.visibility     = 1;
                     UrdfDb db = new UrdfDb();
                     db.AddSensor(item);
                 }
             }
         }
     }
 }
Ejemplo n.º 2
0
    /// <summary>
    /// Handles putting together a robot GameObject or loads if already created
    /// </summary>
    /// <param name="robot">Robot XML description to generate robot with</param>
    /// <returns>Gameobject representation of robot generated from description</returns>
    /// Code from https://github.com/MangoMangoDevelopment/neptune
    private static GameObject GenerateRobotGameObject(Robot robot)
    {
#if UNITY_EDITOR
        Debug.Log("----- Generating robot from description ------");
        Directory.CreateDirectory(assetFolderPath);
        Directory.CreateDirectory(prefabResourcesFolderPath);
        string roboName = robot.Name;

        GameObject    parent        = new GameObject(robot.Name);
        ROSRobotModel rosRobotModel = parent.AddComponent <ROSRobotModel>();
        rosRobotModel.robot = robot;

        Robot rob2 = rosRobotModel.robot;
        Debug.Log(rob2.Name);
        Dictionary <string, GameObject> linkAsGos = new Dictionary <string, GameObject>();

        // creating a list of gameobjects
        foreach (KeyValuePair <string, Link> link in robot.Links)
        {
            GameObject linkGo = new GameObject(link.Key);

            ROSLinkModel linkModel = linkGo.AddComponent <ROSLinkModel>();
            linkModel.link = link.Value;
            linkModel.name = link.Key;

            if (link.Value.Visual.Count > 0)
            {
                GameObject linkVisualGo = null;
                Vector3    linkScale    = new Vector3();
                Vector3    linkPosition = new Vector3();
                Vector3    linkRotation = new Vector3();
                float      radiusScale  = 0.0f;

                foreach (Visual obj in link.Value.Visual)
                {
                    if ((Geometry.Shapes.Mesh == obj.Geometry.Shape) && (obj.Geometry.Mesh != null))
                    {
                        linkModel.hasMesh = true;
                        string   fileName = FileManagerImpl.GetFileName(obj.Geometry.Mesh.FileName, false);
                        string[] guids    = AssetDatabase.FindAssets(string.Format("{0} t:GameObject", fileName));
                        foreach (string guid in guids)
                        {
                            UnityEngine.Object asset = AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GUIDToAssetPath(guid));
                            if (asset.name == fileName)
                            {
                                linkVisualGo = GameObject.Instantiate <GameObject>((GameObject)asset);
                                break;
                            }
                        }
                        if (obj.Geometry.Mesh.Size != null)
                        {
                            linkScale = new Vector3((float)obj.Geometry.Mesh.Size.Length, (float)obj.Geometry.Mesh.Size.Height, (float)obj.Geometry.Mesh.Size.Width);
                        }
                        else
                        {
                            linkScale = new Vector3(1f, 1f, 1f);
                        }
                        linkPosition = new Vector3((float)obj.Origin.Xyz.X, (float)obj.Origin.Xyz.Y, (float)obj.Origin.Xyz.Z);
                        linkRotation = new Vector3(Mathf.Rad2Deg * (float)obj.Origin.Rpy.R, Mathf.Rad2Deg * (float)obj.Origin.Rpy.P, Mathf.Rad2Deg * (float)obj.Origin.Rpy.Y);
                    }
                    else
                    {
                        PrimitiveType type = PrimitiveType.Cube;

                        switch (obj.Geometry.Shape)
                        {
                        case Geometry.Shapes.Cylinder:
                            type        = PrimitiveType.Cylinder;
                            radiusScale = (float)obj.Geometry.Cylinder.Radius * 2;
                            linkScale   = new Vector3(radiusScale, (float)obj.Geometry.Cylinder.Length / 2, radiusScale);
                            break;

                        case Geometry.Shapes.Sphere:
                            type        = PrimitiveType.Sphere;
                            radiusScale = (float)obj.Geometry.Sphere.Radius * 2;
                            linkScale   = new Vector3(radiusScale, radiusScale, radiusScale);
                            break;

                        case Geometry.Shapes.Box:
                            type      = PrimitiveType.Cube;
                            linkScale = new Vector3((float)obj.Geometry.Box.Size.Length, (float)obj.Geometry.Box.Size.Height, (float)obj.Geometry.Box.Size.Width);
                            break;
                        }
                        linkVisualGo = GameObject.CreatePrimitive(type);
                        linkPosition = new Vector3((float)obj.Origin.Xyz.X, (float)obj.Origin.Xyz.Z, (float)obj.Origin.Xyz.Y);
                        linkRotation = new Vector3(Mathf.Rad2Deg * (float)obj.Origin.Rpy.R, Mathf.Rad2Deg * (float)obj.Origin.Rpy.Y, Mathf.Rad2Deg * (float)obj.Origin.Rpy.P);
                    }

                    if (linkVisualGo != null)
                    {
                        linkVisualGo.transform.localEulerAngles = linkRotation;
                        linkVisualGo.transform.localScale       = linkScale;
                        linkVisualGo.transform.localPosition    = linkPosition;

                        if (obj.Material != null && obj.Material.Color != null)
                        {
                            Material mat = new Material(Shader.Find("Standard"));
                            mat.color = new Color((float)obj.Material.Color.Rgb.R / 255,
                                                  (float)obj.Material.Color.Rgb.G / 255,
                                                  (float)obj.Material.Color.Rgb.B / 255);
                            if (!Directory.Exists(assetFolderPath + "/" + parent.name))
                            {
                                AssetDatabase.CreateFolder(assetFolderPath, parent.name);
                            }
                            AssetDatabase.CreateAsset(mat, string.Format(assetPathFormat, parent.name, link.Key));
                            if (linkVisualGo.GetComponentInChildren <MeshRenderer>() != null)
                            {
                                linkVisualGo.GetComponentInChildren <MeshRenderer>().sharedMaterial = mat;
                            }
                        }
                        linkVisualGo.transform.SetParent(linkGo.transform);
                    }
                }
            }
            linkGo.transform.SetParent(parent.transform);
            linkAsGos.Add(link.Key, linkGo);
        }

        foreach (KeyValuePair <string, UrdfToUnity.Urdf.Models.Joint> joint in robot.Joints)
        {
            GameObject child = linkAsGos[joint.Value.Child.Name];
            child.transform.SetParent(linkAsGos[joint.Value.Parent.Name].transform);
            // Very strange, imported object will have the proper associated XYZ coordinates where as
            // a generated primitive types have the YZ coordinates are swapped.
            if (child.GetComponent <ROSLinkModel>().hasMesh)
            {
                child.transform.localPosition = new Vector3((float)joint.Value.Origin.Xyz.X, (float)joint.Value.Origin.Xyz.Y, (float)joint.Value.Origin.Xyz.Z);
            }
            else
            {
                // URDF considers going up as the FloorIndex-axis where as unity consider going up is Y-axis
                child.transform.localPosition = new Vector3((float)joint.Value.Origin.Xyz.X, (float)joint.Value.Origin.Xyz.Z, (float)joint.Value.Origin.Xyz.Y);
            }

            child.transform.localEulerAngles = new Vector3(Mathf.Rad2Deg * (float)joint.Value.Origin.Rpy.R, Mathf.Rad2Deg * (float)joint.Value.Origin.Rpy.Y, Mathf.Rad2Deg * (float)joint.Value.Origin.Rpy.P);
        }

        MeshRenderer[] children = parent.GetComponentsInChildren <MeshRenderer>();
        foreach (MeshRenderer child in children)
        {
            if (child.transform == parent.transform)
            {
                continue;
            }
            if (child.gameObject.GetComponent <Renderer>())
            {
                child.gameObject.AddComponent <MeshCollider>();
                MeshCollider mc = child.gameObject.GetComponent <MeshCollider>();
                mc.sharedMesh = child.gameObject.GetComponent <MeshFilter>().sharedMesh;
            }
        }
        Debug.Log("Saved in: " + string.Format(prefabPathFormat, roboName));
        return(PrefabUtility.CreatePrefab(string.Format(prefabPathFormat, roboName), parent));
#endif
#if UNITY_STANDALONE
        Debug.LogError("Script can only be run from editor");
        return(null);
#endif
    }
Ejemplo n.º 3
0
    /// <summary>
    /// Handles putting together a robot GameObject and saving it as a prefab for
    /// later use.
    /// </summary>
    /// <param name="path">The path of the URDF</param>
    /// <returns>A string represenation of the path and name of the prefab created.</returns>
    static string CreateUrdfRobot(string path)
    {
        FileManagerImpl fileManager = new FileManagerImpl();
        string          filename    = FileManagerImpl.GetFileName(path, false);
        Robot           robo        = fileManager.GetRobotFromFile(path);


        string roboName = "";

        if (robo != null)
        {
            roboName = filename + "/" + robo.Name;
            GameObject parent = new GameObject(robo.Name);
            parent.AddComponent <RosRobotModel>();
            parent.GetComponent <RosRobotModel>().robot = robo;

            Robot rob2 = parent.GetComponent <RosRobotModel>().robot;
            Debug.Log(rob2.Name);
            Dictionary <string, GameObject> linkAsGos = new Dictionary <string, GameObject>();

            // creating a list of gameobjects
            foreach (KeyValuePair <string, Link> link in robo.Links)
            {
                GameObject linkGo = new GameObject(link.Key);

                linkGo.AddComponent <RosLinkModel>();
                RosLinkModel linkModel = linkGo.GetComponent <RosLinkModel>();
                linkModel.link = link.Value;
                linkModel.name = link.Key;

                if (link.Value.Visual.Count > 0)
                {
                    GameObject linkVisualGo = null;
                    Vector3    linkScale    = new Vector3();
                    Vector3    linkPosition = new Vector3();
                    Vector3    linkRotation = new Vector3();
                    float      radiusScale  = 0.0f;

                    foreach (Visual obj in link.Value.Visual)
                    {
                        if ((Geometry.Shapes.Mesh == obj.Geometry.Shape) && (obj.Geometry.Mesh != null))
                        {
                            linkModel.hasMesh = true;
                            string   fileName = FileManagerImpl.GetFileName(obj.Geometry.Mesh.FileName, false);
                            string[] guids    = AssetDatabase.FindAssets(string.Format("{0} t:GameObject", fileName));
                            foreach (string guid in guids)
                            {
                                UnityEngine.Object asset = AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GUIDToAssetPath(guid));
                                if (asset.name == fileName)
                                {
                                    linkVisualGo = GameObject.Instantiate <GameObject>((GameObject)asset);
                                    break;
                                }
                            }
                            if (obj.Geometry.Mesh.Size != null)
                            {
                                linkScale = new Vector3((float)obj.Geometry.Mesh.Size.Length, (float)obj.Geometry.Mesh.Size.Height, (float)obj.Geometry.Mesh.Size.Width);
                            }
                            else
                            {
                                linkScale = new Vector3(0.1f, 0.1f, 0.1f);
                            }
                            linkPosition = new Vector3((float)obj.Origin.Xyz.X, (float)obj.Origin.Xyz.Y, (float)obj.Origin.Xyz.Z);
                            linkRotation = new Vector3(Mathf.Rad2Deg * (float)obj.Origin.Rpy.R, Mathf.Rad2Deg * (float)obj.Origin.Rpy.P, Mathf.Rad2Deg * (float)obj.Origin.Rpy.Y);
                        }
                        else
                        {
                            PrimitiveType type = PrimitiveType.Cube;

                            switch (obj.Geometry.Shape)
                            {
                            case Geometry.Shapes.Cylinder:
                                type        = PrimitiveType.Cylinder;
                                radiusScale = (float)obj.Geometry.Cylinder.Radius * 2;
                                linkScale   = new Vector3(radiusScale, (float)obj.Geometry.Cylinder.Length / 2, radiusScale);
                                break;

                            case Geometry.Shapes.Sphere:
                                type        = PrimitiveType.Sphere;
                                radiusScale = (float)obj.Geometry.Sphere.Radius * 2;
                                linkScale   = new Vector3(radiusScale, radiusScale, radiusScale);
                                break;

                            case Geometry.Shapes.Box:
                                type      = PrimitiveType.Cube;
                                linkScale = new Vector3((float)obj.Geometry.Box.Size.Length, (float)obj.Geometry.Box.Size.Height, (float)obj.Geometry.Box.Size.Width);
                                break;
                            }
                            linkVisualGo = GameObject.CreatePrimitive(type);
                            linkPosition = new Vector3((float)obj.Origin.Xyz.X, (float)obj.Origin.Xyz.Z, (float)obj.Origin.Xyz.Y);
                            linkRotation = new Vector3(Mathf.Rad2Deg * (float)obj.Origin.Rpy.R, Mathf.Rad2Deg * (float)obj.Origin.Rpy.Y, Mathf.Rad2Deg * (float)obj.Origin.Rpy.P);
                        }

                        if (linkVisualGo != null)
                        {
                            linkVisualGo.transform.localEulerAngles = linkRotation;
                            linkVisualGo.transform.localScale       = linkScale;
                            linkVisualGo.transform.localPosition    = linkPosition;

                            if (obj.Material != null && obj.Material.Color != null)
                            {
                                Material mat = new Material(Shader.Find("Standard"));
                                mat.color = new Color(obj.Material.Color.Rgb.R, obj.Material.Color.Rgb.G, obj.Material.Color.Rgb.B);
                                if (!Directory.Exists(assetFolderPath + "/" + parent.name))
                                {
                                    AssetDatabase.CreateFolder(assetFolderPath, parent.name);
                                }
                                AssetDatabase.CreateAsset(mat, string.Format(assetPathFormat, parent.name, link.Key));
                                linkVisualGo.GetComponent <Renderer>().sharedMaterial = mat;
                            }
                            linkVisualGo.transform.SetParent(linkGo.transform);
                        }
                    }
                }
                linkGo.transform.SetParent(parent.transform);
                linkAsGos.Add(link.Key, linkGo);
            }

            foreach (KeyValuePair <string, UrdfUnity.Urdf.Models.Joint> joint in robo.Joints)
            {
                GameObject child = linkAsGos[joint.Value.Child.Name];
                child.transform.SetParent(linkAsGos[joint.Value.Parent.Name].transform);
                // Very strange, imported object will have the proper associated XYZ coordinates where as
                // a generated primitive types have the YZ coordinates are swapped.
                if (child.GetComponent <RosLinkModel>().hasMesh)
                {
                    child.transform.localPosition = new Vector3((float)joint.Value.Origin.Xyz.X, (float)joint.Value.Origin.Xyz.Y, (float)joint.Value.Origin.Xyz.Z);
                }
                else
                {
                    // URDF considers going up as the Z-axis where as unity consider going up is Y-axis
                    child.transform.localPosition = new Vector3((float)joint.Value.Origin.Xyz.X, (float)joint.Value.Origin.Xyz.Z, (float)joint.Value.Origin.Xyz.Y);
                }

                child.transform.localEulerAngles = new Vector3(Mathf.Rad2Deg * (float)joint.Value.Origin.Rpy.R, Mathf.Rad2Deg * (float)joint.Value.Origin.Rpy.Y, Mathf.Rad2Deg * (float)joint.Value.Origin.Rpy.P);
            }
            AssetDatabase.CreateFolder(prefabFolderPath, filename);
            PrefabUtility.CreatePrefab(string.Format(prefabPathFormat, filename, parent.name), parent);
            GameObject.DestroyImmediate(parent);
        }
        else
        {
            Debug.Log("Fail");
            LOGGER.Warn("No Robot generated from URDF.");
        }

        return(roboName);
    }