public static void GenerateRoadGeometryFromLine(this Mesh mesh, Scene scene, Vector3 lineStart, Vector3 lineEnd, float width = 1f, float height = 1f, string materialName = "pb_road", string edgeMaterialName = "pb_roadedge") { if (lineStart.X != lineEnd.X) { throw new ArgumentException("Vectors do not represent a 2D line!"); } // //float cubeLength = (lineEnd - lineStart).Length(); Vector3 forwardDir = Vector3.Normalize(lineEnd - lineStart); Vector3 rightDir = Vector3.UnitX; Vector3 upDir = -Vector3.Cross(forwardDir, rightDir); Vector3 rightDirH = rightDir / 2f; Vector3 upDirH = upDir / 2f; //generate cube points var cubeS_BLL = lineStart + (-rightDirH * width) + (-upDirH * height); var cubeS_BRR = lineStart + (rightDirH * width) + (-upDirH * height); var cubeS_TLL = lineStart + (-rightDirH * width) + (upDirH * height); var cubeS_TRR = lineStart + (rightDirH * width) + (upDirH * height); var cubeS_BL = Vector3.Lerp(cubeS_BLL, cubeS_BRR, 0.1f); var cubeS_BR = Vector3.Lerp(cubeS_BRR, cubeS_BLL, 0.1f); var cubeS_TL = Vector3.Lerp(cubeS_TLL, cubeS_TRR, 0.1f); var cubeS_TR = Vector3.Lerp(cubeS_TRR, cubeS_TLL, 0.1f); var cubeE_BLL = lineEnd + (-rightDirH * width) + (-upDirH * height); var cubeE_BRR = lineEnd + (rightDirH * width) + (-upDirH * height); var cubeE_TLL = lineEnd + (-rightDirH * width) + (upDirH * height); var cubeE_TRR = lineEnd + (rightDirH * width) + (upDirH * height); var cubeE_BL = Vector3.Lerp(cubeE_BLL, cubeE_BRR, 0.1f); var cubeE_BR = Vector3.Lerp(cubeE_BRR, cubeE_BLL, 0.1f); var cubeE_TL = Vector3.Lerp(cubeE_TLL, cubeE_TRR, 0.1f); var cubeE_TR = Vector3.Lerp(cubeE_TRR, cubeE_TLL, 0.1f); int vertexBase = mesh.Vertices.Count; mesh.Vertices.Add(cubeS_BLL); mesh.Vertices.Add(cubeS_BL); mesh.Vertices.Add(cubeS_BR); mesh.Vertices.Add(cubeS_BRR); mesh.Vertices.Add(cubeS_TRR); mesh.Vertices.Add(cubeS_TR); mesh.Vertices.Add(cubeS_TL); mesh.Vertices.Add(cubeS_TLL); mesh.Vertices.Add(cubeE_BLL); mesh.Vertices.Add(cubeE_BL); mesh.Vertices.Add(cubeE_BR); mesh.Vertices.Add(cubeE_BRR); mesh.Vertices.Add(cubeE_TRR); mesh.Vertices.Add(cubeE_TR); mesh.Vertices.Add(cubeE_TL); mesh.Vertices.Add(cubeE_TLL); //find applicable submeshes Submesh edgeSubmesh = mesh.GetOrCreateSubmesh(edgeMaterialName, scene); Submesh roadSubmesh = mesh.GetOrCreateSubmesh(materialName, scene); //left edgeSubmesh.AddLoop(vertexBase); edgeSubmesh.AddLoop(vertexBase + 7); edgeSubmesh.AddLoop(vertexBase + 15); edgeSubmesh.AddLoop(vertexBase + 8); edgeSubmesh.AddLoop(vertexBase); edgeSubmesh.AddLoop(vertexBase + 15); //top 0 edgeSubmesh.AddLoop(vertexBase + 7); edgeSubmesh.AddLoop(vertexBase + 6); edgeSubmesh.AddLoop(vertexBase + 14); edgeSubmesh.AddLoop(vertexBase + 15); edgeSubmesh.AddLoop(vertexBase + 7); edgeSubmesh.AddLoop(vertexBase + 14); //top 1 roadSubmesh.AddLoop(vertexBase + 6); roadSubmesh.AddLoop(vertexBase + 5); roadSubmesh.AddLoop(vertexBase + 13); roadSubmesh.AddLoop(vertexBase + 6); roadSubmesh.AddLoop(vertexBase + 13); roadSubmesh.AddLoop(vertexBase + 14); //top 2 edgeSubmesh.AddLoop(vertexBase + 5); edgeSubmesh.AddLoop(vertexBase + 4); edgeSubmesh.AddLoop(vertexBase + 12); edgeSubmesh.AddLoop(vertexBase + 13); edgeSubmesh.AddLoop(vertexBase + 5); edgeSubmesh.AddLoop(vertexBase + 12); //right edgeSubmesh.AddLoop(vertexBase + 3); edgeSubmesh.AddLoop(vertexBase + 11); edgeSubmesh.AddLoop(vertexBase + 12); edgeSubmesh.AddLoop(vertexBase + 3); edgeSubmesh.AddLoop(vertexBase + 12); edgeSubmesh.AddLoop(vertexBase + 4); //bottom 0 edgeSubmesh.AddLoop(vertexBase + 0); edgeSubmesh.AddLoop(vertexBase + 8); edgeSubmesh.AddLoop(vertexBase + 9); edgeSubmesh.AddLoop(vertexBase + 9); edgeSubmesh.AddLoop(vertexBase + 1); edgeSubmesh.AddLoop(vertexBase + 0); //bottom 1 roadSubmesh.AddLoop(vertexBase + 1); roadSubmesh.AddLoop(vertexBase + 9); roadSubmesh.AddLoop(vertexBase + 10); roadSubmesh.AddLoop(vertexBase + 10); roadSubmesh.AddLoop(vertexBase + 2); roadSubmesh.AddLoop(vertexBase + 1); //bottom 2 edgeSubmesh.AddLoop(vertexBase + 2); edgeSubmesh.AddLoop(vertexBase + 10); edgeSubmesh.AddLoop(vertexBase + 11); edgeSubmesh.AddLoop(vertexBase + 11); edgeSubmesh.AddLoop(vertexBase + 3); edgeSubmesh.AddLoop(vertexBase + 2); }
public static void GenerateCubeGeometryFromLine(this Mesh mesh, Scene scene, Vector3 lineStart, Vector3 lineEnd, float size = 1f, string materialName = "pb_wood") { if (lineStart.X != lineEnd.X) { throw new ArgumentException("Vectors do not represent a 2D line!"); } // //float cubeLength = (lineEnd - lineStart).Length(); Vector3 forwardDir = Vector3.Normalize(lineEnd - lineStart); Vector3 rightDir = Vector3.UnitX; Vector3 upDir = -Vector3.Cross(forwardDir, rightDir); Vector3 rightDirH = rightDir / 2f; Vector3 upDirH = upDir / 2f; //generate cube points var cubeS_BL = lineStart + (-rightDirH * size) + (-upDirH * size); var cubeS_BR = lineStart + (rightDirH * size) + (-upDirH * size); var cubeS_TL = lineStart + (-rightDirH * size) + (upDirH * size); var cubeS_TR = lineStart + (rightDirH * size) + (upDirH * size); var cubeE_BL = lineEnd + (-rightDirH * size) + (-upDirH * size); var cubeE_BR = lineEnd + (rightDirH * size) + (-upDirH * size); var cubeE_TL = lineEnd + (-rightDirH * size) + (upDirH * size); var cubeE_TR = lineEnd + (rightDirH * size) + (upDirH * size); int vertexBase = mesh.Vertices.Count; mesh.Vertices.Add(cubeS_BL); mesh.Vertices.Add(cubeS_BR); mesh.Vertices.Add(cubeS_TR); mesh.Vertices.Add(cubeS_TL); mesh.Vertices.Add(cubeE_BL); mesh.Vertices.Add(cubeE_BR); mesh.Vertices.Add(cubeE_TR); mesh.Vertices.Add(cubeE_TL); //find applicable submeshes Submesh submesh = mesh.GetOrCreateSubmesh(materialName, scene); //left submesh.AddLoop(vertexBase); submesh.AddLoop(vertexBase + 3); submesh.AddLoop(vertexBase + 7); submesh.AddLoop(vertexBase + 4); submesh.AddLoop(vertexBase); submesh.AddLoop(vertexBase + 7); //top submesh.AddLoop(vertexBase + 3); submesh.AddLoop(vertexBase + 2); submesh.AddLoop(vertexBase + 6); submesh.AddLoop(vertexBase + 7); submesh.AddLoop(vertexBase + 3); submesh.AddLoop(vertexBase + 6); //bottom submesh.AddLoop(vertexBase + 0); submesh.AddLoop(vertexBase + 4); submesh.AddLoop(vertexBase + 5); submesh.AddLoop(vertexBase + 5); submesh.AddLoop(vertexBase + 1); submesh.AddLoop(vertexBase + 0); //right submesh.AddLoop(vertexBase + 1); submesh.AddLoop(vertexBase + 5); submesh.AddLoop(vertexBase + 6); submesh.AddLoop(vertexBase + 1); submesh.AddLoop(vertexBase + 6); submesh.AddLoop(vertexBase + 2); }