Example #1
0
    // import materials
    private unsafe void ImportMaterials(int nmaterial)
    {
        // allocate array, find all existing
        materials = new Material[nmaterial];
        Object[] allmaterials = Resources.FindObjectsOfTypeAll(typeof(Material));

        // process materials
        for (int i = 0; i < nmaterial; i++)
        {
            // get material name
            StringBuilder name = new StringBuilder(100);
            MJP.GetElementName(MJP.TElement.MATERIAL, i, name, 100);
            string matname = fileName + "_" + name.ToString();

            // find existing material
            foreach (Object matt in allmaterials)
            {
                if (matt != null && matt.name == matname)
                {
                    materials[i] = (Material)matt;
                    break;
                }
            }

            // not found: create new material
            materials[i] = new Material(Shader.Find("Standard"));

            // get material descriptor and save
            MJP.TMaterial mat;
            MJP.GetMaterial(i, &mat);

            // set properties
            materials[i].name = matname;
            materials[i].EnableKeyword("_EMISSION");
            materials[i].SetColor("_Color", new Color(mat.color[0], mat.color[1], mat.color[2], mat.color[3]));
            materials[i].SetColor("_EmissionColor", new Color(mat.emission, mat.emission, mat.emission, 1));
            if (mat.color[3] < 1)
            {
                materials[i].SetFloat("_Mode", 3.0f);
            }

            // set texture if present
            if (mat.texture >= 0 && importTexture)
            {
                materials[i].mainTexture      = textures[mat.texture];
                materials[i].mainTextureScale = new Vector2(mat.texrepeat[0], mat.texrepeat[1]);
            }

            // create asset in database if not aleady there
            if (!AssetDatabase.Contains(materials[i]))
            {
                AssetDatabase.CreateAsset(materials[i], "Assets/Materials/" + matname + ".mat");
            }
        }

        AssetDatabase.Refresh();
    }
Example #2
0
    private unsafe void ImportLights(int nlight)
    {
        // allocate array
        objects = new GameObject[nlight];

        // process objects
        for (int i = 0; i < nlight; i++)
        {
            // get object name
            StringBuilder name = new StringBuilder(100);
            MJP.GetElementName(MJP.TElement.LIGHT, i, name, 100);
            if (name.Length == 0)
            {
                name.Append("Light "); name.Append(i);
            }
            // create new GameObject, place under root
            objects[i] = new GameObject(name.ToString());
            Light lightComp = objects[i].AddComponent <Light>();

            objects[i].transform.parent = root.transform;
            // get MuJoCo object descriptor
            MJP.TLight obj;
            MJP.GetLight(i, &obj);
            //GetLightState
            // set mesh

            lightComp.type    = obj.directional != 0 ? LightType.Directional : LightType.Point;
            lightComp.shadows = obj.castshadow == 0 ? LightShadows.None : LightShadows.Soft;
            lightComp.color   = new Color(obj.diffuse[0], obj.diffuse[1], obj.diffuse[2]);
            lightComp.range   = (float)Math.Sqrt(255 / obj.attenuation[2]);
            float[] pos = { 0, 0, 0 };
            float[] dir = { 0, 0, 0 };

            fixed(float *ppos = pos)
            fixed(float *pdir = dir)

            MJP.GetLightState(i, 0, ppos, pdir);

            objects[i].transform.localPosition = new Vector3(-pos[0], pos[2], -pos[1]);
            objects[i].transform.rotation      = Quaternion.LookRotation(new Vector3(-dir[0], dir[2], -dir[1]), Vector3.up);
        }
    }
Example #3
0
    // import materials
    private unsafe void ImportMaterials(int nmaterial)
    {
        if (default_material == null)
        {
            Debug.Log("Skipped assigning a material because material is missing");
        }
        else
        {
            materials.Add(-1, new Material(default_material));
        }

        // process materials
        for (int i = 0; i < nmaterial; i++)
        {
            // get material name
            StringBuilder name = new StringBuilder(100);
            MJP.GetElementName(MJP.TElement.MATERIAL, i, name, 100);
            string matname = name.ToString();

            Material matt = Resources.Load <Material>("Materials/" + matname);

            if (matt == null)
            {
                Debug.Log("No material for " + matname + " in Resources");

                if (default_material == null)
                {
                    Debug.Log("Skipped assigning a material because material is missing");
                }
                else
                {
                    matt = new Material(default_material);
                }
            }

            if (matt != null)
            {
                materials.Add(i, matt);
            }
        }
    }
Example #4
0
    // import renderable objects
    private unsafe void ImportObjects(int nobject)
    {
        string cwd = Path.GetDirectoryName(modelFile);

        // make primitives
        PrimitiveType[] ptypes =
        {
            PrimitiveType.Plane,
            PrimitiveType.Sphere,
            PrimitiveType.Cylinder,
            PrimitiveType.Cube
        };
        GameObject[] primitives = new GameObject[4];
        for (int i = 0; i < 4; i++)
        {
            primitives[i] = GameObject.CreatePrimitive(ptypes[i]);
        }

        // allocate array
        objects = new GameObject[nobject];

        // process objects
        for (int i = 0; i < nobject; i++)
        {
            // get object name
            StringBuilder name = new StringBuilder(100);
            MJP.GetObjectName(i, name, 100);

            // create new GameObject, place under root
            objects[i] = new GameObject(name.ToString());
            MeshFilter     filt   = objects[i].AddComponent <MeshFilter>();
            MeshRenderer   rend   = objects[i].AddComponent <MeshRenderer>();
            InstancedColor colors = objects[i].AddComponent <InstancedColor>();

            objects[i].transform.parent = root.transform;
            // get MuJoCo object descriptor
            MJP.TObject obj;
            MJP.GetObject(i, &obj);

            // For Furniture Assembly Environment: do not visualize site
            if (obj.category == (int)MJP.TCategory.SITE && !objects[i].name.Contains("conn"))
            {
                objects[i].layer = 9;
            }
            if (objects[i].name.StartsWith("noviz", StringComparison.Ordinal))
            {
                objects[i].layer = 10;
            }
            if (objects[i].name.StartsWith("floor", StringComparison.Ordinal))
            {
                objects[i].layer = 10;
            }

            // set mesh
            switch ((MJP.TGeom)obj.geomtype)
            {
            case MJP.TGeom.PLANE:
                filt.sharedMesh = primitives[0].GetComponent <MeshFilter>().sharedMesh;
                break;

            case MJP.TGeom.SPHERE:
                filt.sharedMesh = primitives[1].GetComponent <MeshFilter>().sharedMesh;
                break;

            case MJP.TGeom.CYLINDER:
                filt.sharedMesh = primitives[2].GetComponent <MeshFilter>().sharedMesh;
                break;

            case MJP.TGeom.BOX:
                filt.sharedMesh = primitives[3].GetComponent <MeshFilter>().sharedMesh;
                break;

            case MJP.TGeom.HFIELD:
                int nrow = obj.hfield_nrow;
                int ncol = obj.hfield_ncol;
                int r, c;

                // allocate
                Vector3[] hfvertices = new Vector3[nrow * ncol + 4 * nrow + 4 * ncol];
                Vector2[] hfuv       = new Vector2[nrow * ncol + 4 * nrow + 4 * ncol];
                int[]     hffaces0   = new int[3 * 2 * (nrow - 1) * (ncol - 1)];
                int[]     hffaces1   = new int[3 * (4 * (nrow - 1) + 4 * (ncol - 1))];

                // vertices and uv: surface
                for (r = 0; r < nrow; r++)
                {
                    for (c = 0; c < ncol; c++)
                    {
                        int   k  = r * ncol + c;
                        float wc = c / (float)(ncol - 1);
                        float wr = r / (float)(nrow - 1);

                        hfvertices[k].Set(-(wc - 0.5f), obj.hfield_data[k], -(wr - 0.5f));
                        hfuv[k].Set(wc, wr);
                    }
                }

                // vertices and uv: front and back
                for (r = 0; r < nrow; r += (nrow - 1))
                {
                    for (c = 0; c < ncol; c++)
                    {
                        int   k  = nrow * ncol + 2 * ((r > 0?ncol:0) + c);
                        float wc = c / (float)(ncol - 1);
                        float wr = r / (float)(nrow - 1);

                        hfvertices[k].Set(-(wc - 0.5f), -0.5f, -(wr - 0.5f));
                        hfuv[k].Set(wc, 0);
                        hfvertices[k + 1].Set(-(wc - 0.5f), obj.hfield_data[r * ncol + c], -(wr - 0.5f));
                        hfuv[k + 1].Set(wc, 1);
                    }
                }

                // vertices and uv: left and right
                for (c = 0; c < ncol; c += (ncol - 1))
                {
                    for (r = 0; r < nrow; r++)
                    {
                        int   k  = nrow * ncol + 4 * ncol + 2 * ((c > 0?nrow:0) + r);
                        float wc = c / (float)(ncol - 1);
                        float wr = r / (float)(nrow - 1);

                        hfvertices[k].Set(-(wc - 0.5f), -0.5f, -(wr - 0.5f));
                        hfuv[k].Set(wr, 0);
                        hfvertices[k + 1].Set(-(wc - 0.5f), obj.hfield_data[r * ncol + c], -(wr - 0.5f));
                        hfuv[k + 1].Set(wr, 1);
                    }
                }


                // faces: surface
                for (r = 0; r < nrow - 1; r++)
                {
                    for (c = 0; c < ncol - 1; c++)
                    {
                        int f = r * (ncol - 1) + c;
                        int k = r * ncol + c;

                        // first face in rectangle
                        hffaces0[3 * 2 * f]     = k;
                        hffaces0[3 * 2 * f + 2] = k + 1;
                        hffaces0[3 * 2 * f + 1] = k + ncol + 1;

                        // second face in rectangle
                        hffaces0[3 * 2 * f + 3] = k;
                        hffaces0[3 * 2 * f + 5] = k + ncol + 1;
                        hffaces0[3 * 2 * f + 4] = k + ncol;
                    }
                }

                // faces: front and back
                for (r = 0; r < 2; r++)
                {
                    for (c = 0; c < ncol - 1; c++)
                    {
                        int f = ((r > 0?(ncol - 1):0) + c);
                        int k = nrow * ncol + 2 * ((r > 0?ncol:0) + c);

                        // first face in rectangle
                        hffaces1[3 * 2 * f]     = k;
                        hffaces1[3 * 2 * f + 2] = k + (r > 0 ? 1 : 3);
                        hffaces1[3 * 2 * f + 1] = k + (r > 0 ? 3 : 1);

                        // second face in rectangle
                        hffaces1[3 * 2 * f + 3] = k;
                        hffaces1[3 * 2 * f + 5] = k + (r > 0 ? 3 : 2);
                        hffaces1[3 * 2 * f + 4] = k + (r > 0 ? 2 : 3);
                    }
                }

                // faces: left and right
                for (c = 0; c < 2; c++)
                {
                    for (r = 0; r < nrow - 1; r++)
                    {
                        int f = 2 * (ncol - 1) + ((c > 0?(nrow - 1):0) + r);
                        int k = nrow * ncol + 4 * ncol + 2 * ((c > 0?nrow:0) + r);

                        // first face in rectangle
                        hffaces1[3 * 2 * f]     = k;
                        hffaces1[3 * 2 * f + 2] = k + (c > 0 ? 3 : 1);
                        hffaces1[3 * 2 * f + 1] = k + (c > 0 ? 1 : 3);

                        // second face in rectangle
                        hffaces1[3 * 2 * f + 3] = k;
                        hffaces1[3 * 2 * f + 5] = k + (c > 0 ? 2 : 3);
                        hffaces1[3 * 2 * f + 4] = k + (c > 0 ? 3 : 2);
                    }
                }

                Debug.Log(ncol);
                Debug.Log(nrow);
                Debug.Log(Mathf.Min(hffaces1));
                Debug.Log(Mathf.Max(hffaces1));

                // create mesh with automatic normals and tangents
                filt.sharedMesh              = new Mesh();
                filt.sharedMesh.vertices     = hfvertices;
                filt.sharedMesh.uv           = hfuv;
                filt.sharedMesh.subMeshCount = 2;
                filt.sharedMesh.SetTriangles(hffaces0, 0);
                filt.sharedMesh.SetTriangles(hffaces1, 1);
                filt.sharedMesh.RecalculateNormals();
                filt.sharedMesh.RecalculateTangents();

                // set name
                StringBuilder hname = new StringBuilder(100);
                MJP.GetElementName(MJP.TElement.HFIELD, obj.dataid, hname, 100);
                filt.sharedMesh.name = hname.ToString();
                break;

            case MJP.TGeom.CAPSULE:
            case MJP.TGeom.MESH:
                // reuse shared mesh from earlier object
                if (obj.mesh_shared >= 0)
                {
                    filt.sharedMesh = objects[obj.mesh_shared].GetComponent <MeshFilter>().sharedMesh;
                }

                // create new mesh
                else
                {
                    string meshName;
                    // set name
                    if ((MJP.TGeom)obj.geomtype == MJP.TGeom.CAPSULE)
                    {
                        meshName = "Capsule mesh";
                    }
                    else
                    {
                        StringBuilder mname = new StringBuilder(100);
                        MJP.GetElementName(MJP.TElement.MESH, obj.dataid, mname, 100);
                        meshName = mname.ToString();
                    }

                    {
                        // copy vertices, normals, uv
                        Vector3[] vertices = new Vector3[obj.mesh_nvertex];
                        Vector3[] normals  = new Vector3[obj.mesh_nvertex];
                        Vector2[] uv       = new Vector2[obj.mesh_nvertex];
                        for (int k = 0; k < obj.mesh_nvertex; k++)
                        {
                            vertices[k].Set(-obj.mesh_position[3 * k],
                                            obj.mesh_position[3 * k + 2],
                                            -obj.mesh_position[3 * k + 1]);

                            normals[k].Set(-obj.mesh_normal[3 * k],
                                           obj.mesh_normal[3 * k + 2],
                                           -obj.mesh_normal[3 * k + 1]);

                            uv[k].Set(obj.mesh_texcoord[2 * k],
                                      obj.mesh_texcoord[2 * k + 1]);
                        }

                        // copy faces
                        int[] faces = new int[3 * obj.mesh_nface];
                        for (int k = 0; k < obj.mesh_nface; k++)
                        {
                            faces[3 * k]     = obj.mesh_face[3 * k];
                            faces[3 * k + 1] = obj.mesh_face[3 * k + 2];
                            faces[3 * k + 2] = obj.mesh_face[3 * k + 1];
                        }

                        // number of verices can be modified by uncompressed mesh
                        int nvert = obj.mesh_nvertex;


                        // replace with uncompressed mesh when UV needs to be recomputed
                        // ( recomputeUV && (MJP.TGeom)obj.geomtype==MJP.TGeom.MESH )
                        {
                            // make temporary mesh
                            Mesh temp = new Mesh();
                            temp.vertices  = vertices;
                            temp.normals   = normals;
                            temp.triangles = faces;

                            // generate uncompressed UV unwrapping

                            /* Vector2[] UV = Unwrapping.GeneratePerTriangleUV(temp);
                             * int N = UV.GetLength(0)/3;
                             * if( N!=obj.mesh_nface )
                             *   throw new System.Exception("Unexpected number of faces");
                             * nvert = 3*N;*/
                            int N = obj.mesh_nface;
                            nvert = 3 * N;
                            // create corresponding uncompressed vertices, normals, faces
                            Vector3[] Vertex = new Vector3[3 * N];
                            Vector3[] Normal = new Vector3[3 * N];
                            int[]     Face   = new int[3 * N];
                            for (int k = 0; k < N; k++)
                            {
                                Vertex[3 * k]     = vertices[faces[3 * k]];
                                Vertex[3 * k + 1] = vertices[faces[3 * k + 1]];
                                Vertex[3 * k + 2] = vertices[faces[3 * k + 2]];

                                Normal[3 * k]     = normals[faces[3 * k]];
                                Normal[3 * k + 1] = normals[faces[3 * k + 1]];
                                Normal[3 * k + 2] = normals[faces[3 * k + 2]];

                                Face[3 * k]     = 3 * k;
                                Face[3 * k + 1] = 3 * k + 1;
                                Face[3 * k + 2] = 3 * k + 2;
                            }

                            // create uncompressed mesh
                            filt.sharedMesh             = new Mesh();
                            filt.sharedMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                            filt.sharedMesh.vertices    = Vertex;
                            filt.sharedMesh.normals     = Normal;
                            filt.sharedMesh.triangles   = Face;
                            filt.sharedMesh.name        = meshName;

                            // filt.sharedMesh.uv = UV;
                        }

                        // otherwise create mesh directly

                        /*   else
                         * {
                         *     filt.sharedMesh = new Mesh();
                         *     filt.sharedMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                         *     filt.sharedMesh.vertices = vertices;
                         *     filt.sharedMesh.normals = normals;
                         *     filt.sharedMesh.triangles = faces;
                         *     filt.sharedMesh.uv = uv;
                         *     filt.sharedMesh.name = meshName;
                         *     filt.sharedMesh.RecalculateNormals(30);
                         * }*/

                        // optionally recompute normals for meshes

                        /*   if (recomputeNormal && (MJP.TGeom)obj.geomtype == MJP.TGeom.MESH)
                         *     filt.sharedMesh.RecalculateNormals(60);*/

                        filt.sharedMesh.RecalculateNormals(25);
                        // always calculate tangents (MuJoCo does not support tangents)
                        filt.sharedMesh.RecalculateTangents();
                    }

                    // print error if number of vertices or faces is over 65535

                    /* if( obj.mesh_nface>65535 || nvert>65535 )
                     *   Debug.LogError("MESH TOO BIG: " + filt.sharedMesh.name +
                     *                  ", vertices " + nvert + ", faces " + obj.mesh_nface);*/
                }
                break;
            }

            //TODO: Set segmentation color with Material.SetColor("_SegColor")
            // existing material

            byte segmentation = 0;
            // Try to get segmentation id. If nothing is found, the object will remain background (0)
            if (meshSegmentMap.TryGetValue(name.ToString(), out segmentation) == false)
            {
                meshSegmentMap.TryGetValue(filt.sharedMesh.name, out segmentation);
            }
            Material base_material = null;

            if (materials.TryGetValue(obj.material, out base_material))
            {
                rend.sharedMaterial = base_material;
                colors.Diffuse      = new Color(obj.color[0], obj.color[1], obj.color[2], obj.color[3]);
                colors.Segmentation = new Color32(segmentation, segmentation, segmentation, segmentation);
            }
            else // Missing material (shouldn't be possible?)
            {
                Debug.Log("Couldn't find a Material for id:" + obj.material);
            }


            // get MuJoCo object transform and set in Unity
            MJP.TTransform transform;
            int            visible;
            int            selected;
            MJP.GetObjectState(i, &transform, &visible, &selected);
            SetTransform(objects[i], transform);
        }

        // delete primitives
        for (int i = 0; i < 4; i++)
        {
            Destroy(primitives[i]);
        }
    }
Example #5
0
    // import renderable objects
    private unsafe void ImportObjects(int nobject)
    {
        // make primitives
        PrimitiveType[] ptypes =
        {
            PrimitiveType.Plane,
            PrimitiveType.Sphere,
            PrimitiveType.Cylinder,
            PrimitiveType.Cube
        };
        GameObject[] primitives = new GameObject[4];
        for (int i = 0; i < 4; i++)
        {
            primitives[i] = GameObject.CreatePrimitive(ptypes[i]);
        }

        // allocate array
        objects = new GameObject[nobject];

        // process objects
        for (int i = 0; i < nobject; i++)
        {
            // get object name
            StringBuilder name = new StringBuilder(100);
            MJP.GetObjectName(i, name, 100);

            // create new GameObject, place under root
            objects[i] = new GameObject(name.ToString());
            objects[i].AddComponent <MeshFilter>();
            objects[i].AddComponent <MeshRenderer>();
            objects[i].transform.parent = root.transform;

            // get components
            MeshFilter   filt = objects[i].GetComponent <MeshFilter>();
            MeshRenderer rend = objects[i].GetComponent <MeshRenderer>();

            // get MuJoCo object descriptor
            MJP.TObject obj;
            MJP.GetObject(i, &obj);

            // set mesh
            switch ((MJP.TGeom)obj.geomtype)
            {
            case MJP.TGeom.PLANE:
                filt.sharedMesh = primitives[0].GetComponent <MeshFilter>().sharedMesh;
                break;

            case MJP.TGeom.SPHERE:
                filt.sharedMesh = primitives[1].GetComponent <MeshFilter>().sharedMesh;
                break;

            case MJP.TGeom.CYLINDER:
                filt.sharedMesh = primitives[2].GetComponent <MeshFilter>().sharedMesh;
                break;

            case MJP.TGeom.BOX:
                filt.sharedMesh = primitives[3].GetComponent <MeshFilter>().sharedMesh;
                break;

            case MJP.TGeom.HFIELD:
                int nrow = obj.hfield_nrow;
                int ncol = obj.hfield_ncol;
                int r, c;

                // allocate
                Vector3[] hfvertices = new Vector3[nrow * ncol + 4 * nrow + 4 * ncol];
                Vector2[] hfuv       = new Vector2[nrow * ncol + 4 * nrow + 4 * ncol];
                int[]     hffaces0   = new int[3 * 2 * (nrow - 1) * (ncol - 1)];
                int[]     hffaces1   = new int[3 * (4 * (nrow - 1) + 4 * (ncol - 1))];

                // vertices and uv: surface
                for (r = 0; r < nrow; r++)
                {
                    for (c = 0; c < ncol; c++)
                    {
                        int   k  = r * ncol + c;
                        float wc = c / (float)(ncol - 1);
                        float wr = r / (float)(nrow - 1);

                        hfvertices[k].Set(-(wc - 0.5f), obj.hfield_data[k], -(wr - 0.5f));
                        hfuv[k].Set(wc, wr);
                    }
                }

                // vertices and uv: front and back
                for (r = 0; r < nrow; r += (nrow - 1))
                {
                    for (c = 0; c < ncol; c++)
                    {
                        int   k  = nrow * ncol + 2 * ((r > 0?ncol:0) + c);
                        float wc = c / (float)(ncol - 1);
                        float wr = r / (float)(nrow - 1);

                        hfvertices[k].Set(-(wc - 0.5f), -0.5f, -(wr - 0.5f));
                        hfuv[k].Set(wc, 0);
                        hfvertices[k + 1].Set(-(wc - 0.5f), obj.hfield_data[r * ncol + c], -(wr - 0.5f));
                        hfuv[k + 1].Set(wc, 1);
                    }
                }

                // vertices and uv: left and right
                for (c = 0; c < ncol; c += (ncol - 1))
                {
                    for (r = 0; r < nrow; r++)
                    {
                        int   k  = nrow * ncol + 4 * ncol + 2 * ((c > 0?nrow:0) + r);
                        float wc = c / (float)(ncol - 1);
                        float wr = r / (float)(nrow - 1);

                        hfvertices[k].Set(-(wc - 0.5f), -0.5f, -(wr - 0.5f));
                        hfuv[k].Set(wr, 0);
                        hfvertices[k + 1].Set(-(wc - 0.5f), obj.hfield_data[r * ncol + c], -(wr - 0.5f));
                        hfuv[k + 1].Set(wr, 1);
                    }
                }


                // faces: surface
                for (r = 0; r < nrow - 1; r++)
                {
                    for (c = 0; c < ncol - 1; c++)
                    {
                        int f = r * (ncol - 1) + c;
                        int k = r * ncol + c;

                        // first face in rectangle
                        hffaces0[3 * 2 * f]     = k;
                        hffaces0[3 * 2 * f + 2] = k + 1;
                        hffaces0[3 * 2 * f + 1] = k + ncol + 1;

                        // second face in rectangle
                        hffaces0[3 * 2 * f + 3] = k;
                        hffaces0[3 * 2 * f + 5] = k + ncol + 1;
                        hffaces0[3 * 2 * f + 4] = k + ncol;
                    }
                }

                // faces: front and back
                for (r = 0; r < 2; r++)
                {
                    for (c = 0; c < ncol - 1; c++)
                    {
                        int f = ((r > 0?(ncol - 1):0) + c);
                        int k = nrow * ncol + 2 * ((r > 0?ncol:0) + c);

                        // first face in rectangle
                        hffaces1[3 * 2 * f]     = k;
                        hffaces1[3 * 2 * f + 2] = k + (r > 0 ? 1 : 3);
                        hffaces1[3 * 2 * f + 1] = k + (r > 0 ? 3 : 1);

                        // second face in rectangle
                        hffaces1[3 * 2 * f + 3] = k;
                        hffaces1[3 * 2 * f + 5] = k + (r > 0 ? 3 : 2);
                        hffaces1[3 * 2 * f + 4] = k + (r > 0 ? 2 : 3);
                    }
                }

                // faces: left and right
                for (c = 0; c < 2; c++)
                {
                    for (r = 0; r < nrow - 1; r++)
                    {
                        int f = 2 * (ncol - 1) + ((c > 0?(nrow - 1):0) + r);
                        int k = nrow * ncol + 4 * ncol + 2 * ((c > 0?nrow:0) + r);

                        // first face in rectangle
                        hffaces1[3 * 2 * f]     = k;
                        hffaces1[3 * 2 * f + 2] = k + (c > 0 ? 3 : 1);
                        hffaces1[3 * 2 * f + 1] = k + (c > 0 ? 1 : 3);

                        // second face in rectangle
                        hffaces1[3 * 2 * f + 3] = k;
                        hffaces1[3 * 2 * f + 5] = k + (c > 0 ? 2 : 3);
                        hffaces1[3 * 2 * f + 4] = k + (c > 0 ? 3 : 2);
                    }
                }

                Debug.Log(ncol);
                Debug.Log(nrow);
                Debug.Log(Mathf.Min(hffaces1));
                Debug.Log(Mathf.Max(hffaces1));

                // create mesh with automatic normals and tangents
                filt.sharedMesh              = new Mesh();
                filt.sharedMesh.vertices     = hfvertices;
                filt.sharedMesh.uv           = hfuv;
                filt.sharedMesh.subMeshCount = 2;
                filt.sharedMesh.SetTriangles(hffaces0, 0);
                filt.sharedMesh.SetTriangles(hffaces1, 1);
                filt.sharedMesh.RecalculateNormals();
                filt.sharedMesh.RecalculateTangents();

                // set name
                StringBuilder hname = new StringBuilder(100);
                MJP.GetElementName(MJP.TElement.HFIELD, obj.dataid, hname, 100);
                filt.sharedMesh.name = hname.ToString();
                break;

            case MJP.TGeom.CAPSULE:
            case MJP.TGeom.MESH:
                // reuse shared mesh from earlier object
                if (obj.mesh_shared >= 0)
                {
                    filt.sharedMesh = objects[obj.mesh_shared].GetComponent <MeshFilter>().sharedMesh;
                }

                // create new mesh
                else
                {
                    // copy vertices, normals, uv
                    Vector3[] vertices = new Vector3[obj.mesh_nvertex];
                    Vector3[] normals  = new Vector3[obj.mesh_nvertex];
                    Vector2[] uv       = new Vector2[obj.mesh_nvertex];
                    for (int k = 0; k < obj.mesh_nvertex; k++)
                    {
                        vertices[k].Set(-obj.mesh_position[3 * k],
                                        obj.mesh_position[3 * k + 2],
                                        -obj.mesh_position[3 * k + 1]);

                        normals[k].Set(-obj.mesh_normal[3 * k],
                                       obj.mesh_normal[3 * k + 2],
                                       -obj.mesh_normal[3 * k + 1]);

                        uv[k].Set(obj.mesh_texcoord[2 * k],
                                  obj.mesh_texcoord[2 * k + 1]);
                    }

                    // copy faces
                    int[] faces = new int[3 * obj.mesh_nface];
                    for (int k = 0; k < obj.mesh_nface; k++)
                    {
                        faces[3 * k]     = obj.mesh_face[3 * k];
                        faces[3 * k + 1] = obj.mesh_face[3 * k + 2];
                        faces[3 * k + 2] = obj.mesh_face[3 * k + 1];
                    }

                    // number of verices can be modified by uncompressed mesh
                    int nvert = obj.mesh_nvertex;

                    // replace with uncompressed mesh when UV needs to be recomputed
                    if (recomputeUV && (MJP.TGeom)obj.geomtype == MJP.TGeom.MESH)
                    {
                        // make temporary mesh
                        Mesh temp = new Mesh();
                        temp.vertices  = vertices;
                        temp.normals   = normals;
                        temp.triangles = faces;

                        // generate uncompressed UV unwrapping
                        Vector2[] UV = Unwrapping.GeneratePerTriangleUV(temp);
                        int       N  = UV.GetLength(0) / 3;
                        if (N != obj.mesh_nface)
                        {
                            throw new System.Exception("Unexpected number of faces");
                        }
                        nvert = 3 * N;

                        // create corresponding uncompressed vertices, normals, faces
                        Vector3[] Vertex = new Vector3[3 * N];
                        Vector3[] Normal = new Vector3[3 * N];
                        int[]     Face   = new int[3 * N];
                        for (int k = 0; k < N; k++)
                        {
                            Vertex[3 * k]     = vertices[faces[3 * k]];
                            Vertex[3 * k + 1] = vertices[faces[3 * k + 1]];
                            Vertex[3 * k + 2] = vertices[faces[3 * k + 2]];

                            Normal[3 * k]     = normals[faces[3 * k]];
                            Normal[3 * k + 1] = normals[faces[3 * k + 1]];
                            Normal[3 * k + 2] = normals[faces[3 * k + 2]];

                            Face[3 * k]     = 3 * k;
                            Face[3 * k + 1] = 3 * k + 1;
                            Face[3 * k + 2] = 3 * k + 2;
                        }

                        // create uncompressed mesh
                        filt.sharedMesh           = new Mesh();
                        filt.sharedMesh.vertices  = Vertex;
                        filt.sharedMesh.normals   = Normal;
                        filt.sharedMesh.triangles = Face;
                        filt.sharedMesh.uv        = UV;
                    }

                    // otherwise create mesh directly
                    else
                    {
                        filt.sharedMesh           = new Mesh();
                        filt.sharedMesh.vertices  = vertices;
                        filt.sharedMesh.normals   = normals;
                        filt.sharedMesh.triangles = faces;
                        filt.sharedMesh.uv        = uv;
                    }

                    // optionally recompute normals for meshes
                    if (recomputeNormal && (MJP.TGeom)obj.geomtype == MJP.TGeom.MESH)
                    {
                        filt.sharedMesh.RecalculateNormals();
                    }

                    // always calculate tangents (MuJoCo does not support tangents)
                    filt.sharedMesh.RecalculateTangents();

                    // set name
                    if ((MJP.TGeom)obj.geomtype == MJP.TGeom.CAPSULE)
                    {
                        filt.sharedMesh.name = "Capsule mesh";
                    }
                    else
                    {
                        StringBuilder mname = new StringBuilder(100);
                        MJP.GetElementName(MJP.TElement.MESH, obj.dataid, mname, 100);
                        filt.sharedMesh.name = mname.ToString();
                    }

                    // print error if number of vertices or faces is over 65535
                    if (obj.mesh_nface > 65535 || nvert > 65535)
                    {
                        Debug.LogError("MESH TOO BIG: " + filt.sharedMesh.name +
                                       ", vertices " + nvert + ", faces " + obj.mesh_nface);
                    }
                }
                break;
            }

            // existing material
            if (obj.material >= 0)
            {
                // not modified
                if (obj.color[0] == 0.5f && obj.color[1] == 0.5f && obj.color[2] == 0.5f && obj.color[3] == 1)
                {
                    rend.sharedMaterial = materials[obj.material];
                }

                // color override
                else
                {
                    rend.sharedMaterial = new Material(materials[obj.material]);
                    AdjustMaterial(rend.sharedMaterial, obj.color[0], obj.color[1], obj.color[2], obj.color[3]);
                }
            }

            // new material
            else
            {
                rend.sharedMaterial = new Material(Shader.Find("Standard"));
                AdjustMaterial(rend.sharedMaterial, obj.color[0], obj.color[1], obj.color[2], obj.color[3]);
            }

            // get MuJoCo object transform and set in Unity
            MJP.TTransform transform;
            int            visible;
            int            selected;
            MJP.GetObjectState(i, &transform, &visible, &selected);
            SetTransform(objects[i], transform);
        }

        // delete primitives
        for (int i = 0; i < 4; i++)
        {
            DestroyImmediate(primitives[i]);
        }

        AssetDatabase.Refresh();
    }
Example #6
0
    // import textures
    private unsafe void ImportTextures(int ntexture)
    {
        // allocate array, find existing
        textures = new Texture2D[ntexture];
        Object[] alltextures = Resources.FindObjectsOfTypeAll(typeof(Texture2D));

        // process textures
        for (int i = 0; i < ntexture; i++)
        {
            // get texture name
            StringBuilder name = new StringBuilder(100);
            MJP.GetElementName(MJP.TElement.TEXTURE, i, name, 100);
            string texname = fileName + "_" + name.ToString();

            // get texture descriptor and save
            MJP.TTexture tex;
            MJP.GetTexture(i, &tex);

            // MuJoCo cube texture: use only top piece
            if (tex.cube > 0)
            {
                tex.height = tex.width;
            }

            // find existing texture
            foreach (Object texx in alltextures)
            {
                if (texx.name == texname)
                {
                    textures[i] = (Texture2D)texx;

                    // resize if different
                    if (textures[i].width != tex.width || textures[i].height != tex.height)
                    {
                        textures[i].Resize(tex.width, tex.height);
                    }

                    break;
                }
            }

            // not found: create new texture
            if (textures[i] == null)
            {
                textures[i] = new Texture2D(tex.width, tex.height);
            }

            // copy array
            Color32[] color = new Color32[tex.width * tex.height];
            for (int k = 0; k < tex.width * tex.height; k++)
            {
                color[k].r = tex.rgb[3 * k];
                color[k].g = tex.rgb[3 * k + 1];
                color[k].b = tex.rgb[3 * k + 2];
                color[k].a = 255;
            }

            // load data and apply
            textures[i].SetPixels32(color);
            textures[i].Apply();

            // create asset in database if not aleady there
            if (!AssetDatabase.Contains(textures[i]))
            {
                AssetDatabase.CreateAsset(textures[i], "Assets/Textures/" + texname + ".asset");
            }
        }

        AssetDatabase.Refresh();
    }