コード例 #1
0
 public BezierCurve3(BezierCurve3 source)
 {
     SetControlPoints((Vector3[])source.ControlPoints.Clone());
 }
コード例 #2
0
ファイル: Graph.cs プロジェクト: XZelnar/PlanetoidMapGen
    /// <summary>
    /// Generates river meshes
    /// </summary>
    /// <param name="waterLevel"></param>
    /// <returns>Combination corner index-mesh</returns>
    public Dictionary<int, Mesh> GetMeshesForRivers(float waterLevel)
    {
        Dictionary<int, Mesh> ma = new Dictionary<int, Mesh>();//Key is index of the corner, Value is Mesh for that corner.
        Mesh m;
        Edge e1, e2;
        int e1ind, e2ind;
        BezierCurve3 bc1 = new BezierCurve3(), bc2 = new BezierCurve3();
        Corner c;
        Vector3 v1, v2;
        Vector3 midpoint1, midpoint2, midpoint3, midpoint4, midpoint5, midpoint6;
        Vector3 p1, p2, p3;
        int j;
        float sqrmin = waterLevel * waterLevel;
        int edgesWithWater;
        float f, f2;

        #region vertices and indices declaration
        const int RiverToOceanVerticesPerSide = 5;
        const int RiverDoubleVerticesPerSide = 9;
        const int RiverTripleVerticesPerSide = 9;
        int[] indicesRiverStart = new int[] { 0, 1, 2 };
        int[] indicesRiverToOcean = new int[] {
            0, 1, 5, 5, 1, 6,
            1, 2, 6, 6, 2, 7,
            2, 3, 7, 7, 3, 8,
            3, 4, 8, 8, 4, 9
        };
        int[] indicesRiverDouble = new int[] {
            0, 1,  9,  9, 1, 10,
            1, 2, 10, 10, 2, 11,
            2, 3, 11, 11, 3, 12,
            3, 4, 12, 12, 4, 13,
            4, 5, 13, 13, 5, 14,
            5, 6, 14, 14, 6, 15,
            6, 7, 15, 15, 7, 16,
            7, 8, 16, 16, 8, 17
        };
        int[] indicesRiverTriple = new int[] {
            0, 1, 26, 26, 1, 25,
            1, 2, 25, 25, 2, 24,
            2, 3, 24, 24, 3, 23,
            3, 4, 23, 23, 4, 22,

            9, 10, 8, 8, 10, 7,
            10, 11, 7, 7, 11, 6,
            11, 12, 6, 6, 12, 5,
            12, 13, 5, 5, 13, 4,

            18, 19, 17, 17, 19, 16,
            19, 20, 16, 16, 20, 15,
            20, 21, 15, 15, 21, 14,
            21, 22, 14, 14, 22, 13,

            4, 13, 22
        };
        Vector3[] verticesRiverStart = new Vector3[3];
        Vector3[] verticesRiverToOcean = new Vector3[RiverToOceanVerticesPerSide * 2];
        Vector3[] verticesRiverDouble = new Vector3[RiverDoubleVerticesPerSide * 2];
        Vector3[] verticesRiverTriple = new Vector3[RiverTripleVerticesPerSide * 3];
        #endregion

        for (int i = 0; i < corners.Count; i++)//Loop through all corners
        {
            c = corners[i];
            edgesWithWater = (c.edges[0].type == Edge.EdgeType.River ? 1 : 0) + (c.edges[1].type == Edge.EdgeType.River ? 1 : 0) + (c.edges[2].type == Edge.EdgeType.River ? 1 : 0);//Count river edges

            if (edgesWithWater == 0)//No rivers near corner
                continue;

            #region 1 edge with river
            if (edgesWithWater == 1)//1 edge with river
            {
                e1ind = (c.edges[0].type == Edge.EdgeType.River ? 0 : (c.edges[1].type == Edge.EdgeType.River ? 1 : 2));//Get the river edge
                e1 = c.edges[e1ind];

                #region outflow to ocean
                if (IsCornerNearNodeOfType(c, Node.NodeType.Sea))//Outflow to ocean
                {
                    v2 = (e1.C1.Position + e1.C2.Position) / 2;//Get edge middle
                    f = e1.riverWidth / 20;//River width
                    v1 = Vector3.Cross(e1.GetOtherCorner(c).Position - c.Position, c.Position).normalized * f;//Midpoint offset
                    midpoint1 = v2 + v1;//Compute midpoints
                    midpoint2 = v2 - v1;

                    p1 = (c.edges[(e1ind + 1) % 3].GetOtherCorner(c).Position - c.Position).normalized * (f * 3) + c.Position;//Compute middle of other two edges
                    p2 = (c.edges[(e1ind + 2) % 3].GetOtherCorner(c).Position - c.Position).normalized * (f * 3) + c.Position;

                    //Determine closest points
                    if (((midpoint1 - p1).sqrMagnitude + (midpoint2 - p2).sqrMagnitude) < ((midpoint1 - p2).sqrMagnitude + (midpoint2 - p1).sqrMagnitude))//m1 to v1
                    {
                        bc1.StartPoint = midpoint1;
                        bc1.EndPoint = p1;
                        bc1.P1 = c.Position + v1;

                        bc2.StartPoint = midpoint2;
                        bc2.EndPoint = p2;
                        bc2.P1 = c.Position - v1;
                    }
                    else//m1 to v2
                    {
                        bc1.StartPoint = midpoint1;
                        bc1.EndPoint = p2;
                        bc1.P1 = c.Position + v1;

                        bc2.StartPoint = midpoint2;
                        bc2.EndPoint = p1;
                        bc2.P1 = c.Position - v1;
                    }

                    for (j = 0, f = 0; j < RiverToOceanVerticesPerSide; j++, f += (1f / (RiverToOceanVerticesPerSide - 1)))//Get points from Bezier curve
                    {
                        verticesRiverToOcean[j] = bc1.GetPoint(f);
                        verticesRiverToOcean[j + RiverToOceanVerticesPerSide] = bc2.GetPoint(f);
                    }

                    for (j = 0; j < verticesRiverToOcean.Length; j++)//Don't let rivers drop below ocean level
                        if (verticesRiverToOcean[j].sqrMagnitude < sqrmin)
                            verticesRiverToOcean[j] = verticesRiverToOcean[j].normalized * waterLevel;

                    //Create mesh
                    OrderMeshTriangles(verticesRiverToOcean, indicesRiverToOcean);
                    m = new Mesh();
                    m.vertices = verticesRiverToOcean;
                    m.SetIndices(indicesRiverToOcean, MeshTopology.Triangles, 0);
                    ma.Add(i, m);
                }//Outflow to ocean
                #endregion

                #region river start
                else//River start
                {
                    verticesRiverStart[0] = c.Position;
                    v2 = (e1.C1.Position + e1.C2.Position) / 2;//Get edge middle
                    v1 = Vector3.Cross(e1.C1.Position - e1.C2.Position, c.Position).normalized * (e1.riverWidth / 20f);//Midpoint offset
                    verticesRiverStart[1] = v2 + v1;//Midpoints
                    verticesRiverStart[2] = v2 - v1;

                    //Create mesh
                    OrderMeshTriangles(verticesRiverStart, indicesRiverStart);
                    m = new Mesh();
                    m.vertices = verticesRiverStart;
                    m.SetIndices(indicesRiverStart, MeshTopology.Triangles, 0);
                    ma.Add(i, m);
                }
                #endregion
            }//1 edge with river
            #endregion
            #region 2 edges with river
            else if (edgesWithWater == 2)//2 edges with water
            {
                e1ind = (c.edges[0].type == Edge.EdgeType.River ? 0 : 1);//Find river edges
                e1 = c.edges[e1ind];
                e2ind = (c.edges[2].type == Edge.EdgeType.River ? 2 : 1);
                e2 = c.edges[e2ind];

                f = e1.riverWidth / 20;//River width
                v2 = p1 = (e1.C1.Position + e1.C2.Position) / 2;//Edge middle
                v1 = Vector3.Cross(e1.GetOtherCorner(c).Position - c.Position, c.Position).normalized * f;//Midpoint offset
                midpoint1 = v2 + v1;//Midpoints
                midpoint2 = v2 - v1;

                f = e2.riverWidth / 20;//River width
                v2 = (e2.C1.Position + e2.C2.Position) / 2;//Edge middle
                v1 = Vector3.Cross(e2.GetOtherCorner(c).Position - c.Position, c.Position).normalized * f;//Midpoint offset
                midpoint3 = v2 + v1;//Midpoints
                midpoint4 = v2 - v1;

                p1 = c.Position - (p1 + v2) / 2;//Offset for Bezier intermediate point

                //1st curve
                bc1.StartPoint = midpoint1;
                bc1.EndPoint = midpoint4;
                bc1.P1 = (midpoint1 + midpoint4) / 2 + p1;

                //2nd curve
                bc2.StartPoint = midpoint2;
                bc2.EndPoint = midpoint3;
                bc2.P1 = (midpoint2 + midpoint3) / 2 + p1;

                for (j = 0, f = 0; j < RiverDoubleVerticesPerSide; j++, f += (1f / (RiverDoubleVerticesPerSide - 1)))//Get points from Bezier curve
                {
                    verticesRiverDouble[j] = bc1.GetPoint(f);
                    verticesRiverDouble[j + RiverDoubleVerticesPerSide] = bc2.GetPoint(f);
                }

                //Create mesh
                OrderMeshTriangles(verticesRiverDouble, indicesRiverDouble);
                m = new Mesh();
                m.vertices = verticesRiverDouble;
                m.SetIndices(indicesRiverDouble, MeshTopology.Triangles, 0);
                ma.Add(i, m);
            }//2 edges with water
            #endregion
            #region 3 edges with river
            else
            {
                e1 = c.edges[0];
                f = e1.riverWidth / 20;//River width
                v2 = p1 = (e1.C1.Position + e1.C2.Position) / 2;//Edge middle
                v1 = Vector3.Cross(e1.GetOtherCorner(c).Position - c.Position, c.Position).normalized * f;//Midpoint offset
                midpoint1 = v2 + v1;//Midpoints
                midpoint2 = v2 - v1;

                e1 = c.edges[1];
                f = e1.riverWidth / 20;//River width
                v2 = p2 = (e1.C1.Position + e1.C2.Position) / 2;//Edge middle
                v1 = Vector3.Cross(e1.GetOtherCorner(c).Position - c.Position, c.Position).normalized * f;//Midpoint offset
                midpoint3 = v2 + v1;//Midpoints
                midpoint4 = v2 - v1;

                e1 = c.edges[2];
                f = e1.riverWidth / 20;//River width
                v2 = p3 = (e1.C1.Position + e1.C2.Position) / 2;//Edge middle
                v1 = Vector3.Cross(e1.GetOtherCorner(c).Position - c.Position, c.Position).normalized * f;//Midpoint offset
                midpoint5 = v2 + v1;//Midpoints
                midpoint6 = v2 - v1;

                #region edge1-edge2
                //Find closest midpoints
                v1 = midpoint1; v2 = midpoint3;
                f = (v1 - v2).sqrMagnitude;
                if ((f2 = (midpoint2 - midpoint3).sqrMagnitude) < f)
                {
                    f = f2; v1 = midpoint2;
                }
                if ((f2 = (midpoint1 - midpoint4).sqrMagnitude) < f)
                {
                    f = f2; v1 = midpoint1; v2 = midpoint4;
                }
                if ((f2 = (midpoint2 - midpoint4).sqrMagnitude) < f)
                {
                    v1 = midpoint2; v2 = midpoint4;
                }

                //Bezier curve
                bc1.StartPoint = v1;
                bc1.EndPoint = v2;
                bc1.P1 = (v1 + v2) / 2 + (c.Position - (p1 + p2) / 2);
                for (j = 0, f = 0; j < RiverTripleVerticesPerSide; j++, f += (1f / (RiverTripleVerticesPerSide - 1)))//Get points from Bezier curve
                    verticesRiverTriple[j] = bc1.GetPoint(f);
                #endregion

                #region edge2-edge3
                //find closest midpoints
                v1 = midpoint3; v2 = midpoint5;
                f = (v1 - v2).sqrMagnitude;
                if ((f2 = (midpoint4 - midpoint5).sqrMagnitude) < f)
                {
                    f = f2; v1 = midpoint4;
                }
                if ((f2 = (midpoint3 - midpoint6).sqrMagnitude) < f)
                {
                    f = f2; v1 = midpoint3; v2 = midpoint6;
                }
                if ((f2 = (midpoint4 - midpoint6).sqrMagnitude) < f)
                {
                    v1 = midpoint4; v2 = midpoint6;
                }

                //Bezier curve
                bc1.StartPoint = v1;
                bc1.EndPoint = v2;
                bc1.P1 = (v1 + v2) / 2 + (c.Position - (p2 + p3) / 2);
                for (j = 0, f = 0; j < RiverTripleVerticesPerSide; j++, f += (1f / (RiverTripleVerticesPerSide - 1)))//Get points from Bezier curve
                    verticesRiverTriple[j + RiverTripleVerticesPerSide] = bc1.GetPoint(f);
                #endregion

                #region edge1-edge3
                //find closest midpoints
                v1 = midpoint1; v2 = midpoint5;
                f = (v1 - v2).sqrMagnitude;
                if ((f2 = (midpoint2 - midpoint5).sqrMagnitude) < f)
                {
                    f = f2; v1 = midpoint2;
                }
                if ((f2 = (midpoint1 - midpoint6).sqrMagnitude) < f)
                {
                    f = f2; v1 = midpoint1; v2 = midpoint6;
                }
                if ((f2 = (midpoint2 - midpoint6).sqrMagnitude) < f)
                {
                    v1 = midpoint2; v2 = midpoint6;
                }

                //Bezier curve
                bc1.StartPoint = v2;
                bc1.EndPoint = v1;
                bc1.P1 = (v1 + v2) / 2 + (c.Position - (p1 + p3) / 2);
                for (j = 0, f = 0; j < RiverTripleVerticesPerSide; j++, f += (1f / (RiverTripleVerticesPerSide - 1)))//Get points from Bezier curve
                    verticesRiverTriple[j + RiverTripleVerticesPerSide + RiverTripleVerticesPerSide] = bc1.GetPoint(f);
                #endregion

                //Create mesh
                OrderMeshTriangles(verticesRiverTriple, indicesRiverTriple);
                m = new Mesh();
                m.vertices = verticesRiverTriple;
                m.SetIndices(indicesRiverTriple, MeshTopology.Triangles, 0);
                ma.Add(i, m);
            }
            #endregion
        }//Loop through all corners

        return ma;
    }
コード例 #3
0
 public RailSegment(BezierCurve3 curve, RailPiece railPiece)
 {
     RailPiece = railPiece;
     Curve     = curve;
 }
コード例 #4
0
        public void CreateGeometry(RailSegment[] railSegments)
        {
            var curveTangents           = new List <Vector3> [railSegments.Length];
            var curvePositions          = new List <Vector3> [railSegments.Length];
            int crossSectionVertexCount = m_geometryDescription.CrossSectionPositions.Length;
            int vertexCount             = 0;
            int triangleCount           = 0;

            for (int k = 0; k < railSegments.Length; k++)
            {
                BezierCurve3 curve = railSegments[k].Curve;
                curveTangents[k] = new List <Vector3>();
//			curvePositions[k] = curve.GetAngleApproximationWithTangents(0.0025f, curveTangents[k]);
                curvePositions[k] = curve.GetDistanceApproximationWithTangents(0.05f, curveTangents[k]);
                vertexCount      += crossSectionVertexCount * curvePositions[k].Count;
                triangleCount    += 2 * (curvePositions[k].Count - 1) * (crossSectionVertexCount - 1);
            }

            var positions = new Vector3[vertexCount];
            var normals   = new Vector3[vertexCount];
            var uvs       = new Vector2[vertexCount];
            var indices   = new int[3 * triangleCount];

            int vertexIndex = 0;
            int indexIndex  = 0;

            for (int k = 0; k < railSegments.Length; k++)
            {
                int   processedVertexCount = vertexIndex;
                float currentU             = 0;
                for (int crossSectionIndex = 0; crossSectionIndex < curvePositions[k].Count; crossSectionIndex++)
                {
                    Vector3   point     = curvePositions[k][crossSectionIndex];
                    Vector3   tangent   = curveTangents[k][crossSectionIndex];
                    Matrix4x4 transform = MatrixHelpers.CreateLookAt(point, tangent, Vector3.up);
                    for (int crossSectionVertexIndex = 0; crossSectionVertexIndex < crossSectionVertexCount; crossSectionVertexIndex++)
                    {
                        Vector2 position2D    = m_geometryDescription.CrossSectionPositions[crossSectionVertexIndex];
                        var     positionLocal = new Vector3(0, position2D.y, -position2D.x);
                        Vector2 d;
                        if (crossSectionVertexIndex < crossSectionVertexCount - 1)
                        {
                            Vector2 nextPosition2D = m_geometryDescription.CrossSectionPositions[crossSectionVertexIndex + 1];
                            if (nextPosition2D == position2D)
                            {
                                // Normal is 'plane' normal, i.e. only depends on line segment
                                Vector2 previousPosition2D = m_geometryDescription.CrossSectionPositions[crossSectionVertexIndex - 1];
                                d = position2D - previousPosition2D;
                            }
                            else
                            {
                                d = nextPosition2D - position2D;
                                if (crossSectionVertexIndex > 0)
                                {
                                    // Normal is 'vertex' normal, i.e. the average of the line segment and previous line segment
                                    Vector2 previousPosition2D = m_geometryDescription.CrossSectionPositions[crossSectionVertexIndex - 1];
                                    d += position2D - previousPosition2D;
                                }
                            }
                        }
                        else
                        {
                            d = position2D - m_geometryDescription.CrossSectionPositions[crossSectionVertexIndex - 1];
                        }
                        var normalLocal = new Vector3(0, d.x, d.y);
                        normalLocal.Normalize();

                        Vector3 positionGlobal = transform.MultiplyPoint(positionLocal);
                        Vector3 normalGlobal   = transform.MultiplyVector(normalLocal);
                        positions[vertexIndex] = positionGlobal;
                        normals[vertexIndex]   = normalGlobal;
                        uvs[vertexIndex]       = new Vector2(currentU, m_geometryDescription.CrossSectionVs[crossSectionVertexIndex]);

                        vertexIndex++;
                    }
                    if (crossSectionIndex < curvePositions[k].Count - 1)
                    {
                        Vector3 step = curvePositions[k][crossSectionIndex + 1] - curvePositions[k][crossSectionIndex];
                        currentU += m_geometryDescription.DeltaUPerMetre * step.magnitude;
                    }
                }
                for (int crossSectionIndex = 0; crossSectionIndex < curvePositions[k].Count - 1; crossSectionIndex++)
                {
                    int startIndex = processedVertexCount + crossSectionIndex * m_geometryDescription.CrossSectionPositions.Length;
                    for (int crossSectionVertexIndex = 0; crossSectionVertexIndex < crossSectionVertexCount - 1; crossSectionVertexIndex++)
                    {
                        indices[indexIndex + 0] = startIndex + crossSectionVertexIndex;
                        indices[indexIndex + 1] = startIndex + crossSectionVertexIndex + 1;
                        indices[indexIndex + 2] = startIndex + crossSectionVertexCount + crossSectionVertexIndex;

                        indices[indexIndex + 3] = startIndex + crossSectionVertexIndex + 1;
                        indices[indexIndex + 4] = startIndex + crossSectionVertexCount + crossSectionVertexIndex + 1;
                        indices[indexIndex + 5] = startIndex + crossSectionVertexCount + crossSectionVertexIndex;

                        indexIndex += 6;
                    }
                }
            }

            Mesh mesh = GameObject.GetComponent <MeshFilter>().mesh;

            mesh.Clear();
            mesh.vertices  = positions;
            mesh.normals   = normals;
            mesh.uv        = uvs;
            mesh.triangles = indices;
        }
コード例 #5
0
 public RailSegment(BezierCurve3 curve)
 {
     Curve = curve;
 }