[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(); }