Example #1
0
    private void RenderSegments()
    {
        Vertex[] vertices =
        {
            new Vertex(new Vector3(-.0125f, -.0025f, 0), Vector3.down,  0),
            new Vertex(new Vector3(.0125f,  -.0025f, 0), Vector3.down,  1),
            new Vertex(new Vector3(.0125f,  -.0025f, 0), Vector3.right, 1),
            new Vertex(new Vector3(.0125f,   .0025f, 0), Vector3.right, 1),
            new Vertex(new Vector3(.0125f,   .0025f, 0), Vector3.up,    1),
            new Vertex(new Vector3(-.0125f,  .0025f, 0), Vector3.up,    0),
            new Vertex(new Vector3(-.0125f,  .0025f, 0), Vector3.left,  0),
            new Vertex(new Vector3(-.0125f, -.0025f, 0), Vector3.left, 0)
        };
        int[] lines = new int[] {
            0, 1,
            2, 3,
            4, 5,
            6, 7
        };
        ExtrudeShape shape = new ExtrudeShape(vertices, lines);

        for (int i = 0; i < segments.Count; i++)
        {
            RenderSegment(segments[i], shape, paths[i]);
        }
    }
    public void GenerateMesh(ExtrudeShape shape, float detail)
    {
        List <OrientationPoint> path = new List <OrientationPoint>();
        int refPointCount            = Mathf.FloorToInt(ControlPointCount * detail);

        for (int i = 0; i < refPointCount; i++)
        {
            float      t = (float)i / refPointCount;
            Vector3    generatePointRef = GetPoint(t);
            Quaternion rotation         = Quaternion.LookRotation(GetDirection(t), Vector3.up);

            path.Add(new OrientationPoint(generatePointRef, rotation));

            if (i == 1)
            {
                path.Add(new OrientationPoint(generatePointRef, rotation));
            }
        }

        if (Loop)
        {
            path.Add(path[0]);
        }

        GetComponent <MeshFilter>().sharedMesh = TrackGenerator.Extrude(shape, path.ToArray());
    }
Example #3
0
    public void Load()
    {
        if (File.Exists(Application.dataPath + "/ProceduralTracks/CurvesSavedData/" + gameObject.name + ".curve"))
        {
            ClearCurve();

            BinaryFormatter bf   = new BinaryFormatter();
            FileStream      file = File.Open(Application.dataPath + "/ProceduralTracks/CurvesSavedData/" + gameObject.name + ".curve", FileMode.Open);
            BifurcationData data = (BifurcationData)bf.Deserialize(file);
            file.Close();

            if (extrudeShape == null)
            {
                extrudeShape = new ExtrudeShape();
            }

            for (int i = 0; i < data.nodesData.Length; ++i)
            {
                // Create Nodes
                Node node = CreateNode(transform.position, transform.rotation);
                node.Load(data.nodesData[i]);
            }

            planeX = data.planeX;

            // Create Splines
            CreateSpline(nodes[0], nodes[1]).ExtrudeSide(meshes[0], extrudeShape, "right", planeX);
            CreateSpline(nodes[0], nodes[2]).ExtrudeSide(meshes[1], extrudeShape, "left", planeX);
        }
        else
        {
            //Debug.Assert(true, "Data file not found");
            Create();
        }
    }
    public static void Extrude(Mesh mesh, ExtrudeShape shape, OrientedPoint[] path)
    {
        int vertsInShape  = shape.verts.Length;
        int segments      = path.Length - 1;
        int edgeLoops     = path.Length;
        int vertCount     = vertsInShape * edgeLoops;
        int triCount      = shape.Lines.Length * segments * 2;
        int triIndexCount = triCount * 3;

        int[]     triangleIndices = new int[triIndexCount];
        Vector3[] vertices        = new Vector3[vertCount];
        Vector3[] normals         = new Vector3[vertCount];
        Vector2[] uvs             = new Vector2[vertCount];

        // Generate all of the vertices and normals
        for (int i = 0; i < path.Length; i++)
        {
            int offset = i * vertsInShape;
            for (int j = 0; j < vertsInShape; j++)
            {
                int     id   = offset + j;
                Vector3 vert = path[i].LocalToWorld(shape.verts[j]);
                if (shape.verts[j].y == -10)
                {
                    vert.y = -2000;
                }
                vertices[id] = vert;
                normals[id]  = path[i].LocalToWorldDirection(shape.normals[j]);
                uvs[id]      = new Vector2(shape.uCoords[j], path[i].vCoordinate);
            }
        }

        // Generate all of the triangles
        int ti = 0;

        for (int i = 0; i < segments; i++)
        {
            int offset = i * vertsInShape;
            for (int l = 0; l < shape.Lines.Length; l += 2)
            {
                int a = offset + shape.Lines[l];
                int b = offset + shape.Lines[l] + vertsInShape;
                int c = offset + shape.Lines[l + 1] + vertsInShape;
                int d = offset + shape.Lines[l + 1];
                triangleIndices[ti++] = a;
                triangleIndices[ti++] = b;
                triangleIndices[ti++] = c;
                triangleIndices[ti++] = c;
                triangleIndices[ti++] = d;
                triangleIndices[ti++] = a;
            }
        }

        mesh.Clear();
        mesh.vertices  = vertices;
        mesh.normals   = normals;
        mesh.uv        = uvs;
        mesh.triangles = triangleIndices;
    }
Example #5
0
 public Mesh UpdateMesh(List <Vector2> points)
 {
     this.points = points;
     this.mesh   = ExtrudeShape.Generate(this.points, this.depth);
     this.volume = MeshVolume.Calculate(mesh);
     this.mass   = (defaultMass + this.volume * 100.0f);
     return(this.mesh);
 }
Example #6
0
    private void RenderSegment(GameObject segment, ExtrudeShape shape, OrientedPoint[] path)
    {
        // TODO: use the shape from the previous segment to make segments continuous
        // TODO: use sampling to fix texture stretching
        MeshFilter mf   = segment.GetComponent <MeshFilter>();
        Mesh       mesh = mf.mesh;

        Extrude(mesh, shape, path);
    }
Example #7
0
    Mesh Extrude(ExtrudeShape shape, OrientedPoint[] path)
    {
        Mesh mesh          = new Mesh();
        int  vertsInShape  = shape.vertxs.GetLength(0);
        int  segments      = path.GetLength(0) - 1;
        int  edgeLoops     = path.GetLength(0);
        int  vertCount     = vertsInShape * edgeLoops;
        int  triCount      = shape.lines.GetLength(0) * segments;
        int  triIndexCount = triCount * 3;

        int[]     triangleIndices = new int[triIndexCount];
        Vector3[] vertices        = new Vector3[vertCount];
        Vector3[] normals         = new Vector3[vertCount];
        Vector2[] uvs             = new Vector2[vertCount];

        // Generate all of the vertices and normals
        for (int i = 0; i < path.Length; i++)
        {
            int offset = i * vertsInShape;
            for (int j = 0; j < vertsInShape; j++)
            {
                int id = offset + j;
                vertices[id] = path[i].LocalToWorld(shape.vertxs[j]);
                normals[id]  = path[i].LocalToWorldDirection(shape.normals[j]);
                uvs[id]      = new Vector2(shape.uCoords[j], i / ((float)edgeLoops));
            }
        }

        // Generate all of the triangles
        int ti = 0;

        for (int i = 0; i < segments; i++)
        {
            int offset = i * vertsInShape;
            for (int l = 0; l < shape.lines.GetLength(0); l += 2)
            {
                int a = offset + shape.lines[l] + vertsInShape;
                int b = offset + shape.lines[l];
                int c = offset + shape.lines[l + 1];
                int d = offset + shape.lines[l + 1] + vertsInShape;
                triangleIndices[ti] = a; ti++;
                triangleIndices[ti] = b; ti++;
                triangleIndices[ti] = c; ti++;
                triangleIndices[ti] = c; ti++;
                triangleIndices[ti] = d; ti++;
                triangleIndices[ti] = a; ti++;
            }
        }

        mesh.Clear();
        mesh.vertices  = vertices;
        mesh.normals   = normals;
        mesh.uv        = uvs;
        mesh.triangles = triangleIndices;

        return(mesh);
    }
Example #8
0
 public void Extrude()
 {
     if (extrudeShape == null)
     {
         extrudeShape = new ExtrudeShape();
     }
     splines[0].ExtrudeSide(meshes[0], extrudeShape, "right", planeX);
     splines[1].ExtrudeSide(meshes[1], extrudeShape, "left", planeX);
 }
Example #9
0
    public void Extrude()
    {
        if (extrudeShape == null)
        {
            extrudeShape = new ExtrudeShape();
        }

        for (int i = 0; i < splines.Count; ++i)
        {
            splines[i].Extrude(meshes[i], extrudeShape);
        }
    }
Example #10
0
    private void Extrude(Mesh mesh, ExtrudeShape shape, OrientedPoint[] path)
    {
        int vertsInShape  = shape.vert2Ds.Length;
        int segments      = path.Length - 1;
        int edgeLoops     = path.Length;
        int vertCount     = vertsInShape * edgeLoops;
        int triCount      = shape.lines.Length * segments;
        int triIndexCount = triCount * 3;

        int[]     triangleIndices = new int[triIndexCount];
        Vector3[] vertices        = new Vector3[vertCount];
        Vector3[] normals         = new Vector3[vertCount];
        Vector2[] uvs             = new Vector2[vertCount];

        for (int i = 0; i < path.Length; i++)
        {
            int offset = i * vertsInShape;
            for (int j = 0; j < vertsInShape; j++)
            {
                int id = offset + j;
                vertices[id] = path[i].LocalToWorld(shape.vert2Ds[j].point);
                normals[id]  = path[i].LocalToWorldDirection(shape.vert2Ds[j].normal);
                uvs[id]      = new Vector2(shape.vert2Ds[j].uCoord, i / ((float)edgeLoops));
            }
        }
        int ti = 0;

        int[] lines = shape.lines;
        for (int i = 0; i < segments; i++)
        {
            int offset = i * vertsInShape;
            for (int l = 0; l < lines.Length; l += 2)
            {
                int a = offset + lines[l] + vertsInShape;
                int b = offset + lines[l];
                int c = offset + lines[l + 1];
                int d = offset + lines[l + 1] + vertsInShape;
                triangleIndices[ti] = a;     ti++;
                triangleIndices[ti] = b;     ti++;
                triangleIndices[ti] = c;     ti++;
                triangleIndices[ti] = c;     ti++;
                triangleIndices[ti] = d;     ti++;
                triangleIndices[ti] = a;     ti++;
            }
        }

        mesh.Clear();
        mesh.vertices  = vertices;
        mesh.triangles = triangleIndices;
        mesh.normals   = normals;
        mesh.uv        = uvs;
    }
Example #11
0
    public void RenderRoad(Path path)
    {
        transform.position = Vector3.zero;
        Vector3[] points        = path.CalculateEvenlySpacedPoints(spacing);
        int       textureRepeat = Mathf.RoundToInt(tiling * points.Length * spacing * .05f);

        GetComponent <MeshRenderer>().material.mainTextureScale = new Vector3(1, textureRepeat);
        Quaternion[] quats        = getNormal(points);
        Vector3[]    shapRoad     = sortVects3(roadMesh.vertices);
        ExtrudeShape extrudeShape = new ExtrudeShape(shapRoad, roadHeight, roadWidth);

        GetComponent <MeshFilter>().mesh = Extrude(extrudeShape, createOrientedPoints(points, quats));
    }
Example #12
0
    void Start()
    {
        MeshFilter mf = GetComponent <MeshFilter>();

        Mesh mesh = mf.mesh;

        Points = new Vector3[]
        {
            Transform1.position,
            Transform2.position,
            Transform3.position,
            Transform4.position,
        };

        if (_noPointsYet)
        {
            Normals = new Vector2[]
            {
                new Vector2(0, 0),
                new Vector2(1, 0),
                new Vector2(2, 0),
                new Vector2(3, 0),
            };

            Shape = new Vector2[]
            {
                new Vector2(0, 0),
                new Vector2(0, 1),
                new Vector2(0, 2),
                new Vector2(0, 3),
            };

            _noPointsYet = false;
        }

        _curve = new BezierCurves(Points);

        OrientedPoint[] oPoints = _curve.GeneratePath(NumberOfSubdivisions).ToArray();

        float[] uv = new float[]
        {
            0.0f,
            1,
            0,
            1
        };

        ExtrudeShape extrudeShape = new ExtrudeShape(Shape, Normals, uv);

        _curve.Extrude(mesh, extrudeShape, oPoints);
    }
Example #13
0
    public void Load()
    {
        if (File.Exists(Application.dataPath + "/ProceduralTracks/CurvesSavedData/" + gameObject.name + ".curve"))
        {
            ClearCurve();

            BinaryFormatter bf   = new BinaryFormatter();
            FileStream      file = File.Open(Application.dataPath + "/ProceduralTracks/CurvesSavedData/" + gameObject.name + ".curve", FileMode.Open);
            CurveData       data = (CurveData)bf.Deserialize(file);
            file.Close();

            if (extrudeShape == null)
            {
                extrudeShape = new ExtrudeShape();
            }

            Node previousNode = null;
            for (int i = 0; i < data.nodesData.Length; ++i)
            {
                // Create Node
                Node node = CreateNode(transform.position, transform.rotation);
                node.Load(data.nodesData[i]);

                // If not the first, create a spline with the previous one
                if (previousNode != null)
                {
                    BezierSpline spline = CreateSpline(previousNode, node);
                    spline.SetData(data.splinesData[i - 1]);
                    spline.Extrude(meshes[i - 1], extrudeShape);
                }
                previousNode = node;
            }

            this.closed = data.closed;
            if (closed)
            {
                BezierSpline spline = CreateSpline(nodes[nodes.Count - 1], nodes[0]);
                spline.Extrude(meshes[meshes.Count - 1], extrudeShape);
            }

            this.invisible = data.invisible;
        }
        else
        {
            Debug.Assert(true, "Data file not found");
        }
    }
Example #14
0
    private void OnSceneGUI()
    {
        extrudeShape    = target as ExtrudeShape;
        handleTransform = extrudeShape.transform;
        handleRotation  = Tools.pivotRotation == PivotRotation.Local ?
                          handleTransform.rotation : Quaternion.identity;

        Vector3 p0 = ShowPoint(0);

        for (int i = 0; i < extrudeShape.verts.Length - 1; i++)
        {
            Vector3 p1 = ShowPoint(i + 1);
            Handles.DrawLine(p0, p1);
            Repaint();
            p0 = p1;
        }
    }
Example #15
0
    void GenerateCurve()
    {
        bc = new BezierCurve(points);

        ExtrudeShape es = new ExtrudeShape();

        //Vertices for extrusion shape
        es.verts = new Vector2[] {
            new Vector2(-2, 0),
            new Vector2(-1.1f, 0.9f),
            new Vector2(0, 1),
            new Vector2(1.1f, 0.9f),
            new Vector2(2, 0)
        };
        es.normals = new Vector2[] {
            Vector2.up,
            Vector2.up,
            Vector2.up,
            Vector2.up,
            Vector2.up
        };
        es.uCoords = new float[] {
            0,
            0,
            0,
            0,
            0
        };

        bc.Extrude(GetComponent <MeshFilter>().sharedMesh, es, bc.GeneratePath((float)divisions).ToArray());

        /*
         * bc.Extrude(GetComponent<MeshFilter>().sharedMesh, es, new OrientedPoint[]{
         *      new OrientedPoint(new Vector3(0,0,0),Quaternion.identity, 0),
         *      new OrientedPoint(new Vector3(0,5,10),Quaternion.identity, 1),
         *      new OrientedPoint(new Vector3(0,15,20),Quaternion.identity, 2),
         *      new OrientedPoint(new Vector3(0,20,25),Quaternion.identity, 3)
         * });
         */
    }
Example #16
0
    public override void Extrude()
    {
        if (invisible)
        {
            for (int i = 0; i < splines.Count; ++i)
            {
                splines[i].gameObject.GetComponent <MeshCollider>().sharedMesh = null;
                splines[i].gameObject.GetComponent <MeshFilter>().sharedMesh   = null;
            }

            return;
        }

        if (extrudeShape == null)
        {
            extrudeShape = new ExtrudeShape();
        }

        for (int i = 0; i < splines.Count; ++i)
        {
            splines[i].Extrude(meshes[i], extrudeShape);
        }
    }
Example #17
0
 void MakeShape()
 {
     shape       = new ExtrudeShape();
     shape.verts = new Vector2[]
     {
         new Vector2(0, -10),
         new Vector2(0, 10),
         new Vector2(0, 10),
         new Vector2(0, 10),
         new Vector2(1, 10),
         new Vector2(1, -10),
         new Vector2(1, -10),
         new Vector2(0, -10)
     };
     shape.normals = new Vector2[]
     {
         new Vector2(1, 0),
         new Vector2(1, 0),
         new Vector2(0, 1),
         new Vector2(0, 1),
         new Vector2(-1, 0),
         new Vector2(-1, 0),
         new Vector2(0, -1),
         new Vector2(0, -1)
     };
     shape.uCoords = new float[]
     {
         0,
         1,
         1,
         1,
         0,
         1,
         1,
         1
     };
 }
Example #18
0
    public static void Extrude(ref Mesh mesh, ExtrudeShape shape, OrientedPoint[] path)
    {
        int vertsInShape  = shape.verts.Length;
        int segments      = path.Length - 1;
        int edgeLoops     = path.Length;
        int vertCount     = vertsInShape * edgeLoops;
        int triCount      = shape.Lines.Length * segments;
        int triIndexCount = triCount * 3;

        //Debug.Log(string.Format("VertsInShape:{0}\nsegments:{1}\nedgeLoops:{2}\nvertCount:{3}\ntriCount:{4}\ntriIndexCount:{5}",
        //    vertsInShape, segments, edgeLoops, vertCount, triCount, triIndexCount));
        int[]     triangleIndices = new int[triIndexCount];
        Vector3[] vertices        = new Vector3[vertCount];
        Vector3[] normals         = new Vector3[vertCount];
        Vector2[] uvs             = new Vector2[vertCount];

        // Generate all of the vertices and normals
        for (int i = 0; i < path.Length; i++)
        {
            int    offset = i * vertsInShape;
            string debug  = string.Format("pathPoint:{0}\noffset:{1}\n", i, offset);
            for (int j = 0; j < vertsInShape; j++)
            {
                int id = offset + j;
                vertices[id] = path[i].LocalToWorld(shape.verts[j]);
                //vertices[id] = shape.verts[j];
                normals[id] = path[i].LocalToWorldDirection(shape.normals[j]);
                //normals[id] = shape.normals[j];
                uvs[id] = new Vector2(shape.uCoords[j], path[i].vCoordinate);
                debug  += string.Format("id:{0}\nvert:{1}\nnormals:{2}\nuv:{3}\n", id, vertices[id], normals[id], uvs[id]);
            }
            //Debug.Log(debug);
        }

        //Generation
        int ti = 0;

        for (int i = 0; i < segments; i++)
        {
            int offset = i * vertsInShape;
            for (int l = 0; l < shape.Lines.Length; l += 2)
            {
                int a = offset + shape.Lines[l];
                int b = offset + shape.Lines[l] + vertsInShape;
                int c = offset + shape.Lines[l + 1] + vertsInShape;
                int d = offset + shape.Lines[l + 1];
                triangleIndices[ti++] = a;
                triangleIndices[ti++] = b;
                triangleIndices[ti++] = c;
                triangleIndices[ti++] = c;
                triangleIndices[ti++] = d;
                triangleIndices[ti++] = a;
            }
        }

        mesh.Clear();
        mesh.vertices  = vertices;
        mesh.triangles = triangleIndices;
        mesh.normals   = normals;
        mesh.uv        = uvs;
        string debugs = "Final Verts\n";

        for (int i = 0; i < mesh.vertices.Length; i++)
        {
            debugs += string.Format("vert {0}: {1}\n", i, mesh.vertices[i]);
        }
        //Debug.Log(debugs);
    }
Example #19
0
    public void GenerateMesh()
    {
        mf      = GetComponent <MeshFilter>();
        mf.mesh = null;
        if (mf.sharedMesh == null)
        {
            mf.sharedMesh = new Mesh();
        }
        mesh = mf.sharedMesh;
        s    = Parent._Spline;
        if (shape == null)
        {
            shape = new ExtrudeShape();
        }
        shape.verts   = verts.ToArray();
        shape.normals = new Vector2[GetVertCount()];
        shape.uCoords = new float[GetVertCount()];

        float uLength = 0;

        float[] pointPos = new float[GetVertCount()];
        pointPos[0] = 0;
        for (int i = 1; i < verts.Count; i++)
        {
            uLength    += Vector2.Distance(verts[i - 1], verts[i]);
            pointPos[i] = uLength;
        }
        for (int i = 0; i < GetVertCount(); i++)
        {
            shape.uCoords[i] = pointPos[i] / uLength;
            float   dx, dy;
            Vector2 normal;
            if (i == 0)
            {
                dx     = shape.verts[1].x - shape.verts[0].x;
                dy     = shape.verts[1].y - shape.verts[0].y;
                normal = new Vector2(dy, -dx);

                shape.normals[i] = BezierUtil.Cross(new Vector2(dx, dy), normal) > 0 ? normal : new Vector2(-dy, dx);
            }
            else if (i == GetVertCount() - 1)
            {
                dx     = shape.verts[0].x - shape.verts[i].x;
                dy     = shape.verts[0].y - shape.verts[i].y;
                normal = new Vector2(dy, -dx);
            }
            else
            {
                dx     = shape.verts[i + 1].x - shape.verts[i].x;
                dy     = shape.verts[i + 1].y - shape.verts[i].y;
                normal = new Vector2(dy, -dx);
            }
            normal           = BezierUtil.Cross(new Vector2(dy, dx), normal) > 0 ? normal : new Vector2(-dy, dx);
            shape.normals[i] = normal.normalized;
            //print(string.Format("{0}:{1}", i, normal.normalized));
        }

        float[] samples = BezierUtil.GenerateSamples(s.curvePoints.ToArray());

        if (s != null)
        {
            OrientedPoint[] op    = new OrientedPoint[s.curvePoints.Count];
            string          debug = "";
            for (int i = 0; i < op.Length; i++)
            {
                //op[i] = BezierUtil.GetOrientedPoint(s.curvePoints.ToArray(), ((float)i / (float)op.Length), samples);
                op[i] = new OrientedPoint(s.curvePoints[i], Quaternion.identity, samples.Sample(((float)i / (float)op.Length)));
                //debug += " " + op[i].vCoordinate;
            }
            //Debug.Log(debug);
            BezierUtil.Extrude(ref mesh, shape, op);
            //mesh.RecalculateNormals();
        }
        else
        {
            Debug.Log("no s");
        }
    }
Example #20
0
    public override void Extrude()
    {
        if (invisible)
        {
            for (int i = 0; i < splines.Count; ++i)
            {
                splines[i].gameObject.GetComponent<MeshCollider>().sharedMesh = null;
                splines[i].gameObject.GetComponent<MeshFilter>().sharedMesh = null;
            }

            return;
        }

        if (extrudeShape == null)
        {
            extrudeShape = new ExtrudeShape();
        }

        for (int i = 0; i < splines.Count; ++i)
        {
            splines[i].Extrude(meshes[i], extrudeShape);
        }
    }
Example #21
0
    public void Load()
    {
        if(File.Exists(Application.dataPath + "/ProceduralTracks/CurvesSavedData/" + gameObject.name + ".curve"))
        {
            ClearCurve();

            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.dataPath + "/ProceduralTracks/CurvesSavedData/" + gameObject.name + ".curve", FileMode.Open);
            CurveData data = (CurveData)bf.Deserialize(file);
            file.Close();

            if (extrudeShape == null) { extrudeShape = new ExtrudeShape(); }

            Node previousNode = null;
            for (int i = 0; i < data.nodesData.Length; ++i)
            {
                // Create Node
                Node node = CreateNode(transform.position, transform.rotation);
                node.Load(data.nodesData[i]);

                // If not the first, create a spline with the previous one
                if (previousNode != null)
                {
                    BezierSpline spline = CreateSpline(previousNode, node);
                    spline.SetData(data.splinesData[i - 1]);
                    spline.Extrude(meshes[i - 1], extrudeShape);
                }
                previousNode = node;
            }

            this.closed = data.closed;
            if(closed)
            {
                BezierSpline spline = CreateSpline(nodes[nodes.Count-1], nodes[0]);
                spline.Extrude(meshes[meshes.Count-1], extrudeShape);
            }

            this.invisible = data.invisible;
        }
        else
        {
            Debug.Assert(true, "Data file not found");
        }
    }
Example #22
0
    private void Extrude(Mesh mesh, ExtrudeShape shape, OrientedPoint[] path)
    {
        int vertsInShape  = shape.verts.Length;
        int segments      = path.Length - 1;
        int edgeLoops     = path.Length;
        int vertCount     = vertsInShape * edgeLoops;
        int triCount      = shape.lines.Length * segments;
        int triIndexCount = triCount * 3;

        var triangleIndices = new int[triIndexCount];
        var vertices        = new Vector3[vertCount];
        var normals         = new Vector3[vertCount];
        var uvs             = new Vector2[vertCount];

        float totalLength     = 0;
        float distanceCovered = 0;

        for (int i = 0; i < path.Length - 1; i++)
        {
            var d = Vector3.Distance(path[i].position, path[i + 1].position);
            totalLength += d;
        }

        for (int i = 0; i < path.Length; i++)
        {
            int offset = i * vertsInShape;
            if (i > 0)
            {
                var d = Vector3.Distance(path[i].position, path[i - 1].position);
                distanceCovered += d;
            }
            float v = distanceCovered / totalLength;

            for (int j = 0; j < vertsInShape; j++)
            {
                int id = offset + j;
                vertices[id] = path[i].LocalToWorld(shape.verts[j].point);
                normals[id]  = path[i].LocalToWorldDirection(shape.verts[j].normal);
                uvs[id]      = new Vector2(shape.verts[j].uCoord, v);
            }
        }
        int ti = 0;

        for (int i = 0; i < segments; i++)
        {
            int offset = i * vertsInShape;
            for (int l = 0; l < shape.lines.Length; l += 2)
            {
                int a = offset + shape.lines[l] + vertsInShape;
                int b = offset + shape.lines[l];
                int c = offset + shape.lines[l + 1];
                int d = offset + shape.lines[l + 1] + vertsInShape;
                triangleIndices[ti] = c; ti++;
                triangleIndices[ti] = b; ti++;
                triangleIndices[ti] = a; ti++;
                triangleIndices[ti] = a; ti++;
                triangleIndices[ti] = d; ti++;
                triangleIndices[ti] = c; ti++;
            }
        }


        mesh.Clear();
        mesh.vertices  = vertices;
        mesh.normals   = normals;
        mesh.uv        = uvs;
        mesh.triangles = triangleIndices;
    }
    public void Load()
    {
        if (File.Exists(Application.dataPath + "/ProceduralTracks/CurvesSavedData/" + gameObject.name + ".curve"))
        {
            ClearCurve();

            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.dataPath + "/ProceduralTracks/CurvesSavedData/" + gameObject.name + ".curve", FileMode.Open);
            BifurcationData data = (BifurcationData)bf.Deserialize(file);
            file.Close();

            if (extrudeShape == null) { extrudeShape = new ExtrudeShape(); }

            for (int i = 0; i < data.nodesData.Length; ++i)
            {
                // Create Nodes
                Node node = CreateNode(transform.position, transform.rotation);
                node.Load(data.nodesData[i]);
            }

            planeX = data.planeX;

            // Create Splines
            CreateSpline(nodes[0], nodes[1]).ExtrudeSide(meshes[0], extrudeShape, "right", planeX);
            CreateSpline(nodes[0], nodes[2]).ExtrudeSide(meshes[1], extrudeShape, "left", planeX);

            splines[0].SetData(data.splinesData[0]);
            splines[1].SetData(data.splinesData[1]);
        }
        else
        {
            //Debug.Assert(true, "Data file not found");
            //Create();
        }
    }
 public override void Extrude()
 {
     if (extrudeShape == null)
     {
         extrudeShape = new ExtrudeShape();
     }
     splines[0].ExtrudeSide(meshes[0], extrudeShape, "right", planeX);
     splines[1].ExtrudeSide(meshes[1], extrudeShape, "left", planeX);
 }
    /// <summary>
    /// Procedural generates a mesh from the edge spline
    /// Used to simulate roads
    /// </summary>
    private void OnGenerateMesh()
    {
        if (GUILayout.Button("Generate Mesh"))
        {
            Vector2[] verts = new Vector2[]
            {
                new Vector2(-0.5f, 0),
                new Vector2(0, 0),
                new Vector2(0.5f, 0)
            };

            Vector2[] norms = new Vector2[]
            {
                Vector2.up,
                Vector2.up,
                Vector2.up
            };

            float[] uCoords = new float[]
            {
                0,
                1,
                0
            };

            ExtrudeShape shape = new ExtrudeShape(verts, norms, uCoords);

            foreach (Edge edge in map.EdgeList)
            {
                List <OrientedPoint> path = new List <OrientedPoint>();
                MeshFilter           mf   = edge.gameObject.GetComponent <MeshFilter>();
                if (mf.sharedMesh == null)
                {
                    mf.sharedMesh = new Mesh();
                }
                Mesh mesh = mf.sharedMesh;


                foreach (OrientedPoint p in edge.GeneratePath(1000f))
                {
                    path.Add(p);
                }

                edge.Extrude(mesh, shape, path.ToArray());
            }
        }

        EditorGUILayout.Space();
        if (GUILayout.Button("Clear Mesh"))
        {
            foreach (Edge edge in map.EdgeList)
            {
                MeshFilter mf = edge.gameObject.GetComponent <MeshFilter>();
                if (mf.sharedMesh == null)
                {
                    mf.sharedMesh = new Mesh();
                }
                Mesh mesh = mf.sharedMesh;

                mesh.Clear();
            }
        }
    }
Example #26
0
    public void ReDrawMesh()
    {
        Vector3[] points = new Vector3[]
        {
            p1, p2, p3, p4
        };

        BezierCurve curve = new BezierCurve(points, rotationP1, rotationP4);

        Mesh mesh = new Mesh();

        ExtrudeShape shape = new ExtrudeShape();

        float steps     = 6;
        float width     = 10f;
        float step      = width / (steps - 1);
        float halfWidth = width / 2f;

        shape.verts = new Vector2[]
        {
            new Vector2(0 * step - halfWidth, 0),
            new Vector2(1 * step - halfWidth, 0),
            new Vector2(2 * step - halfWidth, 0),
            new Vector2(3 * step - halfWidth, 0),
            new Vector2(4 * step - halfWidth, 0),
            new Vector2(5 * step - halfWidth, 0),
            new Vector2(5 * step - halfWidth, -1),
            new Vector2(-halfWidth, -1),
            new Vector2(-halfWidth, 0)
        };

        shape.normals = new Vector2[]
        {
            new Vector2(0, 1),
            new Vector2(0, 1),
            new Vector2(0, 1),
            new Vector2(0, 1),
            new Vector2(0, 1),
            new Vector2(0, 1),
            new Vector2(0, 1),
            new Vector2(0, 1),
            new Vector2(0, 1)
        };

        shape.uCoords = new float[]
        {
            0.03f,
            0.20f,
            0.40f,
            0.60f,
            0.80f,
            0.97f,
            0.95f,
            0.97f,
            0.95f
        };

        m_path = curve.GeneratePath(segments).ToArray();

        curve.Extrude(mesh, shape, m_path);

        MeshFilter mf = GetComponent <MeshFilter>();

        mf.sharedMesh = mesh;
    }
Example #27
0
    public void ExtrudeSide(Mesh mesh, ExtrudeShape shape, string side, float planeX)
    {
        Vector3 position = new Vector3(planeX, 0, 0);
        Vector3 normal   = new Vector3(1, 0, 0);

        Extrude(mesh, shape);
        mesh = gameObject.GetComponent <MeshFilter>().sharedMesh;

        int[]     triangleIndices = mesh.GetIndices(0); //new int[triIndexCount];
        Vector3[] vertices        = mesh.vertices;
        Vector3[] normals         = mesh.normals;


        List <Vector2> uvs = new List <Vector2>();

        mesh.GetUVs(0, uvs); //new Vector2[vertCount];

        List <Vector3> newVertices = new List <Vector3>();
        List <Vector3> newNormals  = new List <Vector3>();
        List <Vector2> newUVs      = new List <Vector2>();
        List <int>     newIndices  = new List <int>();

        // We will cut the mesh with a plane.
        // for each triangle (looking at indices) process if one vertex on the other side of the plane
        for (int i = 0; i < triangleIndices.Length; i = i + 3)
        {
            List <int> side1 = new List <int>();
            List <int> side2 = new List <int>();


            if (splineCoordsToNode(vertices[triangleIndices[i]]).x > planeX)
            {
                side2.Add(triangleIndices[i]);
            }
            else
            {
                side1.Add(triangleIndices[i]);
            }
            if (splineCoordsToNode(vertices[triangleIndices[i + 1]]).x > planeX)
            {
                side2.Add(triangleIndices[i + 1]);
            }
            else
            {
                side1.Add(triangleIndices[i + 1]);
            }
            if (splineCoordsToNode(vertices[triangleIndices[i + 2]]).x > planeX)
            {
                side2.Add(triangleIndices[i + 2]);
            }
            else
            {
                side1.Add(triangleIndices[i + 2]);
            }



            // Depending on the side evaluated determine wich vertices are in and which out
            List <int> inside;
            List <int> outside;
            if (side == "left")
            {// left
                inside  = side1;
                outside = side2;
            }
            else
            {// right
                inside  = side2;
                outside = side1;
            }

            // Cases
            if (inside.Count == 3)
            {// all vertices on the correct side
                continue;
            }
            else
            {
                // discard triangle
                triangleIndices[i] = triangleIndices[i + 1] = triangleIndices[i + 2] = 0;

                if (outside.Count == 2)
                {// case 1: 1 vertices in, 2 out. Create 2 more vertices and one tri.
                    Vector3 v1 = Intersection(vertices[inside[0]], vertices[outside[0]], normal, position);
                    Vector3 v2 = Intersection(vertices[inside[0]], vertices[outside[1]], normal, position);
                    newVertices.Add(v1);
                    newVertices.Add(v2);

                    newNormals.Add(new Vector3(0, 1, 0));
                    newNormals.Add(new Vector3(0, 1, 0));

                    newUVs.Add(new Vector3(0, 0, 0));
                    newUVs.Add(new Vector3(0, 0, 0));

                    if (side == "right" || (vertices[outside[0]].z > vertices[outside[1]].z))
                    {
                        newIndices.Add(inside[0]);
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v1));
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v2));
                    }
                    else
                    {
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v1));
                        newIndices.Add(inside[0]);
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v2));
                    }
                }
                else if (outside.Count == 1)
                {// case 2: 2 vertices in, 1 out. create 2 more vertices and 2 tris.
                    Vector3 v1 = Intersection(vertices[inside[0]], vertices[outside[0]], normal, position);
                    Vector3 v2 = Intersection(vertices[inside[1]], vertices[outside[0]], normal, position);
                    newVertices.Add(v1);
                    newVertices.Add(v2);

                    newNormals.Add(new Vector3(0, 1, 0));
                    newNormals.Add(new Vector3(0, 1, 0));

                    newUVs.Add(new Vector3(0, 0, 0));
                    newUVs.Add(new Vector3(0, 0, 0));

                    if (side == "right" || (vertices[inside[0]].z > vertices[inside[1]].z))
                    {
                        newIndices.Add(inside[0]);
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v1));
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v2));

                        newIndices.Add(inside[1]);
                        newIndices.Add(inside[0]);
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v2));
                    }
                    else
                    {
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v1));
                        newIndices.Add(inside[0]);
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v2));

                        newIndices.Add(inside[0]);
                        newIndices.Add(inside[1]);
                        newIndices.Add(vertices.Length + newVertices.IndexOf(v2));
                    }
                }
            }
        }

        vertices = Concat <Vector3>(vertices, newVertices.ToArray());
        normals  = Concat <Vector3>(normals, newNormals.ToArray());
        Vector2[] muvs = Concat <Vector2>(uvs.ToArray(), newUVs.ToArray());
        triangleIndices = Concat <int>(triangleIndices, newIndices.ToArray());

        mesh.Clear();
        mesh.vertices  = vertices;
        mesh.triangles = triangleIndices;
        mesh.normals   = normals;
        mesh.uv        = muvs;

        //mesh.RecalculateNormals();

        gameObject.GetComponent <MeshFilter>().sharedMesh   = mesh;
        gameObject.GetComponent <MeshCollider>().sharedMesh = mesh;
    }
Example #28
0
    void GenerateMesh()
    {
        ExtrudeShape shape = new ExtrudeShape();

        Vertex2D[] verts = new Vertex2D[points.Length];



        for (int i = 0; i < points.Length; ++i)
        {
            verts[i]       = new Vertex2D();
            verts[i].point = points[i].position;

            if (i == points.Length - 1)
            {
                Vector2 direction = points[i].position - points[i - 1].position;
                verts[i].normal = new Vector2(-direction.y, direction.x);
            }
            else
            {
                Vector2 direction = points[i + 1].position - points[i].position;
                verts[i].normal = new Vector2(-direction.y, direction.x);
            }

            verts[i].uCoord = 1.0f * i / (points.Length - 1);
        }

        int[] lines = new int[(points.Length - 1) * 2];
        for (int i = 0; i < points.Length - 1; ++i)
        {
            lines[i * 2]     = i;
            lines[i * 2 + 1] = i + 1;
        }

        shape.vert2Ds = verts;
        shape.lines   = lines;

        Vector3[] controlPoints =
        {
            p0.position,
            p1.position,
            p2.position,
            p3.position,
        };

        OrientedPoint[] path = new OrientedPoint[segmentCount + 1];

        Vector3 lastPoint = Vector3.zero;


        for (int i = 0; i <= segmentCount; ++i)
        {
            float      t        = (float)i / segmentCount;
            Vector3    position = CubicBezier3D.GetPoint(controlPoints, t);
            Quaternion rotation = CubicBezier3D.GetOrientation3D(controlPoints, t, Vector3.up);

            path[i] = new OrientedPoint(position, rotation);

            Vector3 normal = CubicBezier3D.GetNormal3D(controlPoints, t, Vector3.up);
            //debug info
            // Debug.DrawLine(position, position + normal * 5, Color.blue);

            if (i != 0)
            {
                Debug.DrawLine(lastPoint, position, Color.green);
            }

            lastPoint = position;
        }

        arr = new float[2];
        CalcLengthTableInto(arr, controlPoints);
        Extrude(mesh, shape, path);
    }
Example #29
0
    public void ExtrudeSideOld(Mesh mesh, ExtrudeShape shape, string side)
    {
        if (shape == null)
        {
            shape = new ExtrudeShape();
        }

        int factor = 1;

        if (side == "left")
        {
            factor = -1;
        }


        float splineLength = GetLength();

        shape.Initialize(1, curve.horizontalDivisions);

        int divisions = (int)(curve.divisionsPerCurve * splineLength / curve.trackWidth / 20);

        if (divisions < 1)
        {
            divisions = 1;
        }
        int vertsInShape = shape.verts.Length;

        List <int>     triangleIndices = new List <int>();     //new int[triIndexCount];
        List <Vector3> vertices        = new List <Vector3>(); //new Vector3[vertCount];
        List <Vector3> normals         = new List <Vector3>(); //new Vector3[vertCount];
        List <Vector2> uvs             = new List <Vector2>(); //new Vector2[vertCount];

        /*
         *  Mesh generation code
         */
        #region meshGeneration

        float divisionLength = 1.0f / (float)divisions;
        orientedPoints = new OrientedPoint[divisions + 1];

        // Create vertices
        for (int i = 0; i <= divisions; ++i)
        {// for each edgeLoop
            float t = i * divisionLength;

            Vector3   up        = Vector3.Lerp(startNode.transform.up, endNode.transform.up, t);
            float     curvature = Mathf.Lerp(startNode.rightCurvature, endNode.rightCurvature, t);
            float     width     = (curve.trackWidth + Mathf.Lerp(startNode.trackWidthModifier, endNode.trackWidthModifier, t)) / 2;
            Matrix4x4 scale     = Matrix4x4.Scale(new Vector3(width, width, width));

            // Initialize oriented point
            orientedPoints[i].position = transform.InverseTransformPoint(GetPoint(t));
            orientedPoints[i].rotation = Quaternion.Inverse(transform.rotation) * (GetOrientation(t, up));
            orientedPoints[i].scale    = scale;

            for (int j = 0; j < vertsInShape; ++j)
            {// for each vertex in the shape
                Vector2 vertex = Vector2.Lerp(shape.verts[j], shape.curvedVerts[j], curvature);
                vertex.x *= factor;
                Vector2 normal = Vector2.Lerp(shape.normals[j], shape.curvedNormals[j], curvature);

                vertices.Add(orientedPoints[i].LocalToWorld(vertex));
                normals.Add(orientedPoints[i].LocalToWorldDirection(normal));

                // u is based on the 2D shape, and v is based on the distance along the curve
                uvs.Add(new Vector2(shape.us[j], t * splineLength / width));
            }
        }

        // Create triangles
        for (int j = 0; j < divisions; ++j)
        {// for each division in the curve
            int offset = shape.verts.Length * j;

            for (int k = 0; k < shape.lines.Length; k = k + 2)
            {//for each 2d line in the shape
                if (side == "right")
                {
                    // triangle 1
                    triangleIndices.Add(shape.lines[k + 1] + offset);
                    triangleIndices.Add(shape.lines[k] + offset);
                    triangleIndices.Add(shape.lines[k] + offset + shape.verts.Length);
                    // triangle 2
                    triangleIndices.Add(shape.lines[k + 1] + offset);
                    triangleIndices.Add(shape.lines[k] + offset + shape.verts.Length);
                    triangleIndices.Add(shape.lines[k + 1] + offset + shape.verts.Length);
                }
                else
                {
                    // triangle 1
                    triangleIndices.Add(shape.lines[k] + offset);
                    triangleIndices.Add(shape.lines[k + 1] + offset);
                    triangleIndices.Add(shape.lines[k] + offset + shape.verts.Length);
                    // triangle 2
                    triangleIndices.Add(shape.lines[k] + offset + shape.verts.Length);
                    triangleIndices.Add(shape.lines[k + 1] + offset);
                    triangleIndices.Add(shape.lines[k + 1] + offset + shape.verts.Length);
                }
            }
        }

        mesh.Clear();
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangleIndices.ToArray();
        mesh.normals   = normals.ToArray();
        mesh.uv        = uvs.ToArray();

        #endregion

        mesh.RecalculateNormals();

        gameObject.GetComponent <MeshFilter>().mesh         = mesh;
        gameObject.GetComponent <MeshCollider>().sharedMesh = mesh;
    }
Example #30
0
 public override void OnInspectorGUI()
 {
     extrudeShape = target as ExtrudeShape;
     DrawDefaultInspector();
 }