private void addLine(Vector3 start, Vector3 end) { addLine(start.ToArray(), color, end.ToArray(), color); }
/// <summary> /// Helper method that creates a Unity Mesh from the given attribute arrays. /// </summary> protected static Mesh[] CreateMesh(string name, int[] triangles, Vector3[] vertices, Vector3[] normals, Vector4[] tangents, Vector2[][] uv, Color[] colors, int vertexLimit) { if (triangles != null && triangles.Length < 3 || vertices == null || vertices.Length < 3) return new Mesh[] { }; if (triangles == null) triangles = Enumerable.Range(0, vertices.Length).ToArray(); //Debug.Log("Building Meshes for attribute arrays of " + vertices.Length + " vertices and " + triangles.Length/3 + " faces."); // The input will be split up into chunks, each with at most vertexLimit / 3 faces. vertexLimit -= vertexLimit % 3; //Make sure it's divisible by 3. var meshCount = (triangles.Length - 1) / vertexLimit + 1; var result = new Mesh[meshCount]; var indexTable = new Dictionary<int, int>(); var indexTableInv = new Dictionary<int, int>(); for (int i = 0; i < result.Length; ++i) { result[i] = new Mesh(); result[i].name = (result.Length == 1) ? name : name + i; // Re-index triangles to the minimum subset of vertices needed by this submesh. var trianglesChunk = triangles.Skip(i * vertexLimit).Take(vertexLimit).ToArray(); var subTriangles = new int[trianglesChunk.Length]; for (int j = 0; j < trianglesChunk.Length; ++j) { int index = trianglesChunk[j]; if (!indexTable.ContainsKey(index)) { int subIndex = indexTableInv.Count; indexTable[index] = subIndex; indexTableInv[subIndex] = index; } subTriangles[j] = indexTable[index]; } var subVertexCount = indexTable.Count; var subVertices = new Vector3[subVertexCount]; for (int j = 0; j < subVertexCount; ++j) subVertices[j] = vertices[indexTableInv[j]]; result[i].vertices = subVertices.ToArray(); if (normals != null) { var subNormals = new Vector3[subVertexCount]; for (int j = 0; j < subVertexCount; ++j) subNormals[j] = normals[indexTableInv[j]]; result[i].normals = subNormals; } if (tangents != null) { var subTangents = new Vector4[subVertexCount]; for (int j = 0; j < subVertexCount; ++j) subTangents[j] = tangents[indexTableInv[j]]; result[i].tangents = subTangents; } if (uv.Length > 0 && uv[0] != null) { var subUv = new Vector2[subVertexCount]; for (int j = 0; j < subVertexCount; ++j) subUv[j] = uv[0][indexTableInv[j]]; result[i].uv = subUv; } if (uv.Length > 1 && uv[1] != null) { var subUv1 = new Vector2[subVertexCount]; for (int j = 0; j < subVertexCount; ++j) subUv1[j] = uv[1][indexTableInv[j]]; result[i].uv1 = subUv1; } if (colors != null) { var subColors = new Color[subVertexCount]; for (int j = 0; j < subVertexCount; ++j) subColors[j] = colors[indexTableInv[j]]; result[i].colors = subColors; } result[i].triangles = subTriangles; indexTableInv.Clear(); indexTable.Clear(); } return result; }
private IEnumerator LoadMeshes() { Debug.Log("LoadMeshes"); foreach (var way in map.ways) { Debug.Log("LoadWay"); var cpolyShape = new CPolygonShape(way.points.ToArray()); cpolyShape.CutEar(); var count = cpolyShape.NumberOfPolygons * 3; Vector3[] vertices = new Vector3[count]; int[] triangles = new int[count]; int ji = 0; for (int i = 0; i < cpolyShape.NumberOfPolygons; i++) { var p = cpolyShape.Polygons(i); for (int j = 0; j < p.Length; j++) { triangles[ji] = ji; ; vertices[ji] = new Vector3(0, (float)p[j].Y, (float)p[j].X); ji++; } } var g = new GameObject(); var f = g.AddComponent<MeshFilter>(); var info = g.AddComponent<Info>(); info.tags = way.tags; var mesh = f.mesh = new Mesh(); mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals(); mesh.RecalculateBounds(); var r = g.AddComponent<MeshRenderer>(); r.material = mat; g.AddComponent<BoxCollider>(); yield return null; } yield return null; }
public static Level loadLevel(string fileName,ContentManager Content) { Level level = new Level(); level.levelName = fileName.Split("\\".ToCharArray()).Last(); //read in the level layout FileStream file = new FileStream(fileName + ".level", FileMode.OpenOrCreate, FileAccess.Read); StreamReader fileIn = new StreamReader(file); Vector2 endpos = Vector2.Zero; level.levelW = int.Parse(fileIn.ReadLine()); level.levelH = int.Parse(fileIn.ReadLine()); level.layout = new Tile[level.levelW, level.levelH]; for (int y = 0; y < level.levelH; y++) { String line = fileIn.ReadLine(); String[] buffer = line.Split(new char[] { ' ' }); for (int x = 0; x < level.levelW; x++) { level.layout[x, y] = new Tile(int.Parse(buffer[x])); Vector2 position = new Vector2(); position.X = x * Level.tileWidth + Level.tileWidth / 2; position.Y = y * Level.tileHeight + Level.tileHeight / 2; level.layout[x, y].position = position; level.layout[x, y].setWidth(Level.tileWidth); level.layout[x, y].setHeight(Level.tileHeight); level.layout[x, y].updateBound(); } } fileIn.Close(); file.Close(); //read the associated XML file XmlTextReader xml = new XmlTextReader(fileName + ".xml"); while (xml.Read()) { if (xml.Name == "level" && xml.HasAttributes) { int x = int.Parse(xml.GetAttribute("endX")); int y = int.Parse(xml.GetAttribute("endY")); level.layout[x, y].assignBooleans(6); int px = int.Parse(xml.GetAttribute("startX")); int py = int.Parse(xml.GetAttribute("startY")); level.player.position = new Vector2(px * Level.tileWidth + Level.tileWidth / 2, py * Level.tileHeight); } //if the node is a tag if (xml.NodeType == XmlNodeType.Element) { //if the tag is a button if (xml.Name == "button") { Dictionary<string, string> enemyFields = new Dictionary<string, string>(); Dictionary<string, string> buttonFields = new Dictionary<string, string>(); LinkedList<string> messages = new LinkedList<string>(); int buttonX = int.Parse(xml.GetAttribute("x")); int buttonY = int.Parse(xml.GetAttribute("y")); int numUses = int.Parse(xml.GetAttribute("uses")); string[] useActions = new string[numUses]; Vector3[][] targets = new Vector3[numUses][]; xml.MoveToAttribute(0); for (int i = 0; i < xml.AttributeCount; i++) { buttonFields.Add(xml.Name, xml.Value); xml.MoveToNextAttribute(); } //while we haven't gotten to the end of the button xml.Read(); while (xml.Name != "button") { if (xml.NodeType == XmlNodeType.Element && xml.Name.StartsWith("use")) { LinkedList<Vector3> useTargets = new LinkedList<Vector3>(); int number = int.Parse(xml.Name.Substring(3)); string variety = xml.GetAttribute("type"); useActions[number] = variety; xml.Read(); while (!xml.Name.StartsWith("use")) { //read in nodes, which are all targets //each target has a point corresponding to a tile in the layout and a type to change that tile to if (xml.NodeType == XmlNodeType.Element && xml.Name == "target") { int x = int.Parse(xml.GetAttribute("x")); int y = int.Parse(xml.GetAttribute("y")); int type = int.Parse(xml.GetAttribute("type")); useTargets.AddLast(new Vector3(x, y, type)); level.layout[x, y].isChangedbyButton = true; } else if (xml.NodeType == XmlNodeType.Element && xml.Name == "enemy") { xml.MoveToAttribute(0); for (int i = 0; i < xml.AttributeCount; i++) { enemyFields.Add(xml.Name, xml.Value); xml.MoveToNextAttribute(); } } else if (xml.NodeType == XmlNodeType.Element && xml.Name == "display") { messages.AddLast(xml.GetAttribute("message")); } xml.Read(); } targets[number] = useTargets.ToArray(); } xml.Read(); } Button b = new Button(); b.useActions = useActions; b.enemyParams = enemyFields; b.messages = messages; b.tiles = targets.ToArray(); foreach (KeyValuePair<string, string> entry in buttonFields) { if (entry.Key == "uses") { b.totalUses = int.Parse(entry.Value); b.isMultipleUse = (b.totalUses > 1); } else if (entry.Key == "cycles") { b.cycles = Boolean.Parse(entry.Value); } else if (entry.Key == "sensor") { b.isMotionSensor = Boolean.Parse(entry.Value); } } if (b.isMotionSensor) { b.assignBooleans(7); } level.layout[buttonX, buttonY] = b; Vector2 position = new Vector2(); position.X = buttonX * Level.tileWidth + Level.tileWidth/2; position.Y = buttonY * Level.tileHeight+Level.tileHeight/2; level.layout[buttonX, buttonY].position = position; level.layout[buttonX, buttonY].setWidth(Level.tileWidth); level.layout[buttonX, buttonY].setHeight(Level.tileHeight); level.layout[buttonX, buttonY].origin = new Vector2(Level.tileWidth, Level.tileHeight) * .05f; level.layout[buttonX, buttonY].updateBound(); } //the player xml name sets player initial position else if (xml.Name == "player") { int playerX = int.Parse(xml.GetAttribute("x")); int playerY = int.Parse(xml.GetAttribute("y")); level.player.position = new Vector2(playerX * Level.tileWidth, playerY * Level.tileHeight); } //enemy expects an initial position else if (xml.Name == "enemy") { Dictionary<string,string> fields = new Dictionary<string,string>(); xml.MoveToAttribute(0); for (int i = 0; i < xml.AttributeCount; i++) { fields.Add(xml.Name,xml.Value); xml.MoveToNextAttribute(); } level.enemies.AddLast(FileIOManager.createEnemyWithParams(fields)); } } } xml.Close(); return level; }
public void CreateMesh2(List<Vector3> vertices, List<Vector2> uvs, List<Vector3> normals) { double t0 = EditorApplication.timeSinceStartup; //Debug.Log ("Face Count: " + faces.Count ()); if (faces.Count () <= 0) return; List<int> mVerticesID = new List<int> (); List<int> mTriangles = new List<int> (); //populate mVerticesID containing all vertices used in all faces of mesh foreach (List<int> face in faces) { mVerticesID.AddRange(face); } //make it unique int[] mVerticesIDArr = mVerticesID.Distinct ().ToArray (); int[] vertLookup = new int[vertices.Count]; for (int i=0; i<vertLookup.Length; i++) { vertLookup[i] = -1; //init values to -1 } for (int i = 0; i < mVerticesIDArr.Length; i++) { vertLookup[mVerticesIDArr[i]] = i; } Vector3[] mVertices = new Vector3[mVerticesIDArr.Length]; Vector2[] mUVs = new Vector2[mVerticesIDArr.Length]; Vector3[] mNormals = new Vector3[mVerticesIDArr.Length]; //populate data array for (int i = 0; i < mVerticesIDArr.Length; i++) { mVertices[i]= vertices[mVerticesIDArr[i]]; mUVs[i] = uvs[mVerticesIDArr[i]]; mNormals[i] = normals[mVerticesIDArr[i]]; } Debug.Log ("Preparing vert data took: " + (t0 - EditorApplication.timeSinceStartup)); t0 = EditorApplication.timeSinceStartup; double tVertLookup = 0; double tFaceCreation = 0; double tf; //generate face and vertices data foreach (List<int> face in faces) { tf = EditorApplication.timeSinceStartup; List<int> newFace = new List<int> (); foreach (int vertID in face){ int newID = vertLookup[vertID];//Array.IndexOf(mVerticesIDArr, vertID); //mVerticesIDArr.Contains(vertID); if (newID >= 0){ newFace.Add(newID); } } tVertLookup += EditorApplication.timeSinceStartup - tf; tf = EditorApplication.timeSinceStartup; newFace.Reverse(); if (newFace.Count() == 3) { mTriangles.AddRange(newFace); } else { //implement face triangulation algorithm Debug.Log ("Non-triangle face"); } tFaceCreation += EditorApplication.timeSinceStartup - tf; } Debug.Log ("Computing face verts took: " + (t0 - EditorApplication.timeSinceStartup)); Debug.Log (" vertex lookup: " + tVertLookup); Debug.Log (" face data creation: " + tFaceCreation); t0 = EditorApplication.timeSinceStartup; //Generate mesh object Mesh mesh = new Mesh (); mesh.vertices = mVertices.ToArray (); mesh.uv = mUVs.ToArray (); mesh.normals = mNormals.ToArray (); mesh.triangles = mTriangles.ToArray (); //add meshrenderer / meshfilters to parent and apply mesh MeshRenderer mr = parent.AddComponent<MeshRenderer> (); mr.sharedMaterial = new Material (Shader.Find ("Standard")); MeshFilter mf = parent.AddComponent<MeshFilter> (); mf.sharedMesh = mesh; }
/// <summary> /// Generates the actual mesh for the polyhedron /// </summary> private void MakeMesh() { MeshFilter mf; mf = Shape.GetComponent <MeshFilter>(); if (mf == null) { mf = Shape.AddComponent <MeshFilter>(); } mf.mesh = null; Mesh mesh = new Mesh(); TriangulatedPolygonGenerator tpg = new TriangulatedPolygonGenerator(); Frame3f frame = new Frame3f(); tpg.Polygon = Polygon.ToPolygon(ref frame); tpg.Generate(); int nv = tpg.vertices.Count; VertexTable.Clear(); foreach (Dataline ring in Polygon) { foreach (VertexLookup v in ring.VertexTable) { VertexTable.Add(v); } } IEnumerable <Vector3d> vlist = tpg.vertices.AsVector3d(); Vector3[] vertices = new Vector3[vlist.Count()]; for (int i = 0; i < vlist.Count(); i++) { Vector3d v = vlist.ElementAt(i); try { VertexLookup vl = VertexTable.Find(item => v.xy.Distance(frame.ToPlaneUV(item.Com.transform.position, 3)) < 0.001); vertices[i] = Shape.transform.InverseTransformPoint(vl.Com.transform.position); vl.pVertex = i; } catch { VertexTable.Add(new VertexLookup() { pVertex = i, Com = VertexTable[0].Com }); vertices[i] = Shape.transform.InverseTransformPoint((Vector3)frame.FromFrameV(v)); } } List <Vector2> uvs = new List <Vector2>(); IEnumerable <Vector2d> uv2d = tpg.uv.AsVector2f(); foreach (Vector2d uv in uv2d) { uvs.Add((Vector2)uv); } mesh.vertices = vertices.ToArray(); mesh.triangles = tpg.triangles.ToArray <int>(); mesh.uv = uvs.ToArray <Vector2>(); mesh.RecalculateBounds(); mesh.RecalculateNormals(); mf.mesh = mesh; }