public Vector3 convertFromDataToPixelSpace(Vector3 dataCoord, bool doOffset = false) { Vector3 dataSpan = new Vector3(XLim[1] - XLim[0], YLim[1] - YLim[0], ZLim[1] - ZLim[0]); // right now, this setting of local scale doesn't account for any camera rotation //TODO: compensate localScale and change transform.rotation to match matlab's camera angle // for now, assume X axis and Y axis, combined with DataAspectRatio define relative scaling // (this assumption is almost certainly incorrect, but proceed anyways) var dataWidth = (XLim[1] - XLim[0]); //TODO: based on camera angle, form critical dimension from weighted combination of directions // for now, just use x axis // max size available is only constrained in X/Y (actually, based on camera angle) var USz = USize; if (USz[2] == 0) { USz[2] = Mathf.Infinity; } var axisSz = dataSpan; axisSz = Misc.InverseScale(axisSz, Misc.ArrayToVec3(DataAspectRatio)); var scale = Misc.VecMin(Misc.InverseScale(USz, axisSz)); axisSz = axisSz * scale; if (doOffset) { Vector3 origin = new Vector3(XLim[0], YLim[0], ZLim[0]); dataCoord = dataCoord - origin; } Vector3 pixelCoord = Vector3.Scale(Misc.InverseScale(dataCoord, dataSpan), axisSz); if (doOffset) { // add offset for axis to be centered inside figure USz = USize; pixelCoord = pixelCoord + USz / 2 - axisSz / 2; pixelCoord.Scale(new Vector3(1, 1, -1)); // correct for Unity's left-handed coordinate system } return(pixelCoord); }
public override void refresh() { base.refresh(); if (needsRefresh) { return; } if (mesh != null) { Destroy(mesh); } mesh = new Mesh(); var meshFilter = transform.gameObject.AddComponent <MeshFilter>(); meshFilter.mesh = mesh; var meshRenderer = transform.gameObject.AddComponent <MeshRenderer>(); if (FaceVertexCData != null) { meshRenderer.material = defaultVertexColorMaterial; } else { meshRenderer.material = defaultMaterial; } if (FaceColor.array != null) { meshRenderer.material.color = Misc.ArrayToColor(FaceColor.array); } if (EdgeColor.str != null) { if (EdgeColor.str != "none") { Debug.LogErrorFormat("Unsupported EdgeColor {0}", EdgeColor.str); } // else do nothing } else { Debug.Assert(EdgeColor.array != null & EdgeColor.array.Length == 3); // add second material as wireframe to show both underlying color and mesh edges var wireframeMaterial = defaultWireframeMaterial; wireframeMaterial.color = Misc.ArrayToColor(EdgeColor.array); meshRenderer.materials = new Material[] { meshRenderer.material, defaultWireframeMaterial }; } //TODO: add second wireframe material if edge color is not none // convert coordinate systems and from float[3] to Vector3 var convertedVertices = new Vector3[Vertices.Length]; for (int i = 0; i < Vertices.Length; i++) { convertedVertices[i] = convertSizeToPixels(Misc.ArrayToVec3(Vertices[i]), MUnits.data, true); } mesh.vertices = convertedVertices; // convert from (numFaces by numTriangles) to (numFaces*numTriangles vector) as expected by Unity var numVerticesPerFace = Faces[0].Length; Debug.Assert(numVerticesPerFace == 3); // quadilaterials and other size face elements not currently supported var convertedFaces = new int[Faces.Length * numVerticesPerFace]; //Debug.LogFormat("Size of faces: {0},{1}", Faces.Length, Faces[0].Length); for (int i = 0; i < Faces.Length; i++) { Debug.Assert(Faces[i].Length == numVerticesPerFace); for (int j = 0; j < numVerticesPerFace; j++) { convertedFaces[numVerticesPerFace * i + j] = Faces[i][j] - 1; // subtract 1 to convert to zero-based indexing } } //Debug.LogFormat("Max index: {0}", Mathf.Max(convertedFaces)); //Debug.LogFormat("Size of Vertices: {0},{1}", Vertices.Length, Vertices[0].Length); MeshTopology meshTopol = MeshTopology.Triangles; if (numVerticesPerFace == 3) { meshTopol = MeshTopology.Triangles; } //else if (numVerticesPerFace == 4) // meshTopol = MeshTopology.Quads; else { Debug.LogErrorFormat("Unsupported number of vertices per face: {0}", meshTopol); } mesh.SetIndices(convertedFaces, meshTopol, 0); //mesh.triangles = convertedFaces; if (FaceVertexCData != null) { // convert scalar maps into colormap into RGB colors if (FaceVertexCData.Length > 0 && (FaceVertexCData[0].Length == 1)) { // assume if one element needs to be converted, all do FaceVertexCData = mapIntoColormap((float [][])FaceVertexCData); } var colors = new List <Color>(); if (FaceVertexCData.Length == 1) { // replicate single color Debug.Assert(FaceVertexCData[0].Length == 3); for (int i = 0; i < Vertices.Length; i++) { colors.Add(Misc.ArrayToColor(FaceVertexCData[0])); } } else { Debug.Assert(FaceVertexCData.Length == Vertices.Length); // for now, only support coloring by vertex (not face) //TODO: add support for coloring by face if FaceVertexCData.Length == numFaces for (int i = 0; i < Vertices.Length; i++) { colors.Add(Misc.ArrayToColor(FaceVertexCData[i])); } } mesh.SetColors(colors); } // duplicate faces and flip normals Misc.MakeMeshDoubleSided(ref mesh); }