Ejemplo n.º 1
0
    /// <summary>
    /// 临时缓存的三角形集合
    /// </summary>
    unsafe void Collapse(VertexStruct u, int v, NativeArray <StructRelevanceSphere> aRelevanceSpheres)
    {
        if (v == -1)        //v=9779  坍塌目标
        {
            u.Destructor(); //析构掉
            return;
        }

        int i;

        //u临近的顶点  把临近顶点添加到tmpVertices队列里面
        tmpVerticesList.Clear();
        for (i = 0; i < u.currentNeightCount; i++)   //u是一个顶点
        {
            int nb = u.pneighbors.Get <int>(i);
            if (nb != u.ID)
            {
                tmpVerticesList.Add(nb);
            }
        }
        //Debug
        tempTriangleList.Clear();
        for (i = 0; i < u.currentFaceCount; i++)
        {
            if (GetTriangles(u.pfaces.Get <int>(i)).HasVertex(v))  //获取到三角形
            {
                tempTriangleList.Add(u.pfaces.Get <int>(i));
            }
        }
        // Delete triangles on edge uv
        for (i = tempTriangleList.Length - 1; i >= 0; i--)
        {
            TriangleStruct t = GetTriangles(tempTriangleList[i]);
            //获取t的三个顶点信息
            t.Destructor(ref m_VertexHeap, ref triangles, ref u, idToHeapIndex);
            triangles[tempTriangleList[i]] = t;
        }
        // Update remaining triangles to have v instead of u
        //缓存vNew
        VertexStruct vNewVertex = m_VertexHeap[idToHeapIndex[v]];

        for (i = u.currentFaceCount - 1; i >= 0; i--)
        {
            TriangleStruct t = GetTriangles(u.pfaces.Get <int>(i));
            t.ReplaceVertex(ref m_VertexHeap, u, ref vNewVertex, idToHeapIndex);
            triangles[u.pfaces.Get <int>(i)] = t;  //更新
        }
        //更新VNewIndex
        m_VertexHeap[idToHeapIndex[v]] = vNewVertex;
        u.Destructor();
        // Recompute the edge collapse costs for neighboring vertices
        for (i = 0; i < tmpVerticesList.Length; i++)
        {
            VertexStruct st = m_VertexHeap[idToHeapIndex[tmpVerticesList[i]]];
            ComputeEdgeCostAtVertex(ref st, aRelevanceSpheres);
            m_VertexHeap[idToHeapIndex[tmpVerticesList[i]]] = st;
            m_VertexHeap.ModifyValue(st.HeapIndex, st);
        }
    }
Ejemplo n.º 2
0
    float ComputeEdgeCollapseCost(VertexStruct u, VertexStruct v, float fRelevanceBias)
    {
        bool  bUseEdgeLength  = UseEdgeLength;
        bool  bUseCurvature   = UseCurvature;
        float borderCurvature = fBorderCurvature;

        int   i;
        float fEdgeLength = bUseEdgeLength ? (Vector3.Magnitude(v.Position - u.Position) / OriginalMeshSize) : 1.0f;
        float fCurvature  = 0.001f;

        if (fEdgeLength < float.Epsilon)
        {
            return(borderCurvature * (1 - Vector3.Dot(u.Normal, v.Normal) + 2 * Vector3.Distance(u.UV, v.UV)));
        }
        else
        {
            List <TriangleStruct> sides = new List <TriangleStruct>();
            for (i = 0; i < u.currentFaceCount; i++)
            {
                TriangleStruct ut = GetTriangles(u.pfaces.Get <int>(i));
                if (HasVertex(ut, v.ID))
                {
                    sides.Add(ut);
                }
            }

            if (bUseCurvature)
            {
                for (i = 0; i < u.currentFaceCount; i++)
                {
                    float fMinCurv = 1.0f;

                    for (int j = 0; j < sides.Count; j++)
                    {
                        float dotprod = Vector3.Dot(GetTriangles(u.pfaces.Get <int>(i)).Normal, sides[j].Normal);
                        fMinCurv = Mathf.Min(fMinCurv, (1.0f - dotprod) / 2.0f);
                    }
                    fCurvature = Mathf.Max(fCurvature, fMinCurv);
                }
            }
            bool isBorder = u.IsBorder(triangles);
            if (isBorder && sides.Count > 1)
            {
                fCurvature = 1.0f;
            }

            if (borderCurvature > 1 && isBorder)
            {
                fCurvature = borderCurvature;
            }
        }

        fCurvature += fRelevanceBias;
        return(fEdgeLength * fCurvature);
    }
Ejemplo n.º 3
0
        public TriangleStruct GetTriangleStruct(uint address)
        {
            if (_triangleCache.ContainsKey(address))
            {
                return(_triangleCache[address]);
            }
            TriangleStruct triStruct = new TriangleStruct(address);

            _triangleCache.Add(address, triStruct);
            return(triStruct);
        }
Ejemplo n.º 4
0
 static int IndexOf(TriangleStruct t, int v)
 {
     for (int i = 0; i < 3; i++)
     {
         if (t.vertexs[i] == v)
         {
             return(i);
         }
     }
     return(-1);
 }
Ejemplo n.º 5
0
        public static List <TriangleStruct> GetTrianglesInRange(uint startAddress, int numTriangles)
        {
            List <TriangleStruct> triangleList = new List <TriangleStruct>();

            for (int i = 0; i < numTriangles; i++)
            {
                uint           address  = startAddress + (uint)(i * TriangleConfig.TriangleStructSize);
                TriangleStruct triangle = new TriangleStruct(address);
                triangleList.Add(triangle);
            }
            return(triangleList);
        }
Ejemplo n.º 6
0
    public bool IsBorder(NativeArray <TriangleStruct> triangles)
    {
        int i, j;

        for (i = 0; i < currentNeightCount; i++)
        {
            int nCount = 0;

            for (j = 0; j < currentFaceCount; j++)
            {
                TriangleStruct st = triangles[pfaces.Get <int>(j)];
                if (st.HasVertex(pneighbors.Get <int>(i)))
                {
                    nCount++;
                }
            }
            if (nCount == 1)
            {
                return(true);
            }
        }
        return(false);
    }
Ejemplo n.º 7
0
 public void SetTriangles(List <TriangleStruct> triangleList)
 {
     labelTitle.Text          = "Triangles";
     textBoxTriangleInfo.Text = TriangleStruct.GetFieldNameString() + "\n" + String.Join("\n", triangleList);
 }
Ejemplo n.º 8
0
    void Start()
    {
        leftmesh  = new Mesh();
        rightmesh = new Mesh();

        ArrayList leftpoints  = new ArrayList();
        ArrayList rightpoints = new ArrayList();

        // Add middle rectangle
        middlepoints.Add(new Vector2(-1f, -4f));
        middlepoints.Add(new Vector2(1f, -4f));
        middlepoints.Add(new Vector2(-1f, 1.5f));
        middlepoints.Add(new Vector2(1f, 1.5f));

        // Create triangle that represents the middle
        Vector3[] toppoints = new Vector3[2];
        toppoints [0] = new Vector2(-1f, 1.5f);
        toppoints [1] = new Vector2(1f, 1.5f);
        toptriangle   = new TriangleStruct(new Vector3(0, -1, 0), toppoints [0], toppoints [1]);

        // Add a straight line where the mountain slope will be on each side
        leftpoints.Add(new Vector2(-5f, -4f));
        leftpoints.Add(new Vector2(-1f, 1.5f));

        rightpoints.Add(new Vector2(1f, 1.5f));
        rightpoints.Add(new Vector2(5f, -4f));

        // Subdivide mountain sides
        for (int i = 0; i < SUBDIVISIONS; i++)
        {
            // Left
            ArrayList templeftpoints = new ArrayList();
            for (int j = 0; j < leftpoints.Count - 1; j++)
            {
                // get a midpoint and randomly scale by normal (based on line length)
                Vector2 leftfirstpoint  = (Vector2)leftpoints [j];
                Vector2 leftsecondpoint = (Vector2)leftpoints [j + 1];
                Vector2 leftline        = leftsecondpoint - leftfirstpoint;
                Vector2 leftnormal      = new Vector2(-leftline.y, leftline.x);
                leftnormal = leftnormal.normalized;
                Vector2 leftmidpoint   = Vector2.Scale(leftfirstpoint, new Vector2(0.5f, 0.5f)) + Vector2.Scale(leftsecondpoint, new Vector2(0.5f, 0.5f));
                float   leftnorm       = leftline.magnitude;
                float   leftbumpscale  = leftnorm / 5;
                float   leftbumpoffset = UnityEngine.Random.Range(-leftbumpscale * (0.8f), leftbumpscale);
                Vector2 newleftpoint   = leftmidpoint + (Vector2.Scale(leftnormal, new Vector2(leftbumpoffset, leftbumpoffset)));

                templeftpoints.Add(leftfirstpoint);
                templeftpoints.Add(newleftpoint);
                templeftpoints.Add(leftsecondpoint);
            }
            leftpoints = templeftpoints;

            // Right side
            ArrayList temprightpoints = new ArrayList();
            for (int j = 0; j < rightpoints.Count - 1; j++)
            {
                Vector2 rightfirstpoint  = (Vector2)rightpoints [j];
                Vector2 rightsecondpoint = (Vector2)rightpoints [j + 1];
                Vector2 rightline        = rightsecondpoint - rightfirstpoint;
                Vector2 rightnormal      = new Vector2(-rightline.y, rightline.x);
                rightnormal = rightnormal.normalized;
                Vector2 rightmidpoint   = Vector2.Scale(rightfirstpoint, new Vector2(0.5f, 0.5f)) + Vector2.Scale(rightsecondpoint, new Vector2(0.5f, 0.5f));
                float   rightnorm       = rightline.magnitude;
                float   rightbumpscale  = rightnorm / 5;
                float   rightbumpoffset = UnityEngine.Random.Range(-rightbumpscale * (0.8f), rightbumpscale);
                Vector2 newrightpoint   = rightmidpoint + (Vector2.Scale(rightnormal, new Vector2(rightbumpoffset, rightbumpoffset)));

                temprightpoints.Add(rightfirstpoint);
                temprightpoints.Add(newrightpoint);
                temprightpoints.Add(rightsecondpoint);
            }
            rightpoints = temprightpoints;
        }

        // Create lists of triangles all with the same base poin. Triangles (b, 1, 2), (b, 2, 3), (b, 3, 4) etc...
        Vector2 leftbase  = new Vector3(-1f, -4f, 0);
        Vector2 rightbase = new Vector3(1f, -4f, 0);

        Vector2[] templeft  = Array.ConvertAll(leftpoints.ToArray(), new Converter <object, Vector2>(ObjToVector));
        Vector2[] tempright = Array.ConvertAll(rightpoints.ToArray(), new Converter <object, Vector2>(ObjToVector));

        // Converting to 3d points
        Vector3[] leftvertices = new Vector3[templeft.Length + 1];
        leftvertices [0] = leftbase;
        for (int i = 0; i < templeft.Length; i++)
        {
            leftvertices[i + 1] = new Vector3(templeft[i].x, templeft[i].y, 0);
        }

        Vector3[] rightvertices = new Vector3[tempright.Length + 1];
        rightvertices [0] = rightbase;
        for (int i = 0; i < tempright.Length; i++)
        {
            rightvertices[i + 1] = new Vector3(tempright[i].x, tempright[i].y, 0);
        }

        List <int> leftindexlist  = new List <int>();
        List <int> rightindexlist = new List <int>();

        for (int i = 1; i <= templeft.Length - 1; i++)
        {
            leftindexlist.Add(0);
            leftindexlist.Add(i);
            leftindexlist.Add(i + 1);
        }

        for (int i = 1; i <= tempright.Length - 1; i++)
        {
            rightindexlist.Add(0);
            rightindexlist.Add(i);
            rightindexlist.Add(i + 1);
        }

        int[] leftindices  = leftindexlist.ToArray();
        int[] rightindices = rightindexlist.ToArray();

        // Creating the meshes
        leftmesh.vertices  = leftvertices;
        leftmesh.triangles = leftindices;
        leftmesh.RecalculateNormals();
        leftmesh.RecalculateBounds();

        rightmesh.vertices  = rightvertices;
        rightmesh.triangles = rightindices;
        rightmesh.RecalculateNormals();
        rightmesh.RecalculateBounds();

        // Add Meshes to Gameobjects
        GameObject leftmountain = GameObject.Find("MountainLeft");
        MeshFilter leftfilter   = leftmountain.transform.GetComponent <MeshFilter> ();

        leftfilter.mesh = leftmesh;

        GameObject rightmountain = GameObject.Find("MountainRight");
        MeshFilter rightfilter   = rightmountain.transform.GetComponent <MeshFilter> ();

        rightfilter.mesh = rightmesh;

        GameObject middlemountain = GameObject.Find("MountainMiddle");

        middlemountain.transform.position   = new Vector3(0, -1.25f, 0);
        middlemountain.transform.localScale = new Vector3(2f, 5.5f, 1f);

        // Creating lists of Triangle Structures
        int[]     lefttriindices  = leftmesh.triangles;
        Vector3[] lefttrivertices = leftmesh.vertices;
        lefttriangles = new TriangleStruct[leftindices.Length / 3];
        for (int i = 0; i < lefttriangles.Length; i++)
        {
            Vector3        leftbasepoint = leftvertices [leftindices [3 * i]];
            Vector3        leftpointone  = leftvertices [leftindices [3 * i + 1]];
            Vector3        leftpointtwo  = leftvertices [leftindices [3 * i + 2]];
            TriangleStruct leftt         = new TriangleStruct(leftbasepoint, leftpointone, leftpointtwo);
            lefttriangles [i] = leftt;
        }

        int[]     righttriindices  = rightmesh.triangles;
        Vector3[] righttrivertices = rightmesh.vertices;
        righttriangles = new TriangleStruct[rightindices.Length / 3];
        for (int i = 0; i < righttriangles.Length; i++)
        {
            Vector3        rightbasepoint = rightvertices [rightindices [3 * i]];
            Vector3        rightpointone  = rightvertices [rightindices [3 * i + 1]];
            Vector3        rightpointtwo  = rightvertices [rightindices [3 * i + 2]];
            TriangleStruct rightt         = new TriangleStruct(rightbasepoint, rightpointone, rightpointtwo);
            righttriangles [i] = rightt;
        }
    }
Ejemplo n.º 9
0
    public unsafe void Compute(List <Vertex> vertices, Mesh m_OriginalMesh, TriangleList[] triangleArray, RelevanceSphere[] aRelevanceSpheres, float[] costs, int[] collapses, int[] m_aVertexPermutation, int[] m_VertexHeap, bool bUseEdgeLength, bool bUseCurvature, float bBorderCurvature, float fOriginalMeshSize)
    {
        computerHeapJob                      = new ComputeHeapJob();
        this.m_aVertexPermutation            = m_aVertexPermutation;
        this.m_VertexHeap                    = m_VertexHeap;
        computerHeapJob.UseEdgeLength        = bUseEdgeLength;
        computerHeapJob.UseCurvature         = bUseCurvature;
        computerHeapJob.fBorderCurvature     = bBorderCurvature;
        computerHeapJob.OriginalMeshSize     = fOriginalMeshSize;
        computerHeapJob.m_aVertexPermutation = new NativeArray <int>(m_aVertexPermutation, Allocator.TempJob);
        computerHeapJob.m_aVertexMap         = new NativeArray <int>(m_VertexHeap, Allocator.TempJob);
        computerHeapJob.idToHeapIndex        = new NativeArray <int>(vertices.Count, Allocator.TempJob);
        computerHeapJob.tempTriangleList     = new NativeList <int>(Allocator.TempJob);
        computerHeapJob.tmpVerticesList      = new NativeList <int>(Allocator.TempJob);
        NativeHeap <VertexStruct> minNativeHeap = NativeHeap <VertexStruct> .CreateMinHeap(vertices.Count, Allocator.TempJob);

        int intSize      = UnsafeUtility.SizeOf <int>();
        int intAlignment = UnsafeUtility.AlignOf <int>();

        //------------------------顶点数据---------------------------------
        for (int i = 0; i < vertices.Count; i++)
        {
            Vertex       v  = vertices[i];
            VertexStruct sv = new VertexStruct()
            {
                ID         = v.m_nID,
                m_fObjDist = costs[i],
                Position   = v.m_v3Position,
                collapse   = collapses[i] == -1 ? -1 : vertices[collapses[i]].m_nID,
                isBorder   = v.IsBorder() ? 1 : 0,
                Normal     = v.Normal,
                UV         = v.UV,
            };
            sv.NewVertexNeighbors(v.m_listNeighbors.Count, intSize, intAlignment, Allocator.TempJob);
            sv.NewFaceTriangle(v.m_listFaces.Count, intSize, intAlignment, Allocator.TempJob);
            sv.idToHeapIndex = computerHeapJob.idToHeapIndex;
            for (int j = 0; j < v.m_listNeighbors.Count; j++)
            {
                sv.AddNeighborVertex(v.m_listNeighbors[j].m_nID);
            }
            for (int j = 0; j < v.m_listFaces.Count; j++)
            {
                sv.AddFaceTriangle(v.m_listFaces[j].Index);
            }
            minNativeHeap.Insert(sv);
        }
        //------------------------顶点数据结束-----------------------------
        //------------------------三角形数据-------------------------------
        List <TriangleStruct> structTrangle = new List <TriangleStruct>();

        for (int n = 0; n < triangleArray.Length; n++)
        {
            List <Triangle> triangles = triangleArray[n].m_listTriangles;
            for (int i = 0; i < triangles.Count; i++)
            {
                Triangle       t  = triangles[i];
                TriangleStruct st = new TriangleStruct()
                {
                    Index     = t.Index,
                    Indices   = (int *)UnsafeUtility.Malloc(t.Indices.Length * intAlignment, intAlignment, Allocator.TempJob),
                    Normal    = t.Normal,
                    faceIndex = (int *)UnsafeUtility.Malloc(t.FaceIndex.Length * intSize, intAlignment, Allocator.TempJob),
                    vertexs   = t.Vertices.Length == 0 ? null : (int *)UnsafeUtility.Malloc(t.Vertices.Length * intSize, intAlignment, Allocator.TempJob),
                };

                for (int j = 0; j < t.Indices.Length; j++)
                {
                    st.Indices[j] = t.Indices[j];
                }
                for (int j = 0; j < t.FaceIndex.Length; j++)
                {
                    st.faceIndex[j] = t.FaceIndex[j];
                }
                for (int j = 0; j < t.Vertices.Length; j++)
                {
                    st.vertexs[j] = t.Vertices[j].m_nID;
                }
                structTrangle.Add(st);
            }
        }
        //------------------------三角形数据结束
        computerHeapJob.Spheres = new NativeArray <StructRelevanceSphere>(aRelevanceSpheres.Length, Allocator.TempJob);
        for (int i = 0; i < aRelevanceSpheres.Length; i++)
        {
            RelevanceSphere       rs  = aRelevanceSpheres[i];
            StructRelevanceSphere srs = new StructRelevanceSphere()
            {
                Transformation = Matrix4x4.TRS(rs.m_v3Position, rs.m_q4Rotation, rs.m_v3Scale),
                Relevance      = rs.m_fRelevance,
            };
            computerHeapJob.Spheres[i] = srs;
        }
        computerHeapJob.triangles = new NativeArray <TriangleStruct>(structTrangle.ToArray(), Allocator.TempJob);

        computerHeapJob.m_VertexHeap = minNativeHeap;
        handle = computerHeapJob.Schedule();
        //Debug.Log(" computerHeapJob.m_VertexHeap.Length" + computerHeapJob.m_VertexHeap.Length);
    }
Ejemplo n.º 10
0
 static bool HasVertex(TriangleStruct t, int v)
 {
     return(IndexOf(t, v) >= 0);  //>=0
 }
Ejemplo n.º 11
0
    /// <summary>
    /// 析构方法
    /// </summary>
    public void Destructor(ref NativeHeap <VertexStruct> vertexHeap, ref NativeArray <TriangleStruct> triangleArray, ref VertexStruct vold, NativeArray <int> idToHeapIndex)
    {
        //动态数组
        int i;

        for (i = 0; i < 3; i++)
        {
            if (vertexs[i] != -1)
            {
                VertexStruct v;

                if (vertexs[i] == vold.ID)
                {
                    v = vold;
                }
                else
                {
                    v = vertexHeap[idToHeapIndex[vertexs[i]]];
                }
                Pointer ptr             = v.pfaces;
                int     triangleIndices = ptr.Get <int>(v.currentFaceCount - 1);
                ptr.Set <int>(faceIndex[i], triangleIndices);
                TriangleStruct t = triangleArray[triangleIndices];
                t.faceIndex[t.IndexOf(v.ID)] = faceIndex[i];
                //修改完重新赋值
                v.RemoveAtTriangele(v.currentFaceCount - 1);     //直接修改里面的内容了
                triangleArray[triangleIndices] = t;
                v.pfaces = ptr;
                if (vertexs[i] == vold.ID)
                {
                    vold = v;
                }
                else
                {
                    vertexHeap[idToHeapIndex[vertexs[i]]] = v;
                }
            }
        }
        for (i = 0; i < 3; i++)
        {
            int i2 = (i + 1) % 3;
            if (vertexs[i] == -1 || vertexs[i2] == -1)
            {
                continue;
            }
            VertexStruct v;
            VertexStruct v2;
            int          indexI  = -1;
            int          indexI2 = -1;
            if (vertexs[i] == vold.ID)
            {
                v = vold;
            }
            else
            {
                indexI = 1;
                v      = vertexHeap[idToHeapIndex[vertexs[i]]];
            }
            if (vertexs[i2] == vold.ID)
            {
                v2 = vold;
            }
            else
            {
                indexI2 = 1;
                v2      = vertexHeap[idToHeapIndex[vertexs[i2]]];
            }
            v.RemoveIfNonNeighbor(vertexs[i2], triangleArray);
            if (indexI != -1)
            {
                vertexHeap[idToHeapIndex[vertexs[i]]] = v;
            }
            else
            {
                vold = v;
            }
            v2.RemoveIfNonNeighbor(vertexs[i], triangleArray);
            if (indexI2 != -1)
            {
                vertexHeap[idToHeapIndex[vertexs[i2]]] = v2;
            }
            else
            {
                vold = v2;
            }
        }
    }
Ejemplo n.º 12
0
    // Update is called once per frame
    void Update()
    {
        // ball is not moving
        if (velocity.x == 0 && velocity.y == 0)
        {
            sphere.transform.position = pos;
            // wait x seconds before deleting
            alivetime -= Time.deltaTime;
            if (alivetime < 0)
            {
                Destroy(gameObject);
            }
            return;
        }

        // Calculate a new position with velocity, airresistance, gravity, wind
        TriangleStruct[] lefttriangles  = mountain.lefttriangles;
        TriangleStruct[] righttriangles = mountain.righttriangles;

        float gravity   = props.GetGravity();
        float airres    = props.GetAirRes();
        float windspeed = props.GetWindforce();

        velocity = velocity + new Vector3(0, gravity, 0);

        if (velocity.x > 0)
        {
            velocity = velocity + new Vector3(-airres, 0, 0);
        }
        else
        {
            velocity = velocity + new Vector3(airres, 0, 0);
        }

        velocity = velocity + new Vector3(windspeed, 0, 0);

        Vector3 newpos = pos + velocity;

        // Collision Detection + Response

        // Check for goats
        Transform goats = goatspawner.transform;

        // Get each goat instance
        foreach (Transform goat in goats)
        {
            GoatPoints gp = (GoatPoints)goat.GetComponent("GoatPoints");

            // surround each goat by a generous sphere bounding box and check that first
            float     r = gp.radius;
            PointMass c = gp.center;
            if ((c.position - (new Vector2(pos.x, pos.y))).magnitude > r)
            {
                continue;
            }

            // Check each point in the goat for a collision
            ArrayList points = gp.points;
            for (int i = 0; i < points.Count; i++)
            {
                PointMass p = (PointMass)points [i];
                if (HitGoat(p))
                {
                    // If there is a collision, delete this ball and unanchor the goat (giving it the ball's velocity)
                    Vector2 velocity2d = new Vector2(velocity.x, velocity.y);
                    gp.Unhinge();
                    p.GiveVelocity(velocity2d);
                    Destroy(gameObject);
                }
            }
        }

        // bounding boxes for mountains
        if (pos.y - radius <= 2.0f)
        {
            // left
            if (pos.x + radius >= -5.0f && pos.x - radius <= -1.0f)
            {
                // left mountain triangles
                for (int i = 0; i < lefttriangles.Length; i++)
                {
                    TriangleStruct lefttri = lefttriangles [i];

                    if (lefttri.left == lefttri.right)
                    {
                        continue;
                    }
                    // If there is a collision, change the velocity and recursively calulate a new position (up to 'counter' times)
                    if (lefttri.SphereCollides(newpos, radius))
                    {
                        ChangeVelocity(lefttri.getNormal());
                        trycounter++;
                        Update();
                        return;
                    }
                }
            }
            // right
            if (pos.x + radius >= 1.0f && pos.x - radius <= 5.0f)
            {
                // right mountain triangles
                for (int i = 0; i < righttriangles.Length; i++)
                {
                    TriangleStruct righttri = righttriangles [i];

                    if (righttri.left == righttri.right)
                    {
                        continue;
                    }
                    if (righttri.SphereCollides(newpos, radius))
                    {
                        ChangeVelocity(righttri.getNormal());
                        trycounter++;
                        Update();
                        return;
                    }
                }
            }
            // middle
            if (pos.x + radius >= -1.0f && pos.x - radius <= 1.0f)
            {
                // top of mountain
                TriangleStruct toptriangle = mountain.toptriangle;
                if (toptriangle.SphereCollides(newpos, radius))
                {
                    ChangeVelocity(toptriangle.getNormal());
                    trycounter++;
                    Update();
                    return;
                }
            }
        }

        // Update Position
        pos = newpos;
        sphere.transform.position = pos;
        trycounter = 0;
    }
Ejemplo n.º 13
0
    // called multiple times per frame
    public bool SolveConstraints()
    {
        // Stretch or pull all points from links
        for (int i = 0; i < links.Count; i++)
        {
            PointLink currlink = (PointLink)links [i];
            currlink.Solve();
        }

        // Skip most if point is anchored (cannot change)
        if (!anchored)
        {
            // Boundary Constraints, true return deletes the goat
            if (position.y < -4f)
            {
                return(true);
            }
            if (position.y > 11f)
            {
                return(true);
            }
            if (position.x > 11f)
            {
                return(true);
            }
            if (position.x < -11f)
            {
                return(true);
            }

            // Constraints to hit mountain
            CreateMountain   mountain = (CreateMountain)gi.GetComponent("CreateMountain");
            TriangleStruct[] left     = mountain.lefttriangles;
            TriangleStruct[] right    = mountain.righttriangles;
            TriangleStruct   top      = mountain.toptriangle;

            if (position.y <= 2.0f)
            {
                // left
                if (position.x >= -5.0f && position.x <= -1.0f)
                {
                    for (int i = 0; i < left.Length; i++)
                    {
                        TriangleStruct lefttri = (TriangleStruct)left [i];
                        if (lefttri.PointInTriangle(position))
                        {
                            position = lefttri.Relocate(position);
                            if (isAnchor)
                            {
                                anchored = true;
                                anchor   = position;
                            }
                        }
                    }
                }
                // right
                else if (position.x >= 1.0f && position.x <= 5.0f)
                {
                    for (int i = 0; i < right.Length; i++)
                    {
                        TriangleStruct righttri = (TriangleStruct)right [i];
                        if (righttri.PointInTriangle(position))
                        {
                            position = righttri.Relocate(position);
                            if (isAnchor)
                            {
                                anchored = true;
                                anchor   = position;
                            }
                        }
                    }
                }
                // middle
                else if (position.x >= -1.0f && position.x <= 1.0f)
                {
                    if (top.PointInTriangle(position))
                    {
                        position = top.Relocate(position);
                        if (isAnchor)
                        {
                            anchored = true;
                            anchor   = position;
                        }
                    }
                }
            }
        }
        // pin to mountain if anchored by a foot
        if (anchored)
        {
            position = anchor;
        }
        return(false);
    }