コード例 #1
0
ファイル: MJRemote.cs プロジェクト: arpit-kapoor/RL-Humanoid
    // update Unity representation of MuJoCo model
    unsafe private void UpdateModel()
    {
        MJP.TTransform transform;

        // update object states
        for (int i = 0; i < nobject; i++)
        {
            if (objects[i])
            {
                // set transform and visibility
                int visible;
                int selected;
                MJP.GetObjectState(i, &transform, &visible, &selected);
                SetTransform(objects[i], transform);
                objects[i].SetActive(visible > 0);

                // set emission color
                if (selected > 0)
                {
                    objects[i].GetComponent <Renderer>().material.SetColor("_EmissionColor", selcolor);
                }
                else
                {
                    objects[i].GetComponent <Renderer>().material.SetColor("_EmissionColor", Color.black);
                }
            }
        }

        // update camera
        MJP.GetCameraState(camindex, &transform);
        SetCamera(thecamera, transform);
        thecamera.fieldOfView = camfov[camindex + 1];
    }
コード例 #2
0
ファイル: MJRemote.cs プロジェクト: sts-sadr/furniture
    // update Unity representation of MuJoCo model
    unsafe private void UpdateModel()
    {
        MJP.TTransform transform;

        // update object states
        for (int i = 0; i < nobject; i++)
        {
            if (objects[i])
            {
                // set transform and visibility
                int visible;
                int selected;
                MJP.GetObjectState(i, &transform, &visible, &selected);

                // For Furniture Assembly Environment: apply new geom position
                if (modifiedObjects.ContainsKey(objects[i].name))
                {
                    objects[i].transform.position = modifiedObjects[objects[i].name];
                }
                else
                {
                    SetTransform(objects[i], transform);
                }
                objects[i].SetActive(visible > 0);

                // set emission color
                if (selected > 0)
                {
                    objects[i].GetComponent <Renderer>().material.SetColor("_EmissionColor", selcolor);
                }
                else
                {
                    objects[i].GetComponent <Renderer>().material.SetColor("_EmissionColor", Color.black);
                }
            }
        }

        // update camera
        MJP.GetCameraState(camindex, &transform);
        SetCamera(thecamera, transform);
        thecamera.fieldOfView = camfov[camindex + 1];
    }
コード例 #3
0
ファイル: MJSimulate.cs プロジェクト: ZWO2VPY6UT/grewRL
    // per-frame update
    unsafe void Update()
    {
        // process input
        ProcessKeyboard();
        if (Input.mousePresent)
        {
            ProcessMouse();
        }

        // update object states
        MJP.TTransform transform;
        for (int i = 0; i < nobject; i++)
        {
            if (objects[i])
            {
                int visible;
                int selected;
                MJP.GetObjectState(i, &transform, &visible, &selected);
                SetTransform(objects[i], transform);
                objects[i].SetActive(visible > 0);

                // set emission color
                if (selected > 0)
                {
                    objects[i].GetComponent <Renderer>().material.SetColor("_EmissionColor", selcolor);
                }
                else
                {
                    objects[i].GetComponent <Renderer>().material.SetColor("_EmissionColor", Color.black);
                }
            }
        }

        // update camera
        MJP.GetCameraState(camindex, &transform);
        SetCamera(thecamera, transform);
        thecamera.fieldOfView = camfov[camindex + 1];
    }
コード例 #4
0
ファイル: MJRemote.cs プロジェクト: sts-sadr/furniture
    // initialize
    unsafe void Start()
    {
        // For Furniture Assembly Environment: record geom positions
        modifiedObjects = new Dictionary <string, Vector3>();
        backgrounds     = new List <GameObject>();
        foreach (GameObject child in SceneManager.GetActiveScene().GetRootGameObjects())
        {
            if (child.name.StartsWith("Background_"))
            {
                backgrounds.Add(child);
                child.SetActive(false);
            }
        }

        //material_random_parameters["Plastic (Instance)"] = new RandomColor(0.0f, 1.0f, 0.0f, 1.0f, 0.2f, 1.0f);

        // set selection color
        selcolor = new Color(0.5f, 0.5f, 0.5f, 1);

        // preallocate buffer with maximum possible message size
        buffersize = 2048; // Math.Max(4, Math.Max(4*nqpos, 28*nmocap));
        buffer     = new byte[buffersize];

        // initialize plugin
        //   MJP.Initialize();
        //  MJP.LoadModel(Application.streamingAssetsPath + "/" + modelFile);

        // get number of renderable objects, allocate map
        MJP.TSize size;
        MJP.GetSize(&size);
        nqpos   = size.nqpos;
        nmocap  = size.nmocap;
        ncamera = size.ncamera;
        nobject = size.nobject;
        objects = new GameObject[nobject];

        // get root
        //root = GameObject.Find("MuJoCo");
        if (root == null)
        {
            throw new System.Exception("MuJoCo root object not found");
        }

        root.transform.localPosition = transform.localPosition;
        root.transform.localRotation = transform.localRotation;
        root.transform.localScale    = transform.localScale;

        // get camera under root
        int nchild = root.transform.childCount;

        for (int i = 0; i < nchild; i++)
        {
            thecamera = root.transform.GetChild(i).gameObject.GetComponent <Camera>();
            if (thecamera != null)
            {
                // thecamera.enabled = false;
                break;
            }
        }
        if (thecamera == null)
        {
            throw new System.Exception("No camera found under MuJoCo root object");
        }

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

            // find corresponding GameObject
            for (int j = 0; j < nchild; j++)
            {
                if (root.transform.GetChild(j).name == name.ToString())
                {
                    objects[i] = root.transform.GetChild(j).gameObject;
                    break;
                }
            }

            // set initial state
            if (objects[i])
            {
                MJP.TTransform transform;
                int            visible;
                int            selected;
                MJP.GetObjectState(i, &transform, &visible, &selected);
                SetTransform(objects[i], transform);
                objects[i].SetActive(visible > 0);
            }
        }

        // get camera fov and offscreen resolution
        camfov = new float[ncamera + 1];
        int offwidth  = 1280;
        int offheight = 720;

        for (int i = -1; i < ncamera; i++)
        {
            MJP.TCamera cam;
            MJP.GetCamera(i, &cam);
            camfov[i + 1] = cam.fov;

            // plugin returns offscreen width and height for all cameras
            offwidth  = cam.width;
            offheight = cam.height;
        }

        //TODO: The dummy camera and camera added by mjonline import should be merged together
        GameObject camobj = GameObject.Find("DummyCamera");

        if (camobj != null)
        {
            dummycamera         = camobj.GetComponent <Camera>();
            dummycamera.enabled = true;
        }

        // prepare offscreen rendering
        off_render = new OffscreenRenderer(offwidth, offheight);

        // synchronize time
        MJP.SetTime(Time.time);

        //randomizeAppearance();

        Debug.Log("New simulation init'd " + offwidth + "x" + offheight);
    }
コード例 #5
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]);
        }
    }
コード例 #6
0
ファイル: MJRemote.cs プロジェクト: arpit-kapoor/RL-Humanoid
    // initialize
    unsafe void Start()
    {
        // set selection color
        selcolor = new Color(0.5f, 0.5f, 0.5f, 1);

        // initialize plugin
        MJP.Initialize();
        MJP.LoadModel(Application.streamingAssetsPath + "/" + modelFile);

        // get number of renderable objects, allocate map
        MJP.TSize size;
        MJP.GetSize(&size);
        nqpos   = size.nqpos;
        nmocap  = size.nmocap;
        ncamera = size.ncamera;
        nobject = size.nobject;
        objects = new GameObject[nobject];

        // get root
        root = GameObject.Find("MuJoCo");
        if (root == null)
        {
            throw new System.Exception("MuJoCo root object not found");
        }

        // get camera under root
        int nchild = root.transform.childCount;

        for (int i = 0; i < nchild; i++)
        {
            thecamera = root.transform.GetChild(i).gameObject.GetComponent <Camera>();
            if (thecamera != null)
            {
                break;
            }
        }
        if (thecamera == null)
        {
            throw new System.Exception("No camera found under MuJoCo root object");
        }

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

            // find corresponding GameObject
            for (int j = 0; j < nchild; j++)
            {
                if (root.transform.GetChild(j).name == name.ToString())
                {
                    objects[i] = root.transform.GetChild(j).gameObject;
                    break;
                }
            }

            // set initial state
            if (objects[i])
            {
                MJP.TTransform transform;
                int            visible;
                int            selected;
                MJP.GetObjectState(i, &transform, &visible, &selected);
                SetTransform(objects[i], transform);
                objects[i].SetActive(visible > 0);
            }
        }

        // get camera fov and offscreen resolution
        camfov = new float[ncamera + 1];
        for (int i = -1; i < ncamera; i++)
        {
            MJP.TCamera cam;
            MJP.GetCamera(i, &cam);
            camfov[i + 1] = cam.fov;

            // plugin returns offscreen width and height for all cameras
            offwidth  = cam.width;
            offheight = cam.height;
        }

        // prepare offscreen rendering
        offtex       = new Texture2D(offwidth, offheight, TextureFormat.RGB24, false);
        offrt        = new RenderTexture(offwidth, offheight, 24);
        offrt.width  = offwidth;
        offrt.height = offheight;
        offrt.Create();

        // synchronize time
        MJP.SetTime(Time.time);

        // preallocate buffer with maximum possible message size
        buffersize = Math.Max(4, Math.Max(4 * nqpos, 28 * nmocap));
        buffer     = new byte[buffersize];

        // start listening for connections
        listener = new TcpListener(System.Net.IPAddress.Parse(tcpAddress), tcpPort);
        listener.Start();
    }
コード例 #7
0
ファイル: MJImport.cs プロジェクト: WarrG3X/DobotVR
    // 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();
    }
コード例 #8
0
ファイル: MJSimulate.cs プロジェクト: sts-sadr/furniture
    // initialize
    unsafe void Start()
    {
        // set selection color
        selcolor = new Color(0.5f, 0.5f, 0.5f, 1);

        // initialize plugin
        ////  MJP.Initialize();
        //  MJP.LoadModel(Application.streamingAssetsPath + "/" + modelFile);

        // get number of renderable objects, allocate map
        MJP.TSize size;
        MJP.GetSize(&size);
        ncamera = size.ncamera;
        nobject = size.nobject;
        objects = new GameObject[nobject];

        // get root
        // root = GameObject.Find("MuJoCo");
        if (root == null)
        {
            throw new System.Exception("MuJoCo root object not found");
        }

        // get camera under root
        int nchild = root.transform.childCount;

        for (int i = 0; i < nchild; i++)
        {
            thecamera = root.transform.GetChild(i).gameObject.GetComponent <Camera>();
            if (thecamera != null)
            {
                break;
            }
        }
        if (thecamera == null)
        {
            throw new System.Exception("No camera found under MuJoCo root object");
        }

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

            // find corresponding GameObject
            for (int j = 0; j < nchild; j++)
            {
                if (root.transform.GetChild(j).name == name.ToString())
                {
                    objects[i] = root.transform.GetChild(j).gameObject;
                    break;
                }
            }

            // set initial state
            if (objects[i])
            {
                MJP.TTransform transform;
                int            visible;
                int            selected;
                MJP.GetObjectState(i, &transform, &visible, &selected);
                SetTransform(objects[i], transform);
                objects[i].SetActive(visible > 0);
            }
        }

        int offwidth  = 1280;
        int offheight = 720;

        // get camera fov and offscreen resolution
        camfov = new float[ncamera + 1];
        for (int i = -1; i < ncamera; i++)
        {
            MJP.TCamera cam;
            MJP.GetCamera(i, &cam);
            camfov[i + 1] = cam.fov;

            // plugin returns offscreen width and height for all cameras
            offwidth  = cam.width;
            offheight = cam.height;
        }

        off_render = new OffscreenRenderer(offwidth, offheight);

        // synchronize time
        MJP.SetTime(Time.time);
        videotime = Time.time;
    }