Exemplo n.º 1
0
        [MenuItem("Hypercube/Copy current slice calibration", false, 300)]  //# is prio
        public static void openCubeWindowPrefs()
        {
            calibrator c = GameObject.FindObjectOfType <calibrator>();

            if (c)
            {
                c.copyCurrentSliceCalibration();
            }
            else
            {
                Debug.LogWarning("No calibrator was found, and therefore no copying occurred.");
            }
        }
        public void updateMesh()
        {
            if (!sliceMesh)
            {
                return;
            }

            if (slices < 1)
            {
                slices = 1;
            }

            if (skews == null || skews.Length < slices) //if they don't exist yet, just use temporary values
            {
                ULOffsets = new Vector2[slices];
                UROffsets = new Vector2[slices];
                LLOffsets = new Vector2[slices];
                LROffsets = new Vector2[slices];
                MOffsets  = new Vector2[slices];
                skews     = new Vector2[slices];
                bows      = new Vector4[slices];
                for (int s = 0; s < slices; s++)
                {
                    ULOffsets[s] = new Vector2(0f, 0f);
                    UROffsets[s] = new Vector2(0f, 0f);
                    LLOffsets[s] = new Vector2(0f, 0f);
                    LROffsets[s] = new Vector2(0f, 0f);
                    MOffsets[s]  = new Vector2(0f, 0f);
                    skews[s]     = new Vector2(0f, 0f);
                    bows[s]      = new Vector4(0f, 0f, 0f, 0f);
                }
            }

            if (canvasMaterials.Count == 0)
            {
                Debug.LogError("Canvas materials have not been set!  Please define what materials you want to apply to each slice in the hypercubeCanvas component.");
                return;
            }

            if (slices < 1)
            {
                slices = 1;
                return;
            }
            if (sliceHeight < 1)
            {
                sliceHeight = 1;
                return;
            }
            if (sliceWidth < 1)
            {
                sliceWidth = 1;
                return;
            }

            if (tesselation < 1)
            {
                tesselation = 1;
                return;
            }

            if (slices > canvasMaterials.Count)
            {
                Debug.LogWarning("Can't add more than " + canvasMaterials.Count + " slices, because only " + canvasMaterials.Count + " canvas materials are defined.");
                slices = canvasMaterials.Count;
                return;
            }

            List <Vector3> verts     = new List <Vector3>();
            List <Vector2> uvs       = new List <Vector2>();
            List <int[]>   submeshes = new List <int[]>(); //the triangle list(s)

            Material[] faceMaterials = new Material[slices];

            bool outFlipX = _flipX; //true values
            bool outFlipY = _flipY;
            bool outFlipZ = _flipZ;

            //modifiers
            if (flipX)
            {
                outFlipX = !outFlipX;
            }
            if (flipY)
            {
                outFlipY = !outFlipY;
            }
            if (flipZ)
            {
                outFlipZ = !outFlipZ;
            }


            //create the mesh
            float size          = 1f / (float)slices;
            int   vertCount     = 0;
            float pixelSliceGap = (1f / sliceHeight) * sliceGap * size;

            for (int s = 0; s < slices; s++)
            {
                float   yPos = ((float)s * size) + (s * pixelSliceGap);
                Vector2 topL = new Vector2(-1f + ULOffsets[s].x, yPos + size + ULOffsets[s].y);                                                                                                                          //top left
                Vector2 topM = new Vector2(MOffsets[s].x, yPos + size + Mathf.Lerp(ULOffsets[s].y, UROffsets[s].y, Mathf.InverseLerp(-1f + ULOffsets[s].x, 1f + UROffsets[s].x, MOffsets[s].x)));                        //top middle

                Vector2 topR = new Vector2(1f + UROffsets[s].x, yPos + size + UROffsets[s].y);                                                                                                                           //top right

                Vector2 midL   = new Vector2(-1f + Mathf.Lerp(ULOffsets[s].x, LLOffsets[s].x, Mathf.InverseLerp(size + ULOffsets[s].y, LLOffsets[s].y, (size / 2) + MOffsets[s].y)), yPos + (size / 2) + MOffsets[s].y); //middle left
                Vector2 middle = new Vector2(MOffsets[s].x, yPos + (size / 2) + MOffsets[s].y);                                                                                                                          //center
                Vector2 midR   = new Vector2(1f + Mathf.Lerp(UROffsets[s].x, LROffsets[s].x, Mathf.InverseLerp(size + UROffsets[s].y, LROffsets[s].y, (size / 2) + MOffsets[s].y)), yPos + (size / 2) + MOffsets[s].y);  //middle right

                Vector2 lowL = new Vector2(-1f + LLOffsets[s].x, yPos + LLOffsets[s].y);                                                                                                                                 //bottom left
                Vector2 lowM = new Vector2(MOffsets[s].x, yPos + Mathf.Lerp(LLOffsets[s].y, LROffsets[s].y, Mathf.InverseLerp(-1f + LLOffsets[s].x, 1f + LROffsets[s].x, MOffsets[s].x)));                               //bottom middle
                Vector2 lowR = new Vector2(1f + LROffsets[s].x, yPos + LROffsets[s].y);                                                                                                                                  //bottom right

                //skews
                topM.x += skews[s].x;
                lowM.x -= skews[s].x;
                midL.y += skews[s].y;
                midR.y -= skews[s].y;

                //interpolate the alternate axis on the skew so that edges will always be straight ( fix elbows caused when we skew)
                topM.y = Mathf.Lerp(topL.y, topR.y, Mathf.InverseLerp(topL.x, topR.x, topM.x));
                lowM.y = Mathf.Lerp(lowL.y, lowR.y, Mathf.InverseLerp(lowL.x, lowR.x, lowM.x));
                midL.x = Mathf.Lerp(topL.x, lowL.x, Mathf.InverseLerp(topL.y, lowL.y, midL.y));
                midR.x = Mathf.Lerp(topR.x, lowR.x, Mathf.InverseLerp(topR.y, lowR.y, midR.y));

                Vector2 UV_ul     = new Vector2(0f, 0f);
                Vector2 UV_mid    = new Vector2(.5f, .5f);
                Vector2 UV_br     = new Vector2(1f, 1f);
                Vector2 UV_left   = new Vector2(0f, .5f);
                Vector2 UV_bottom = new Vector2(.5f, 1f);
                Vector2 UV_top    = new Vector2(.5f, 0f);
                Vector2 UV_right  = new Vector2(1f, .5f);

                if (outFlipX && outFlipY)
                {
                    UV_ul.Set(1f, 0f);
                    UV_br.Set(0f, 1f);
                    UV_left.Set(1f, .5f);
                    UV_right.Set(0f, .5f);
                }
                else if (!outFlipX && !outFlipY)
                {
                    UV_ul.Set(0f, 1f);
                    UV_br.Set(1f, 0f);
                    UV_bottom.Set(.5f, 0f);
                    UV_top.Set(.5f, 1f);
                }
                else if (outFlipX && !outFlipY)
                {
                    UV_ul.Set(1f, 1f);
                    UV_br.Set(0f, 0f);
                    UV_bottom.Set(.5f, 0f);
                    UV_top.Set(.5f, 1f);
                    UV_left.Set(1f, .5f);
                    UV_right.Set(0f, .5f);
                }

                //we generate each slice mesh out of 4 interpolated parts.
                List <int> tris = new List <int>();

                vertCount += generateSliceShard(topL, topM, midL, middle, UV_ul, UV_mid, bows[s], shardOrientation.UL, vertCount, ref verts, ref tris, ref uvs);      //top left shard
                vertCount += generateSliceShard(topM, topR, middle, midR, UV_top, UV_right, bows[s], shardOrientation.UR, vertCount, ref verts, ref tris, ref uvs);   //top right shard
                vertCount += generateSliceShard(midL, middle, lowL, lowM, UV_left, UV_bottom, bows[s], shardOrientation.LL, vertCount, ref verts, ref tris, ref uvs); //bottom left shard
                vertCount += generateSliceShard(middle, midR, lowM, lowR, UV_mid, UV_br, bows[s], shardOrientation.LR, vertCount, ref verts, ref tris, ref uvs);      //bottom right shard

                submeshes.Add(tris.ToArray());

                //every face has a separate material/texture
                if (!outFlipZ)
                {
                    faceMaterials[s] = canvasMaterials[s];
                }
                else
                {
                    faceMaterials[s] = canvasMaterials[slices - s - 1];
                }
            }


            MeshRenderer r = sliceMesh.GetComponent <MeshRenderer>();

            if (!r)
            {
                r = sliceMesh.AddComponent <MeshRenderer>();
            }

            MeshFilter mf = sliceMesh.GetComponent <MeshFilter>();

            if (!mf)
            {
                mf = sliceMesh.AddComponent <MeshFilter>();
            }

            Mesh m = mf.sharedMesh;

            if (!m)
            {
                return; //probably some in-editor state where things aren't init.
            }
            m.Clear();

            m.SetVertices(verts);
            m.SetUVs(0, uvs);

            m.subMeshCount = slices;
            for (int s = 0; s < slices; s++)
            {
                m.SetTriangles(submeshes[s], s);
            }

            //normals are necessary for the transparency shader to work (since it uses it to calculate camera facing)
            Vector3[] normals = new Vector3[verts.Count];
            for (int n = 0; n < verts.Count; n++)
            {
                normals[n] = Vector3.forward;
            }

            m.normals = normals;

#if HYPERCUBE_DEV
            if (!calibrator)
            {
                calibrator = GetComponent <calibrator>();
            }

            if (calibrator && calibrator.gameObject.activeSelf && calibrator.enabled)
            {
                r.materials = calibrator.getMaterials();
            }
            else
#endif
            r.materials = faceMaterials;     //normal path

            m.RecalculateBounds();
        }