public static Vector3 GetTriangleCenter(VertexInfo vi1, VertexInfo vi2, VertexInfo vi3, int triangleType)
        {
            Vector3 v1 = vi1.globalVertex;
            Vector3 v2 = vi2.globalVertex;
            Vector3 v3 = vi3.globalVertex;

            if (triangleType == 0)
            {
                // vi1 is upside vertex and vi2, vi3 are horizontal downside vertices
                float   z0      = vi1.height;
                float   h       = vi2.height - vi1.height;
                float   tCenter = (4 * z0 + 3 * h) / (6 * z0 + 4 * h);
                Vector3 v1ToMid = (v2 + v3) / 2f - v1;

                return(v1 + v1ToMid * tCenter);
            }
            else if (triangleType == 1)
            {
                // vi1, vi2 are horizontal upside vertices and vi3 is downside vertex
                float   z0      = vi1.height;
                float   h       = vi3.height - vi1.height;
                float   tCenter = (2 * z0 + h) / (6 * z0 + 2 * h);
                Vector3 v3ToMid = (v1 + v2) / 2f - v3;

                return(v3 + v3ToMid * tCenter);
            }
            else
            {
                return((v1 + v2 + v3) / 3f);
            }
        }
Example #2
0
        private float CuttingAlgorithmOneAbove(VertexInfo top, VertexInfo mid, VertexInfo bottom, int triangleIndex)
        {
            float submergedArea = 0f;

            float      tPointCutTB = -bottom.height / (top.height - bottom.height);
            Vector3    pointCutTB  = bottom.globalVertex + (top.globalVertex - bottom.globalVertex) * tPointCutTB;
            VertexInfo cutTB       = new VertexInfo
            {
                clockwiseOrder = -1,
                globalVertex   = pointCutTB,
                height         = WaterPatch.instance.DistanceToWater(pointCutTB, timeStamp),
            };

            float      tPointCutTM = -mid.height / (top.height - mid.height);
            Vector3    pointCutTM  = mid.globalVertex + (top.globalVertex - mid.globalVertex) * tPointCutTM;
            VertexInfo cutTM       = new VertexInfo
            {
                clockwiseOrder = -1,
                globalVertex   = pointCutTM,
                height         = WaterPatch.instance.DistanceToWater(pointCutTM, timeStamp),
            };

            if ((top.clockwiseOrder + 1) % 3 == mid.clockwiseOrder)
            {
                // downLeft: bottom, downRight: mid
                cutTB.clockwiseOrder = (mid.clockwiseOrder + 1) % 3;
                cutTM.clockwiseOrder = (cutTB.clockwiseOrder + 1) % 3;
            }
            else
            {
                // downLeft: mid, downRight: bottom
                cutTM.clockwiseOrder = (mid.clockwiseOrder + 1) % 3;
                cutTB.clockwiseOrder = (cutTM.clockwiseOrder + 1) % 3;
            }
            VertexInfo[] sortingVertices = new VertexInfo[] { mid, cutTB, cutTM };
            Array.Sort(sortingVertices);
            submergedArea += CuttingAlgorithmHorizontal(sortingVertices[0], sortingVertices[1], sortingVertices[2], triangleIndex);

            if ((top.clockwiseOrder + 1) % 3 == mid.clockwiseOrder)
            {
                // downLeft: bottom, downRight: mid
                bottom.clockwiseOrder = (mid.clockwiseOrder + 1) % 3;
                cutTB.clockwiseOrder  = (bottom.clockwiseOrder + 1) % 3;
            }
            else
            {
                // downLeft: mid, downRight: bottom
                cutTB.clockwiseOrder  = (mid.clockwiseOrder + 1) % 3;
                bottom.clockwiseOrder = (cutTB.clockwiseOrder + 1) % 3;
            }
            sortingVertices = new VertexInfo[] { mid, cutTB, bottom };
            Array.Sort(sortingVertices);
            submergedArea += CuttingAlgorithmHorizontal(sortingVertices[0], sortingVertices[1], sortingVertices[2], triangleIndex);

            return(submergedArea);
        }
Example #3
0
        private float CuttingAlgorithmTwoAbove(VertexInfo top, VertexInfo mid, VertexInfo bottom, int triangleIndex)
        {
            float      tPointCutTB = -bottom.height / (top.height - bottom.height);
            Vector3    pointCutTB  = bottom.globalVertex + (top.globalVertex - bottom.globalVertex) * tPointCutTB;
            VertexInfo cutTB       = new VertexInfo
            {
                clockwiseOrder = -1,
                globalVertex   = pointCutTB,
                height         = WaterPatch.instance.DistanceToWater(pointCutTB, timeStamp),
            };

            float      tPointCutMB = -bottom.height / (mid.height - bottom.height);
            Vector3    PointCutMB  = bottom.globalVertex + (mid.globalVertex - bottom.globalVertex) * tPointCutMB;
            VertexInfo cutMB       = new VertexInfo
            {
                clockwiseOrder = -1,
                globalVertex   = PointCutMB,
                height         = WaterPatch.instance.DistanceToWater(PointCutMB, timeStamp),
            };

            if ((top.clockwiseOrder + 1) % 3 == mid.clockwiseOrder)
            {
                // downLeft: bottom, downRight: mid
                cutTB.clockwiseOrder = (bottom.clockwiseOrder + 1) % 3;
                cutMB.clockwiseOrder = (cutTB.clockwiseOrder + 1) % 3;
            }
            else
            {
                // downLeft: mid, downRight: bottom
                cutMB.clockwiseOrder = (bottom.clockwiseOrder + 1) % 3;
                cutTB.clockwiseOrder = (cutMB.clockwiseOrder + 1) % 3;
            }

            if (cutTB.height > cutMB.height)
            {
                return(CuttingAlgorithmHorizontal(cutTB, cutMB, bottom, triangleIndex));
            }
            else
            {
                return(CuttingAlgorithmHorizontal(cutMB, cutTB, bottom, triangleIndex));
            }
        }
        public TriangleInfo(VertexInfo vi1, VertexInfo vi2, VertexInfo vi3, int triangleType, Rigidbody rB, float timeStamp)
        {
            Vector3 v1 = vi1.globalVertex;
            Vector3 v2 = vi2.globalVertex;
            Vector3 v3 = vi3.globalVertex;

            this.center = WaterInteractionUtils.GetTriangleCenter(vi1, vi2, vi3, triangleType);

            // beause of simplification. center distance can be positive in submerged triangle
            // if height is positive, don't add to force
            this.height   = WaterPatch.instance.DistanceToWater(this.center, timeStamp);
            this.normal   = Vector3.Cross(v2 - v1, v3 - v1).normalized;
            this.velocity = WaterInteractionUtils.GetTriangleVelocity(this.center, rB);
            if (this.velocity.magnitude < 0.0001f)
            {
                this.cosine = 0;
            }
            else
            {
                this.cosine = Vector3.Dot(this.velocity, this.normal) / this.velocity.magnitude;
            }
            this.area = WaterInteractionUtils.GetTriangleArea(v1, v2, v3);
        }
Example #5
0
        private float CuttingAlgorithmHorizontal(VertexInfo top, VertexInfo mid, VertexInfo bottom, int triangleIndex)
        {
            if (top.height - mid.height < epsilon)
            {
                int triangleType = (mid.height - bottom.height < epsilon) ? 2 : 1;

                TriangleInfo triangle;
                if ((top.clockwiseOrder + 1) % 3 == mid.clockwiseOrder)
                {
                    triangle = new TriangleInfo(top, mid, bottom, triangleType, Rigidbody3d, timeStamp);
                }
                else
                {
                    triangle = new TriangleInfo(mid, top, bottom, triangleType, Rigidbody3d, timeStamp);
                }

                TriangleBufferIndices.Add(triangleIndex);
                SubmergedTriangles.Add(triangle);
                return(triangle.area);
            }
            else if (mid.height - bottom.height < epsilon)
            {
                TriangleInfo triangle;
                if ((top.clockwiseOrder + 1) % 3 == mid.clockwiseOrder)
                {
                    triangle = new TriangleInfo(top, mid, bottom, 0, Rigidbody3d, timeStamp);
                }
                else
                {
                    triangle = new TriangleInfo(top, bottom, mid, 0, Rigidbody3d, timeStamp);
                }

                TriangleBufferIndices.Add(triangleIndex);
                SubmergedTriangles.Add(triangle);
                return(triangle.area);
            }

            float      tPointCutTB = (mid.height - bottom.height) / (top.height - bottom.height);
            Vector3    pointCutTB  = bottom.globalVertex + (top.globalVertex - bottom.globalVertex) * tPointCutTB;
            VertexInfo cutTB       = new VertexInfo
            {
                clockwiseOrder = -1, // no more use
                globalVertex   = pointCutTB,
                height         = WaterPatch.instance.DistanceToWater(pointCutTB, timeStamp),
            };

            TriangleInfo upside, downside;

            if ((top.clockwiseOrder + 1) % 3 == mid.clockwiseOrder)
            {
                // downLeft: bottom, downRight: mid
                upside   = new TriangleInfo(top, mid, cutTB, 0, Rigidbody3d, timeStamp);
                downside = new TriangleInfo(cutTB, mid, bottom, 1, Rigidbody3d, timeStamp);
            }
            else
            {
                // downLeft: mid, downRight: bottom
                upside   = new TriangleInfo(top, cutTB, mid, 0, Rigidbody3d, timeStamp);
                downside = new TriangleInfo(mid, cutTB, bottom, 1, Rigidbody3d, timeStamp);
            }

            TriangleBufferIndices.Add(triangleIndex);
            TriangleBufferIndices.Add(triangleIndex);
            SubmergedTriangles.Add(upside);
            SubmergedTriangles.Add(downside);

            return(upside.area + downside.area);
        }