Example #1
0
        /// <summary>
        /// 半球防空区域
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="radius"></param>
        /// <param name="angle">默认为半球,通过修改角度可以修改球的缺省</param>
        /// <param name="meshFilter"></param>
        public static void DrawHemisphere(Vector3 pos, float radius, MeshFilter meshFilter, int angle = 90)
        {
            meshFilter.mesh.vertices  = PhysicsMath.GetVertices(pos, radius, angle);   // 圆球形
            meshFilter.mesh.triangles = PhysicsMath.Sort3(angle);

            meshFilter.mesh.RecalculateBounds();     // 重置范围
            meshFilter.mesh.RecalculateNormals();    // 重置法线
            meshFilter.mesh.RecalculateTangents();   // 重置切线
        }
Example #2
0
        public EllipseGraphic(Vector2 center, Vector2 radius)
        {
            var points = PhysicsMath.GetEllipsePoints(radius.x, radius.y, center, 60);

            m_Poses = new List <Vector3>();
            foreach (var item in points)
            {
                m_Poses.Add(item);
            }
        }
Example #3
0
        /// <summary>
        /// 创建通用多边形区域
        /// </summary>
        /// <param name="id"> 命令ID,用作字典key </param>
        /// <param name="list">下底面点链表</param>
        /// <param name="height">高度</param>
        public void CreatePolygon(List <Vector3> list, float height, Color color)
        {
            Vector3[] vector3s = PhysicsMath.CheckVector(list);                         // 使数组逆时针排序
            Mesh      mesh     = GLDraw.CreatePolygon(vector3s, height, color.Int32()); // 画出图形

            Game.GraphicsModule.AddGraphics(Camera.main, () =>
            {
                ShapeMaterial.SetPass(0);
                Graphics.DrawMeshNow(mesh, Matrix4x4.identity);
            });
        }
Example #4
0
        /// <summary>
        /// 创建扇形防空区
        /// </summary>
        /// <param name="id"> 命令ID,用作字典key </param>
        /// <param name="origin">起始点</param>
        /// <param name="tarPoint">水平最远距离点</param>
        /// <param name="alpha">横向张角</param>
        /// <param name="theta">纵向张角</param>
        public void CreateSector(Vector3 origin, Vector3 tarPoint, float alpha, float theta, Color color)
        {
            Vector3[] vertices = PhysicsMath.GetSectorPoints_2(origin, tarPoint, alpha, theta);
            Mesh      mesh     = GLDraw.CreatePolygon(vertices, color.Int32());

            Game.GraphicsModule.AddGraphics(Camera.main, () =>
            {
                ShapeMaterial.SetPass(0);
                Graphics.DrawMeshNow(mesh, Matrix4x4.identity);
            });
        }
Example #5
0
        /// <summary>
        /// 创建通用多边形区域
        /// </summary>
        /// <param name="id"> 命令ID,用作字典key </param>
        /// <param name="list">下底面点链表</param>
        /// <param name="height">高度</param>
        public void CreatePolygon(int id, List <Vector3> list, float height, Color Fillcolor, Color BoradColor)
        {
            LineRenderer[]    lineRenderers = new LineRenderer[4];
            List <GameObject> meshList      = GetMeshPrefab(lineRenderers, 1);              // 获取mesh

            meshDic.Add(id, meshList);                                                      // 加入字典
            MeshFilter meshFilter = meshList[0].GetComponent <MeshFilter>();                // 获取meshfilter

            meshList[0].GetComponent <MeshRenderer>().material.color = Fillcolor;

            Vector3[] vector3s = PhysicsMath.CheckVector(list);                                 // 使数组逆时针排序
            DrawTriangles.DrawPolygon(vector3s, height, meshFilter, lineRenderers, BoradColor); // 画出图形
        }
Example #6
0
        /// <summary>
        /// 创建扇形防空区
        /// </summary>
        /// <param name="id"> 命令ID,用作字典key </param>
        /// <param name="origin">起始点</param>
        /// <param name="tarPoint">水平最远距离点</param>
        /// <param name="alpha">横向张角</param>
        /// <param name="theta">纵向张角</param>
        public void CreateSector(int id, Vector3 origin, Vector3 tarPoint, float alpha, float theta, Color Fillcolor, Color BoradColor)
        {
            LineRenderer[]    lineRenderers = new LineRenderer[4];
            List <GameObject> meshList      = GetMeshPrefab(lineRenderers, 1);

            meshDic.Add(id, meshList);
            MeshFilter meshFilter = meshList[0].GetComponent <MeshFilter>();

            meshList[0].GetComponent <MeshRenderer>().material.color = Fillcolor;

            Vector3[] vertices = PhysicsMath.GetSectorPoints_2(origin, tarPoint, alpha, theta);
            DrawTriangles.DrawPolygon(vertices, meshFilter, lineRenderers, BoradColor);
        }
Example #7
0
        public Dictionary <int, List <GameObject> > meshDic = new Dictionary <int, List <GameObject> >();     // 命令与mesh对应字典

        /// <summary>
        /// 创建圆柱形区域
        /// </summary>
        /// <param name="id"> 命令ID,用作字典key </param>
        /// <param name="point"> 圆心点 </param>
        /// <param name="radius"> 半径 </param>
        /// <param name="height"> 高度 </param>
        public void CreateCylinder(int id, Vector3 point, float radius, float height, Color Fillcolor, Color BoradColor)
        {
            LineRenderer[]    lineRenderers = new LineRenderer[4];
            List <GameObject> meshList      = GetMeshPrefab(lineRenderers, 1);          // 获取mesh

            meshDic.Add(id, meshList);                                                  // 加入字典
            MeshFilter meshFilter = meshList[0].GetComponent <MeshFilter>();            // 获取meshfilter

            meshList[0].GetComponent <MeshRenderer>().material.color = Fillcolor;

            Vector3[] vertices = PhysicsMath.GetCirclePoints(point, radius);                     // 获取点集
            DrawTriangles.DrawCylinder(vertices, height, meshFilter, lineRenderers, BoradColor); // 画出图形
        }
Example #8
0
        public BezierGraphic(Vector3[] originPoints, uint[] segTypes)
        {
            List <Vector3> points = new List <Vector3>();
            int            index  = 0;

            for (int i = 0; i < segTypes.Length; i++)
            {
                switch (segTypes[i])
                {
                case 0:         // 直线,只取2个点
                    AddifNotContain(points, new List <Vector3>()
                    {
                        originPoints[index++], originPoints[index]
                    });
                    break;

                case 1:         // 二次贝塞尔, 取3个点
                    Vector3[] bezier2 = new Vector3[3];
                    bezier2[0] = originPoints[index++];
                    bezier2[1] = originPoints[index++];
                    bezier2[2] = originPoints[index];
                    AddifNotContain(points, PhysicsMath.GetBezierList(bezier2));
                    break;

                case 2:         // 三次贝塞尔, 取4个点
                    Vector3[] bezier3 = new Vector3[4];
                    bezier3[0] = originPoints[index++];
                    bezier3[1] = originPoints[index++];
                    bezier3[2] = originPoints[index++];
                    bezier3[3] = originPoints[index];
                    AddifNotContain(points, PhysicsMath.GetBezierList(bezier3));
                    break;

                default:
                    break;
                }
            }

            m_Poses = points;

            void AddifNotContain(List <Vector3> _drawPath, List <Vector3> _pointsAdd)
            {
                if (_drawPath.Count > 0 && _drawPath.End() == _pointsAdd[0])
                {
                    _pointsAdd.RemoveAt(0);
                }
                _drawPath.AddRange(_pointsAdd);
            }       // 内部函数, 去重添加
        }
Example #9
0
        /// <summary>
        /// 创建空中走廊
        /// </summary>
        /// <param name="id"> 命令ID,用作字典key </param>
        /// <param name="list">中心点链表</param>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        public void CreateAirCorridorSpace(int id, List <Vector3> list, float width, float height, Color Fillcolor)
        {
            LineRenderer[]    lineRenderers = new LineRenderer[4];
            List <GameObject> meshList      = GetMeshPrefab(lineRenderers, 1);              // 获取mesh

            meshDic.Add(id, meshList);                                                      // 加入字典
            MeshFilter meshFilter = meshList[0].GetComponent <MeshFilter>();                // 获取meshfilter

            meshList[0].GetComponent <MeshRenderer>().material.color = Fillcolor;

            //Vector3[] vertices = PhysicsMath.GetAirCorridorSpace(list, width, height);       // 获取点集
            //DrawTriangles.DrawAirCorridorSpace(vertices, meshFilter, lineRenderers);        // 画出图形

            Vector3[] bottomPoints = PhysicsMath.GetAirSpaceBottomPoints(list, width, height);
            Vector3[] vertices     = PhysicsMath.GetAirBottomSpaceWithSector(bottomPoints.ToList(), width);

            DrawTriangles.GetAirSpaceWithSector(vertices.ToList(), width, height, list.Count - 1, meshFilter);
        }
Example #10
0
        /// <summary>
        /// 画数据折线
        /// </summary>
        private void DrawLine(VertexHelper vh)
        {
            foreach (var data in datas)
            {
                Vector2[] pixelPoints = new Vector2[data.Length];
                for (int i = 0; i < data.Length; i++)
                {
                    pixelPoints[i].x = (data[i].x - axleMinValue.x) / axleMaxValue.x * width;
                    pixelPoints[i].y = (data[i].y - axleMinValue.y) / axleMaxValue.y * height;
                    pixelPoints[i]  += offset;
                }

                UIVertex[] verts = new UIVertex[4];
                for (int i = 0; i < verts.Length; i++)
                {
                    verts[i].color = lineColor;
                }

                for (int i = 0; i < pixelPoints.Length - 1; i++)
                {
                    SetVerts(pixelPoints[i], pixelPoints[i + 1], lineWidth, verts);
                    vh.AddUIVertexQuad(verts);
                }

                // 点状数据
                //foreach (var item in pixelPoints)
                //{
                //    verts[0].position = item;
                //    verts[1].position = new Vector2(5, 0) + item;
                //    verts[2].position = new Vector2(5, 5) + item;
                //    verts[3].position = new Vector2(0, 5) + item;
                //    vh.AddUIVertexQuad(verts);
                //}

                void SetVerts(Vector2 _start, Vector2 _end, float _width, UIVertex[] _verts)
                {
                    Vector2[] tmp = PhysicsMath.GetRect(_start, _end, _width);
                    _verts[0].position = tmp[0];
                    _verts[1].position = tmp[1];
                    _verts[2].position = tmp[3];
                    _verts[3].position = tmp[2];
                }
            }
        }
Example #11
0
        protected override void OnUpdate()
        {
            Entities.ForEach((UnityEngine.BoxCollider2D collider) =>
            {
                // Convert the collider if it's valid.
                if (ConversionUtilities.CanConvertCollider(collider))
                {
                    try
                    {
                        var lossyScale = new float3(collider.transform.lossyScale).xy;
                        if (math.any(!math.isfinite(lossyScale)) || math.any(lossyScale <= 0.0f))
                        {
                            throw new ArgumentException("Transform XY scale cannot be zero or Infinite/NaN.", "Transform XY scale.");
                        }

                        var localToWorld = ConversionUtilities.GetColliderLocalToWorld(collider);
                        var size         = collider.size;

                        var geometry = new BoxGeometry
                        {
                            Center      = new float3(localToWorld.MultiplyPoint(collider.offset)).xy,
                            Size        = new float2(size.x * lossyScale.x, size.y * lossyScale.y),
                            Angle       = PhysicsMath.ZRotationFromQuaternion(localToWorld.rotation),
                            BevelRadius = math.max(collider.edgeRadius, PhysicsSettings.Constants.MinimumConvexRadius),
                        };

                        geometry.Validate();

                        var colliderBlob = PhysicsBoxCollider.Create(
                            geometry,
                            ConversionUtilities.GetCollisionFilterFromCollider(collider),
                            ConversionUtilities.GetPhysicsMaterialFromCollider(collider)
                            );

                        // Submit the collider for conversion.
                        m_ColliderConversionSystem.SubmitCollider(collider, ref colliderBlob);
                    }
                    catch (ArgumentException exception)
                    {
                        UnityEngine.Debug.LogWarning($"{collider.name}: {exception.Message}", collider);
                    }
                }
            });
        }
Example #12
0
        // Get collider local to world as defined relative to any attached Rigidbody2D.
        public static Matrix4x4 GetColliderLocalToWorld(Collider2D collider)
        {
            // If no attached rigidbody or we're attached to a rigidbody but it's on the same GameObject
            // then we simply use identity as the relative transform.
            var attachedRigidbody = collider.attachedRigidbody;

            if (attachedRigidbody == null || attachedRigidbody.gameObject == collider.gameObject)
            {
                return(Matrix4x4.identity);
            }

            // Calculate relative to the attached rigidbody.
            var rigidbodyTransform  = attachedRigidbody.transform;
            var bodyInverseRotation = Quaternion.Inverse(PhysicsMath.ZQuaternionFromQuaternion(rigidbodyTransform.rotation));
            var bodyInversePosition = bodyInverseRotation * -rigidbodyTransform.position;
            var localToWorld        = collider.transform.localToWorldMatrix;

            return(Matrix4x4.TRS(bodyInversePosition, bodyInverseRotation, Vector3.one) * localToWorld);
        }
Example #13
0
        public override void GetVertexs(ref List <UIVertex> vertexs)
        {
            if (m_Poses.Count < 2)
            {
                return;
            }

            int     count = m_Poses.Count;
            Vector2 dir   = PhysicsMath.GetHorizontalDir((m_Poses[1] - m_Poses[0]).XY());

            vertexs.Add(new UIVertex()
            {
                position = m_Poses[0].XY() - dir * width, color = color,
            });
            vertexs.Add(new UIVertex()
            {
                position = m_Poses[0].XY() + dir * width, color = color,
            });


            for (int i = 1; i < count - 1; i++)
            {
                dir = PhysicsMath.GetHorizontalDir((m_Poses[i + 1] - m_Poses[i - 1]).XY());
                vertexs.Add(new UIVertex()
                {
                    position = m_Poses[i].XY() - dir * width, color = color,
                });
                vertexs.Add(new UIVertex()
                {
                    position = m_Poses[i].XY() + dir * width, color = color
                });
            }

            dir = PhysicsMath.GetHorizontalDir((m_Poses[count - 1] - m_Poses[count - 2]).XY());
            vertexs.Add(new UIVertex()
            {
                position = m_Poses[count - 1].XY() - dir * width, color = color,
            });
            vertexs.Add(new UIVertex()
            {
                position = m_Poses[count - 1].XY() + dir * width, color = color,
            });
        }
 protected Vector2 CollisionCheck(Vector3 position, Vector2 force)
 {
     if (security > 25)
     {
         return(force);
     }
     boxRaycast = Physics2D.BoxCast(position, collisionBox.bounds.size, 0.0f, force.normalized, Mathf.Infinity, collisionMask);
     security++;
     if (boxRaycast.collider != null)
     {
         if (boxRaycast.distance > force.magnitude * Time.deltaTime)
         {
             return(force);
         }
         if (boxRaycast.transform.tag == "MoveableObj")
         {
             force += boxRaycast.normal * Time.deltaTime;
         }
         Vector2 normalHit = boxRaycast.normal;
         float   angle     = Mathf.Abs((Vector2.Angle(normalHit, force.normalized) - 90) * Mathf.Deg2Rad);
         if (Mathf.Approximately(Mathf.Sin(angle), 0))
         {
             return(force);
         }
         float range = skinWidth / Mathf.Sin(angle);
         if (boxRaycast.distance - range > 0)
         {
             Vector2 snap = force.normalized * (boxRaycast.distance - range);
             // snap = Vector2.ClampMagnitude(snap, force.magnitude * Time.deltaTime);
             position  += (Vector3)snap;
             totalSnap += (Vector3)snap;
         }
         Vector2 normalForce = PhysicsMath.NormalizeForce2D(force, normalHit);
         force += normalForce;
         force  = ApplicationOfFriction(normalForce.magnitude, force, staticFriction);
         force  = CollisionCheck(position, force);
     }
     return(force);
 }
Example #15
0
            public unsafe void Draw()
            {
                if (VertexCount < 3)
                {
                    return;
                }

                BeginLineStrip(Color);

                fixed(byte *array = Vertices)
                {
                    float2 *vertexArray = (float2 *)array;

                    for (var i = 0; i < VertexCount; ++i)
                    {
                        var vertex = PhysicsMath.mul(Transform, vertexArray[i]);
                        DrawLineVertex(vertex);
                    }
                    DrawLineVertex(PhysicsMath.mul(Transform, vertexArray[0]));
                }

                EndDraw();
            }
Example #16
0
        private static unsafe void DrawComposite(
            Collider *collider,
            ref PhysicsTransform worldTransform,
            ref PhysicsDebugStreamSystem.Context outputStream,
            Color colliderColor)
        {
            switch (collider->ColliderType)
            {
            case ColliderType.Compound:
            {
                var compoundCollider = (PhysicsCompoundCollider *)collider;
                var children         = compoundCollider->Children;

                for (var i = 0; i < children.Length; ++i)
                {
                    ref PhysicsCompoundCollider.Child child = ref children[i];

                    var colliderWorldTransform = PhysicsMath.mul(worldTransform, child.CompoundFromChild);
                    DrawCollider(children[i].Collider, ref colliderWorldTransform, ref outputStream, colliderColor);
                }

                return;
            }
            }
Example #17
0
        /// <summary>
        /// 创建紫色杀伤盒
        /// </summary>
        /// <param name="id"> 命令ID,用作字典key </param>
        /// <param name="list">底面四点链表</param>
        /// <param name="lower">下限高度</param>
        /// <param name="Ceiling">上限高度</param>
        public void CreateKillBox(List <Vector3> list, float lower, float Ceiling, Color color)
        {
            // 第一个杀伤盒
            Vector3[] vector3s1 = PhysicsMath.CheckVector(list);                              // 使数组逆时针排序
            Mesh      mesh0     = GLDraw.CreatePolygon(vector3s1, lower, color.Int32());      // 画出图形

            // 第二个杀伤盒
            List <Vector3> CeilingList = new List <Vector3>();   // 中层顶点集合

            foreach (var item in list)
            {
                CeilingList.Add(item + Vector3.up * lower);
            }

            Vector3[] vector3s2 = PhysicsMath.CheckVector(CeilingList);                            // 使数组逆时针排序
            Mesh      mesh1     = GLDraw.CreatePolygon(vector3s2, Ceiling - lower, color.Int32()); // 画出图形

            Game.GraphicsModule.AddGraphics(Camera.main, () =>
            {
                ShapeMaterial.SetPass(0);
                Graphics.DrawMeshNow(mesh0, Matrix4x4.identity);
                Graphics.DrawMeshNow(mesh1, Matrix4x4.identity);
            });
        }
Example #18
0
        public void MassProperties_BuiltFromChildren_MatchesExpected()
        {
            void TestCompoundBox(PhysicsTransform transform)
            {
                // Create a unit box
                var boxCollider = PhysicsBoxCollider.Create(new BoxGeometry
                {
                    Size        = new float2(1f),
                    Center      = transform.Translation,
                    Angle       = 0f,
                    BevelRadius = 0.0f
                });

                // Create a compound of mini boxes, matching the volume of the single box
                var miniBox = PhysicsBoxCollider.Create(new BoxGeometry
                {
                    Size        = new float2(0.5f),
                    Center      = float2.zero,
                    Angle       = 0f,
                    BevelRadius = 0.0f
                });

                const uint UserData      = 0xDEADBEEF;
                const int  ChildrenCount = 4;

                var childrenTransforms = new NativeArray <PhysicsTransform>(ChildrenCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory)
                {
                    [0] = new PhysicsTransform(new float2(-0.25f, -0.25f), float2x2.identity),
                    [1] = new PhysicsTransform(new float2(0.25f, -0.25f), float2x2.identity),
                    [2] = new PhysicsTransform(new float2(0.25f, 0.25f), float2x2.identity),
                    [3] = new PhysicsTransform(new float2(-0.25f, 0.25f), float2x2.identity),
                };

                var children = new NativeArray <PhysicsCompoundCollider.ColliderBlobInstance>(ChildrenCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

                for (var i = 0; i < ChildrenCount; ++i)
                {
                    children[i] = new PhysicsCompoundCollider.ColliderBlobInstance
                    {
                        Collider          = miniBox,
                        CompoundFromChild = PhysicsMath.mul(transform, childrenTransforms[i])
                    };
                }

                var colliderBlob = PhysicsCompoundCollider.Create(children, UserData);

                childrenTransforms.Dispose();
                children.Dispose();

                ref var collider = ref colliderBlob.GetColliderRef <PhysicsCompoundCollider>();

                Assert.AreEqual(ColliderType.Compound, collider.ColliderType);
                Assert.AreEqual(CollisionType.Composite, collider.CollisionType);
                Assert.AreEqual(UserData, collider.UserData);

                var boxMassProperties      = boxCollider.Value.MassProperties;
                var compoundMassProperties = colliderBlob.Value.MassProperties;

                Assert.AreEqual(boxMassProperties.Area, compoundMassProperties.Area, 1e-3f, "Area incorrect.");
                Assert.AreEqual(boxMassProperties.AngularExpansionFactor, compoundMassProperties.AngularExpansionFactor, 1e-3f, "AngularExpansionFactor incorrect.");
                PhysicsAssert.AreEqual(boxMassProperties.MassDistribution.LocalCenterOfMass, compoundMassProperties.MassDistribution.LocalCenterOfMass, 1e-3f, "LocalCenterOfMass incorrect.");
                Assert.AreEqual(boxMassProperties.MassDistribution.InverseInertia, compoundMassProperties.MassDistribution.InverseInertia, 1e-3f, "InverseInertia incorrect.");

                boxCollider.Dispose();
                colliderBlob.Dispose();
            }
Example #19
0
    /// <summary>
    /// 根据传参 路径点信息 创建路面:
    /// 0 --- 2
    /// |     |
    /// 1 --- 3
    /// </summary>
    /// <param name="meshFilter">路面网格</param>
    /// <param name="_roadPoints">路点</param>
    /// <param name="_width">路面宽度</param>
    public static void CreateRoads(Terrain terrain, MeshFilter meshFilter, List <Vector3> wayPoints, float _width = 5)
    {
        if (wayPoints.Count < 2)
        {
            return;                                                                 // 路点数量不能低于2个
        }
        List <Vector3> _roadPoints = wayPoints;                                     // 取出路径点

        List <Vector3> vertice   = new List <Vector3>();                            // 顶点
        List <int>     triangles = new List <int>();                                // 三角形排序
        List <Vector2> uv        = new List <Vector2>();                            // uv排序

        Vector3 dir = PhysicsMath.GetHorizontalDir(_roadPoints[1], _roadPoints[0]); // 获取两点间的垂直向量

        vertice.Add(_roadPoints[0] + dir * _width);                                 // 添加初始顶点
        vertice.Add(_roadPoints[0] - dir * _width);

        uv.Add(Vector2.zero);                           // 添加初始顶点对应uv
        uv.Add(Vector2.right);

        for (int i = 1, count = _roadPoints.Count; i < count; i++)
        {
            // 添加由 路径点 生成的路面点集
            dir = PhysicsMath.GetHorizontalDir(_roadPoints[i], _roadPoints[i - 1]);
            vertice.Add(_roadPoints[i] + dir * _width);
            vertice.Add(_roadPoints[i] - dir * _width);

            // 添加三jio形排序
            triangles.Add(2 * i - 2);
            triangles.Add(2 * i);
            triangles.Add(2 * i - 1);

            triangles.Add(2 * i);
            triangles.Add(2 * i + 1);
            triangles.Add(2 * i - 1);

            // 添加uv排序
            if (i % 2 == 1)
            {
                uv.Add(Vector2.up);
                uv.Add(Vector2.one);
            }
            else
            {
                uv.Add(Vector2.zero);
                uv.Add(Vector2.right);
            }
        }

        List <float> roadHeights = PointsFitToTerrain(terrain, ref vertice);                     // 路面高度适配地形

        //TerrainUtility.ChangeHeights(terrain, _roadPoints.ToArray(), roadHeights.ToArray());    // 将道路整平

        meshFilter.mesh.Clear();
        meshFilter.mesh.vertices  = vertice.ToArray();
        meshFilter.mesh.triangles = triangles.ToArray();
        meshFilter.mesh.uv        = uv.ToArray();

        meshFilter.mesh.RecalculateBounds();     // 重置范围
        meshFilter.mesh.RecalculateNormals();    // 重置法线
        meshFilter.mesh.RecalculateTangents();   // 重置切线
    }
Example #20
0
        /// <summary>
        /// 圆柱
        /// </summary>
        public static Mesh CreateCylinder(Vector3 buttomOrigin, float radius, float height, int colorInt = ColorInt32.white)
        {
            Vector3[] buttomSurface = PhysicsMath.GetCirclePoints(buttomOrigin, radius);

            List <Vector3> verticesDown = new List <Vector3>();
            List <Vector3> verticesUp   = new List <Vector3>();
            List <Vector3> vertices     = new List <Vector3>();

            List <int> triangles = new List <int>();

            //上下面坐标赋值 数组转List
            for (int i = 0; i < buttomSurface.Length; i++)
            {
                verticesDown.Add(buttomSurface[i]);
            }
            for (int i = 0; i < buttomSurface.Length; i++)
            {
                verticesUp.Add(buttomSurface[i] + new Vector3(0, height, 0));
            }
            //计算一个平面的点数量
            int count = verticesDown.Count;

            //将上下平面点合并
            for (int i = 0; i < verticesDown.Count; i++)
            {
                vertices.Add(verticesDown[i]);
            }
            for (int i = 0; i < verticesUp.Count; i++)
            {
                vertices.Add(verticesUp[i]);
            }

            //获取底面和顶面的三角形排序
            List <int> trianglesDown = PhysicsMath.DrawPolygon(verticesDown, false);
            List <int> trianglesUp   = PhysicsMath.DrawPolygon(verticesUp, true);

            for (int i = 0; i < trianglesDown.Count; i++)
            {
                trianglesUp[i] += count;
            }

            //合并底面顶面三角形排序
            for (int i = 0; i < trianglesDown.Count; i++)
            {
                triangles.Add(trianglesDown[i]);
            }
            for (int i = 0; i < trianglesUp.Count; i++)
            {
                triangles.Add(trianglesUp[i]);
            }

            //侧面三角形排序
            for (int i = 0; i < count - 1; i++)
            {
                // 加上侧面的点集
                vertices.Add(vertices[i]);
                vertices.Add(vertices[i + 1]);
                vertices.Add(vertices[i + count + 1]);
                vertices.Add(vertices[i + count]);

                // 侧面三角形排序
                triangles.Add(2 * count + 1 + i * 4);
                triangles.Add(2 * count + 0 + i * 4);
                triangles.Add(2 * count + 3 + i * 4);
                triangles.Add(2 * count + 1 + i * 4);
                triangles.Add(2 * count + 3 + i * 4);
                triangles.Add(2 * count + 2 + i * 4);
            }

            // 加上最后一个侧面的点集
            vertices.Add(vertices[count - 1]);
            vertices.Add(vertices[0]);
            vertices.Add(vertices[count]);
            vertices.Add(vertices[2 * count - 1]);

            // 加上最后一个侧面的三角形排序
            triangles.Add(vertices.Count - 3);
            triangles.Add(vertices.Count - 4);
            triangles.Add(vertices.Count - 1);
            triangles.Add(vertices.Count - 3);
            triangles.Add(vertices.Count - 1);
            triangles.Add(vertices.Count - 2);

            Color[] colors = new Color[vertices.Count];
            Color   color  = colorInt.Color();

            for (int i = 0; i < colors.Length; ++i)
            {
                colors[i] = color;
            }

            Mesh mesh = new Mesh
            {
                name      = "Cylinder",
                vertices  = vertices.ToArray(),
                triangles = triangles.ToArray(),
                colors    = colors,
            };

            mesh.RecalculateBounds();     // 重置范围
            mesh.RecalculateNormals();    // 重置法线
            mesh.RecalculateTangents();   // 重置切线

            return(mesh);
        }
Example #21
0
        static unsafe bool CastCollider(
            Ray ray, ref float2x2 rotation,
            ref DistanceProxy proxySource, ref DistanceProxy proxyTarget,
            out ColliderCastHit hit)
        {
            hit = default;

            var transformSource = new PhysicsTransform
            {
                Translation = ray.Origin,
                Rotation    = rotation
            };

            // Check we're not initially overlapped.
            if ((proxySource.VertexCount < 3 || proxyTarget.VertexCount < 3) &&
                OverlapQueries.OverlapConvexConvex(ref transformSource, ref proxySource, ref proxyTarget))
            {
                return(false);
            }

            // B = Source
            // A = Target

            var radiusSource = proxySource.ConvexRadius;
            var radiusTarget = proxyTarget.ConvexRadius;
            var totalRadius  = radiusSource + radiusTarget;

            var invRotation = math.inverse(rotation);

            var sweepDirection = ray.Displacement;
            var normal         = float2.zero;
            var lambda         = 0.0f;

            // Initialize the simplex.
            var simplex = new Simplex();

            simplex.Count = 0;
            var vertices = &simplex.Vertex1;

            // Get a support point in the inverse direction.
            var indexTarget   = proxyTarget.GetSupport(-sweepDirection);
            var supportTarget = proxyTarget.Vertices[indexTarget];
            var indexSource   = proxySource.GetSupport(PhysicsMath.mul(invRotation, sweepDirection));
            var supportSource = PhysicsMath.mul(transformSource, proxySource.Vertices[indexSource]);
            var v             = supportTarget - supportSource;

            // Sigma is the target distance between polygons
            var         sigma     = math.max(PhysicsSettings.Constants.MinimumConvexRadius, totalRadius - PhysicsSettings.Constants.MinimumConvexRadius);
            const float tolerance = PhysicsSettings.Constants.LinearSlop * 0.5f;

            var iteration = 0;

            while (
                iteration++ < PhysicsSettings.Constants.MaxGJKInterations &&
                math.abs(math.length(v) - sigma) > tolerance
                )
            {
                if (simplex.Count >= 3)
                {
                    SafetyChecks.ThrowInvalidOperationException("ColliderCast Simplex must have less than 3 vertex.");
                }

                // Support in direction -supportV (Target - Source)
                indexTarget   = proxyTarget.GetSupport(-v);
                supportTarget = proxyTarget.Vertices[indexTarget];
                indexSource   = proxySource.GetSupport(PhysicsMath.mul(invRotation, v));
                supportSource = PhysicsMath.mul(transformSource, proxySource.Vertices[indexSource]);
                var p = supportTarget - supportSource;

                v = math.normalizesafe(v);

                // Intersect ray with plane.
                var vp = math.dot(v, p);
                var vr = math.dot(v, sweepDirection);
                if (vp - sigma > lambda * vr)
                {
                    if (vr <= 0.0f)
                    {
                        return(false);
                    }

                    lambda = (vp - sigma) / vr;
                    if (lambda > 1.0f)
                    {
                        return(false);
                    }

                    normal        = -v;
                    simplex.Count = 0;
                }

                // Reverse simplex since it works with B - A.
                // Shift by lambda * r because we want the closest point to the current clip point.
                // Note that the support point p is not shifted because we want the plane equation
                // to be formed in un-shifted space.
                var vertex = vertices + simplex.Count;
                vertex->IndexA   = indexSource;
                vertex->SupportA = supportSource + lambda * sweepDirection;
                vertex->IndexB   = indexTarget;
                vertex->SupportB = supportTarget;
                vertex->W        = vertex->SupportB - vertex->SupportA;
                vertex->A        = 1.0f;
                simplex.Count   += 1;

                switch (simplex.Count)
                {
                case 1:
                    break;

                case 2:
                    simplex.Solve2();
                    break;

                case 3:
                    simplex.Solve3();
                    break;

                default:
                    SafetyChecks.ThrowInvalidOperationException("Simplex has invalid count.");
                    return(default);
                }

                // If we have 3 points, then the origin is in the corresponding triangle.
                if (simplex.Count == 3)
                {
                    // Overlap.
                    return(false);
                }

                // Get search direction.
                v = simplex.GetClosestPoint();
            }

            // Ensure we don't process an empty simplex.
            if (simplex.Count == 0)
            {
                return(false);
            }

            // Prepare result.
            var pointSource = float2.zero;
            var pointTarget = float2.zero;

            simplex.GetWitnessPoints(ref pointSource, ref pointTarget);

            normal = math.normalizesafe(-v);

            hit = new ColliderCastHit
            {
                Position      = pointTarget + (normal * radiusTarget),
                SurfaceNormal = normal,
                Fraction      = lambda
            };

            return(true);
        }
Example #22
0
        /// <summary>
        /// 立体线,可用于画空中走廊
        /// </summary>
        /// <param name="positions">空中走廊所有顶点</param>
        public static Mesh CreateLineMesh_Old(Vector3[] vertexs, float width, float height, int colorInt = ColorInt32.white)
        {
            Vector3[] positions = PhysicsMath.GetAirCorridorSpace(vertexs.ToList(), width, height);       // 获取点集

            List <Vector3> vertices = new List <Vector3>();
            List <int>     trangles = new List <int>();
            int            count    = positions.Length - 4;

            // 左侧面
            vertices.Add(positions[0]);
            vertices.Add(positions[1]);
            vertices.Add(positions[2]);
            vertices.Add(positions[3]);
            trangles.Add(3);
            trangles.Add(1);
            trangles.Add(0);
            trangles.Add(3);
            trangles.Add(2);
            trangles.Add(1);



            // 走廊框体
            for (int i = 0; i < count; i++)
            {
                if (i % 4 == 3)
                {
                    vertices.Add(positions[i]);
                    vertices.Add(positions[i - 3]);
                    vertices.Add(positions[i + 1]);
                    vertices.Add(positions[i + 4]);
                }
                else
                {
                    vertices.Add(positions[i]);
                    vertices.Add(positions[i + 1]);
                    vertices.Add(positions[i + 5]);
                    vertices.Add(positions[i + 4]);
                }

                trangles.Add((i + 1) * 4);
                trangles.Add((i + 1) * 4 + 2);
                trangles.Add((i + 1) * 4 + 3);
                trangles.Add((i + 1) * 4);
                trangles.Add((i + 1) * 4 + 1);
                trangles.Add((i + 1) * 4 + 2);
            }

            // 右侧面
            vertices.Add(positions[count]);
            vertices.Add(positions[count + 1]);
            vertices.Add(positions[count + 2]);
            vertices.Add(positions[count + 3]);
            trangles.Add(vertices.Count - 4);
            trangles.Add(vertices.Count - 2);
            trangles.Add(vertices.Count - 1);
            trangles.Add(vertices.Count - 4);
            trangles.Add(vertices.Count - 3);
            trangles.Add(vertices.Count - 2);

            Color[] colors = new Color[vertices.Count];
            Color   color  = colorInt.Color();

            for (int i = 0; i < colors.Length; ++i)
            {
                colors[i] = color;
            }

            Mesh mesh = new Mesh
            {
                name      = "Line",
                vertices  = vertices.ToArray(),
                triangles = trangles.ToArray(),
                colors    = colors,
            };

            mesh.RecalculateBounds();     // 重置范围
            mesh.RecalculateNormals();    // 重置法线
            mesh.RecalculateTangents();   // 重置切线

            return(mesh);
        }
Example #23
0
        /// <summary>
        /// 凹/凸多边形空域 每个点高度不一样时 可以用来画扇形区域
        /// </summary>
        /// <param name="positions"></param>
        public static Mesh CreatePolygon(Vector3[] positions, int colorInt = ColorInt32.white)
        {
            List <Vector3> verticesDown = new List <Vector3>();
            List <Vector3> verticesUp   = new List <Vector3>();
            List <Vector3> vertices     = new List <Vector3>();

            List <int> triangles = new List <int>();

            //上下面坐标赋值 数组转List
            for (int i = 0; i < positions.Length / 2; i++)
            {
                verticesDown.Add(positions[i]);
            }
            for (int i = positions.Length / 2; i < positions.Length; i++)
            {
                verticesUp.Add(positions[i]);
            }
            //计算一个平面的点数量
            int count = verticesDown.Count;

            //将上下平面点合并
            for (int i = 0; i < verticesDown.Count; i++)
            {
                vertices.Add(verticesDown[i]);
            }
            for (int i = 0; i < verticesUp.Count; i++)
            {
                vertices.Add(verticesUp[i]);
            }

            //获取底面和顶面的三角形排序
            List <int> trianglesDown = PhysicsMath.DrawPolygon(verticesDown, false);
            List <int> trianglesUp   = PhysicsMath.DrawPolygon(verticesUp, true);

            for (int i = 0; i < trianglesDown.Count; i++)
            {
                trianglesUp[i] += count;
            }

            //合并底面顶面三角形排序
            for (int i = 0; i < trianglesDown.Count; i++)
            {
                triangles.Add(trianglesDown[i]);
            }
            for (int i = 0; i < trianglesUp.Count; i++)
            {
                triangles.Add(trianglesUp[i]);
            }

            //侧面三角形排序
            for (int i = 0; i < count - 1; i++)
            {
                // 加上侧面的点集
                vertices.Add(vertices[i]);
                vertices.Add(vertices[i + 1]);
                vertices.Add(vertices[i + count + 1]);
                vertices.Add(vertices[i + count]);

                // 侧面三角形排序
                triangles.Add(2 * count + 1 + i * 4);
                triangles.Add(2 * count + 0 + i * 4);
                triangles.Add(2 * count + 3 + i * 4);
                triangles.Add(2 * count + 1 + i * 4);
                triangles.Add(2 * count + 3 + i * 4);
                triangles.Add(2 * count + 2 + i * 4);
            }

            // 加上最后一个侧面的点集
            vertices.Add(vertices[count - 1]);
            vertices.Add(vertices[0]);
            vertices.Add(vertices[count]);
            vertices.Add(vertices[2 * count - 1]);

            // 加上最后一个侧面的三角形排序
            triangles.Add(vertices.Count - 3);
            triangles.Add(vertices.Count - 4);
            triangles.Add(vertices.Count - 1);
            triangles.Add(vertices.Count - 3);
            triangles.Add(vertices.Count - 1);
            triangles.Add(vertices.Count - 2);

            Color[] colors = new Color[vertices.Count];
            Color   color  = colorInt.Color();

            for (int i = 0; i < colors.Length; ++i)
            {
                colors[i] = color;
            }

            Mesh mesh = new Mesh
            {
                name      = "Polygon",
                vertices  = vertices.ToArray(),
                triangles = triangles.ToArray(),
                colors    = colors,
            };

            mesh.RecalculateBounds();     // 重置范围
            mesh.RecalculateNormals();    // 重置法线
            mesh.RecalculateTangents();   // 重置切线

            return(mesh);
        }
Example #24
0
        /// <summary>
        /// 立体线,可用于画空中走廊
        /// </summary>
        /// <param name="_bottomList">下底面排序</param>
        /// <param name="_width">宽度</param>
        /// <param name="_height">高度</param>
        /// <returns></returns>
        public static Mesh CreateLineMesh(List <Vector3> list, float _width, float _height, int colorInt = ColorInt32.white)
        {
            Vector3[] bottomPoints = PhysicsMath.GetAirSpaceBottomPoints(list, _width, _height);
            Vector3[] vertices     = PhysicsMath.GetAirBottomSpaceWithSector(bottomPoints.ToList(), _width);

            // 计算Mesh
            int _squareCount = list.Count - 1;
            var _bottomList  = vertices.ToList();

            List <Vector3> outList       = new List <Vector3>(); //输出点集合
            List <Vector3> topList       = new List <Vector3>(); //顶面点集合
            List <Vector3> allSquareList = new List <Vector3>(); // 所有矩形点集
            List <Vector3> allArcList    = new List <Vector3>(); // 所有弧形点集
            List <int>     triangles     = new List <int>();     // 存储三角形排序集合

            foreach (var item in _bottomList)
            {
                topList.Add(item + Vector3.up * _height);// 添加顶面点集
            }

            #region 矩形所有
            //合并矩形上下底面点集
            for (int i = 0; i < _squareCount * 4; i += 2)
            {
                allSquareList.Add(_bottomList[i]);
                allSquareList.Add(_bottomList[i + 1]);
                allSquareList.Add(topList[i + 1]);
                allSquareList.Add(topList[i]);
            }
            int bottomCount = _bottomList.Count;

            //画最左侧面
            outList.Add(allSquareList[0]);
            outList.Add(allSquareList[1]);
            outList.Add(allSquareList[2]);
            outList.Add(allSquareList[3]);

            triangles.Add(3);
            triangles.Add(0);
            triangles.Add(1);
            triangles.Add(3);
            triangles.Add(1);
            triangles.Add(2);

            //获得矩形区域点集合 4是为了去除左侧四个点
            for (int i = 0; i < _squareCount; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    //取余对内层循环的最后一次做处理  (i * 8)是为了去除前面i个矩形的点
                    if (j % 4 == 3)
                    {
                        outList.Add(allSquareList[i * 8 + j]);
                        outList.Add(allSquareList[i * 8 + (j - 3)]);
                        outList.Add(allSquareList[i * 8 + (j + 1)]);
                        outList.Add(allSquareList[i * 8 + (j + 4)]);
                    }
                    else
                    {
                        //以下四个点是组成了矩形的一个面
                        outList.Add(allSquareList[i * 8 + j]);
                        outList.Add(allSquareList[i * 8 + j + 1]);
                        outList.Add(allSquareList[i * 8 + j + 5]);
                        outList.Add(allSquareList[i * 8 + j + 4]);
                    }

                    // 第一个4是为了去除左侧面的四个点,16是为了去除一个矩形四个面的16个点,第二个4是为了去除内层循环j个面的点
                    triangles.Add(4 + i * 16 + j * 4);
                    triangles.Add(4 + i * 16 + j * 4 + 2);
                    triangles.Add(4 + i * 16 + j * 4 + 1);

                    triangles.Add(4 + i * 16 + j * 4);
                    triangles.Add(4 + i * 16 + j * 4 + 3);
                    triangles.Add(4 + i * 16 + j * 4 + 2);
                }
            }

            //画最右侧面
            outList.Add(allSquareList[allSquareList.Count - 4]);
            outList.Add(allSquareList[allSquareList.Count - 3]);
            outList.Add(allSquareList[allSquareList.Count - 2]);
            outList.Add(allSquareList[allSquareList.Count - 1]);

            triangles.Add(outList.Count - 1);
            triangles.Add(outList.Count - 3);
            triangles.Add(outList.Count - 4);
            triangles.Add(outList.Count - 1);
            triangles.Add(outList.Count - 2);
            triangles.Add(outList.Count - 3);
            #endregion

            #region 弧形所有

            int squarePointCount  = outList.Count;    // 记录用于画矩形的点的数量
            int squareBottomCount = _squareCount * 4; // 记录底面矩形点的数量

            // 添加弧形底面点
            for (int i = squareBottomCount; i < _bottomList.Count; i++)
            {
                outList.Add(_bottomList[i]);
            }
            // 添加弧形顶面点
            for (int i = squareBottomCount; i < _bottomList.Count; i++)
            {
                outList.Add(_bottomList[i] + Vector3.up * _height);
            }
            // 弧形顶面和底面三角形排序
            for (int i = 0; i < _squareCount - 1; i++)
            {
                for (int j = 1; j < 11; j++)
                {
                    triangles.Add(squarePointCount + i * 12);
                    triangles.Add(squarePointCount + i * 12 + j + 1);
                    triangles.Add(squarePointCount + i * 12 + j);
                }
            }
            for (int i = _squareCount - 1; i < (_squareCount - 1) * 2; i++)
            {
                for (int j = 1; j < 11; j++)
                {
                    triangles.Add(squarePointCount + i * 12);
                    triangles.Add(squarePointCount + i * 12 + j);
                    triangles.Add(squarePointCount + i * 12 + j + 1);
                }
            }

            int prePointCount = outList.Count; // 记录当前输出集合的点的数量

            // 添加弧形侧面点集
            for (int i = squareBottomCount; i < _bottomList.Count; i++)
            {
                outList.Add(_bottomList[i]);
                outList.Add(_bottomList[i] + Vector3.up * _height);
            }

            // 弧形侧面三角形排序
            for (int i = 0; i < _squareCount - 1; i++)
            {
                //j从2开始去除两个弧心点,i*24是为了去除每次内层循环后加入的22个点
                for (int j = 2; j < 22; j += 2)
                {
                    triangles.Add(prePointCount + i * 24 + j);
                    triangles.Add(prePointCount + i * 24 + j + 3);
                    triangles.Add(prePointCount + i * 24 + j + 1);
                    triangles.Add(prePointCount + i * 24 + j);
                    triangles.Add(prePointCount + i * 24 + j + 2);
                    triangles.Add(prePointCount + i * 24 + j + 3);
                }
            }
            #endregion

            Color[] colors = new Color[outList.Count];
            Color   color  = colorInt.Color();
            for (int i = 0; i < colors.Length; ++i)
            {
                colors[i] = color;
            }

            Mesh mesh = new Mesh
            {
                name      = "LineMesh",
                vertices  = outList.ToArray(),
                triangles = triangles.ToArray(),
                colors    = colors,
            };
            mesh.RecalculateBounds();              // 重置范围
            mesh.RecalculateNormals();             // 重置法线
            mesh.RecalculateTangents();            // 重置切线

            return(mesh);
        }
Example #25
0
    public override void OnUpdate()
    {
        MouseLeft();

        // 路面创建测试
        if (Input.GetKeyDown(KeyCode.K))
        {
            List <Vector3> points_out = new List <Vector3>();
            List <Vector3> points_in  = new List <Vector3>();
            Vector3        dirr;

            dirr = PhysicsMath.GetHorizontalDir(positions[1] - positions[0]);
            points_in.Add(positions[0] + dirr * 4);
            points_out.Add(positions[0] - dirr * 4);

            for (int i = 1; i < positions.Count - 1; i++)
            {
                dirr = PhysicsMath.GetHorizontalDir(positions[i + 1] - positions[i - 1]);
                points_in.Add(positions[i] + dirr * 4);
                points_out.Add(positions[i] - dirr * 4);
            }

            dirr = PhysicsMath.GetHorizontalDir(positions[positions.Count - 1] - positions[positions.Count - 2]);
            points_in.Add(positions[positions.Count - 1] + dirr * 4);
            points_out.Add(positions[positions.Count - 1] - dirr * 4);

            for (int i = 0; i < positions.Count; i++)
            {
                outCurve.AddNode(points_out[i], c);
                inCurve.AddNode(points_in[i], c);
                centerCurve.AddNode(positions[i], c);
            }
            outCurve.AddCatmull_RomControl();
            inCurve.AddCatmull_RomControl();
            centerCurve.AddCatmull_RomControl();


            for (int i = 0; i < outCurve.segmentList.Count; i++)
            {
                float add = 1f / 20;
                for (float j = 0; j < 1; j += add)
                {
                    Vector3 point = centerCurve.segmentList[i].GetPoint(j);
                    path.Add(point);
                    objs.Add(Utility.CreatPrimitiveType(PrimitiveType.Sphere, Color.red, point, 1));

                    //point = outCurve.segmentList[i].GetPoint(j);
                    //path.Add(point);
                    //objs.Add(Utility.CreatPrimitiveType(PrimitiveType.Sphere, point, 1, Color.red));

                    //point = inCurve.segmentList[i].GetPoint(j);
                    //path.Add(point);
                    //objs.Add(Utility.CreatPrimitiveType(PrimitiveType.Sphere, point, 1, Color.red));
                }
            }

            CreateRoads(Terrain.activeTerrain, meshFilter, path, 6);
        }
        if (Input.GetKeyDown(KeyCode.C))
        {
            meshFilter.mesh.Clear();
            objs.ForEach((a) => { Object.Destroy(a); });
            objs.Clear();
            outCurve    = new SplineCurve();
            inCurve     = new SplineCurve();
            centerCurve = new SplineCurve();
            positions.Clear();
            path.Clear();
        }

        if (Input.GetKeyDown(KeyCode.J))
        {
            hit = Utility.SendRay(LayerMask.GetMask("Terrain"));
        }


        // 刷新地图
        if (Input.GetKeyDown(KeyCode.L))
        {
            //TerrainUtility.Refresh();
        }
    }
Example #26
0
        /// <summary>
        /// 凹多边形空域 每个点高度不一样时 可以用来画扇形区域
        /// </summary>
        /// <param name="positions"></param>
        /// <param name="meshFilter"></param>
        /// <param name="lineRenderers"></param>
        public static void DrawPolygon(Vector3[] positions, MeshFilter meshFilter, LineRenderer[] lineRenderers, Color BoradColor)
        {
            List <Vector3> verticesDown = new List <Vector3>();
            List <Vector3> verticesUp   = new List <Vector3>();
            List <Vector3> vertices     = new List <Vector3>();

            List <int> triangles = new List <int>();

            //上下面坐标赋值 数组转List
            for (int i = 0; i < positions.Length / 2; i++)
            {
                verticesDown.Add(positions[i]);
            }
            for (int i = positions.Length / 2; i < positions.Length; i++)
            {
                verticesUp.Add(positions[i]);
            }
            //计算一个平面的点数量
            int count = verticesDown.Count;

            //将上下平面点合并
            for (int i = 0; i < verticesDown.Count; i++)
            {
                vertices.Add(verticesDown[i]);
            }
            for (int i = 0; i < verticesUp.Count; i++)
            {
                vertices.Add(verticesUp[i]);
            }

            //获取底面和顶面的三角形排序
            List <int> trianglesDown = PhysicsMath.DrawPolygon(verticesDown, false);
            List <int> trianglesUp   = PhysicsMath.DrawPolygon(verticesUp, true);

            for (int i = 0; i < trianglesDown.Count; i++)
            {
                trianglesUp[i] += count;
            }

            //合并底面顶面三角形排序
            for (int i = 0; i < trianglesDown.Count; i++)
            {
                triangles.Add(trianglesDown[i]);
            }
            for (int i = 0; i < trianglesUp.Count; i++)
            {
                triangles.Add(trianglesUp[i]);
            }

            //侧面三角形排序
            for (int i = 0; i < count - 1; i++)
            {
                // 加上侧面的点集
                vertices.Add(vertices[i]);
                vertices.Add(vertices[i + 1]);
                vertices.Add(vertices[i + count + 1]);
                vertices.Add(vertices[i + count]);

                // 侧面三角形排序
                triangles.Add(2 * count + 1 + i * 4);
                triangles.Add(2 * count + 0 + i * 4);
                triangles.Add(2 * count + 3 + i * 4);
                triangles.Add(2 * count + 1 + i * 4);
                triangles.Add(2 * count + 3 + i * 4);
                triangles.Add(2 * count + 2 + i * 4);
            }

            // 加上最后一个侧面的点集
            vertices.Add(vertices[count - 1]);
            vertices.Add(vertices[0]);
            vertices.Add(vertices[count]);
            vertices.Add(vertices[2 * count - 1]);

            // 加上最后一个侧面的三角形排序
            triangles.Add(vertices.Count - 3);
            triangles.Add(vertices.Count - 4);
            triangles.Add(vertices.Count - 1);
            triangles.Add(vertices.Count - 3);
            triangles.Add(vertices.Count - 1);
            triangles.Add(vertices.Count - 2);

            meshFilter.mesh.vertices  = vertices.ToArray();
            meshFilter.mesh.triangles = triangles.ToArray();

            meshFilter.mesh.RecalculateBounds();     // 重置范围
            meshFilter.mesh.RecalculateNormals();    // 重置法线
            meshFilter.mesh.RecalculateTangents();   // 重置切线

            //设置LineRenderer属性
            foreach (var item in lineRenderers)
            {
                item.startWidth    = 5;
                item.endWidth      = 5;
                item.positionCount = 2;
                item.startColor    = BoradColor;
                item.endColor      = BoradColor;
            }
            lineRenderers[0].positionCount = positions.Length + 1;

            //画两个弧面线及和圆心点的连接线
            for (int i = 0; i < positions.Length; i++)
            {
                lineRenderers[0].SetPosition(i, positions[i]);
            }
            lineRenderers[0].SetPosition(positions.Length, positions[0]);


            lineRenderers[1].SetPosition(0, positions[1]);
            lineRenderers[1].SetPosition(1, positions[positions.Length / 2 + 1]);
            lineRenderers[2].SetPosition(0, positions[positions.Length / 2 - 1]);
            lineRenderers[2].SetPosition(1, positions[positions.Length - 1]);
        }
Example #27
0
 private void CreatSector_2()
 {
     Vector3[] points = PhysicsMath.GetSectorPoints_2(positions[0], new Vector3(positions[1].x, positions[0].y, positions[1].z), alpha, theta);
     MeshManager.Instance.CreateSector(positions[0], positions[1], alpha, theta, sectorColor);
 }
Example #28
0
        /// <summary>
        /// 凹多边形空域 每个点高度不一样时 可以用来画扇形区域
        /// </summary>
        /// <param name="positions"></param>
        /// <param name="meshFilter"></param>
        /// <param name="lineRenderers"></param>
        public static void DrawPolygon(Vector3Extend[] positions, MeshFilter meshFilter)
        {
            List <Vector3> verticesDown = new List <Vector3>();
            List <Vector3> verticesUp   = new List <Vector3>();
            List <Vector3> vertices     = new List <Vector3>();

            List <int> triangles = new List <int>();

            //上下面坐标赋值 数组转List
            for (int i = 0; i < positions.Length; i++)
            {
                verticesDown.Add(positions[i].position);
            }
            for (int i = 0; i < positions.Length; i++)
            {
                verticesUp.Add(positions[i].position + new Vector3(0, positions[i].height, 0));
            }
            //计算一个平面的点数量
            int count = verticesDown.Count;

            //将上下平面点合并
            for (int i = 0; i < verticesDown.Count; i++)
            {
                vertices.Add(verticesDown[i]);
            }
            for (int i = 0; i < verticesUp.Count; i++)
            {
                vertices.Add(verticesUp[i]);
            }

            //获取底面和顶面的三角形排序
            List <int> trianglesDown = PhysicsMath.DrawPolygon(verticesDown, false);
            List <int> trianglesUp   = PhysicsMath.DrawPolygon(verticesUp, true);

            for (int i = 0; i < trianglesDown.Count; i++)
            {
                trianglesUp[i] += count;
            }

            //合并底面顶面三角形排序
            for (int i = 0; i < trianglesDown.Count; i++)
            {
                triangles.Add(trianglesDown[i]);
            }
            for (int i = 0; i < trianglesUp.Count; i++)
            {
                triangles.Add(trianglesUp[i]);
            }

            //侧面三角形排序
            for (int i = 0; i < count - 1; i++)
            {
                // 加上侧面的点集
                vertices.Add(vertices[i]);
                vertices.Add(vertices[i + 1]);
                vertices.Add(vertices[i + count + 1]);
                vertices.Add(vertices[i + count]);

                // 侧面三角形排序
                triangles.Add(2 * count + 1 + i * 4);
                triangles.Add(2 * count + 0 + i * 4);
                triangles.Add(2 * count + 3 + i * 4);
                triangles.Add(2 * count + 1 + i * 4);
                triangles.Add(2 * count + 3 + i * 4);
                triangles.Add(2 * count + 2 + i * 4);
            }

            // 加上最后一个侧面的点集
            vertices.Add(vertices[count - 1]);
            vertices.Add(vertices[0]);
            vertices.Add(vertices[count]);
            vertices.Add(vertices[2 * count - 1]);

            // 加上最后一个侧面的三角形排序
            triangles.Add(vertices.Count - 3);
            triangles.Add(vertices.Count - 4);
            triangles.Add(vertices.Count - 1);
            triangles.Add(vertices.Count - 3);
            triangles.Add(vertices.Count - 1);
            triangles.Add(vertices.Count - 2);

            meshFilter.mesh.vertices  = vertices.ToArray();
            meshFilter.mesh.triangles = triangles.ToArray();

            meshFilter.mesh.RecalculateBounds();     // 重置范围
            meshFilter.mesh.RecalculateNormals();    // 重置法线
            meshFilter.mesh.RecalculateTangents();   // 重置切线
        }
Example #29
0
        /// <summary>
        /// 获取凹多边形平面排序
        /// </summary>
        /// <param name="points"> 关键点集合 </param>
        /// <returns></returns>
        public static List <int> GetPolygonSort(List <Vector3> points, bool isUp)
        {
            List <int> indexs = new List <int>();

            for (int i = 0; i < points.Count; i++)
            {
                indexs.Add(i);
            }

            List <int> triangles = new List <int>();

            //创建一个除去自身前一点的 多边形,判断前一点是否为内点(凹点)
            int index = points.Count - 1;
            int next;
            int prev;

            int maxCount = indexs.Count + 1;
            int count    = 0;

            // 切分到无法切割三角形为止
            while (indexs.Count > 2)
            {
                if (maxCount > indexs.Count) // 正确
                {
                    maxCount = indexs.Count;
                    count    = 0;
                }
                else
                {
                    if (count > maxCount)
                    {
                        throw new System.Exception("当前有" + (count - 1).ToString() + "个数据死在循环中");
                    }
                    count++;
                }

                // 判断要判断是否切割的三角形的三个点是否在同一位置
                next = (index == indexs.Count - 1) ? 0 : index + 1;
                prev = (index == 0) ? indexs.Count - 1 : index - 1;
                if (points[index] == points[prev] && points[index] == points[next])
                {
                    throw new System.Exception("[DrawPolygon data error]三个点的个位置两两相等");
                }

                List <Vector3> polygon = new List <Vector3>(points.ToArray());
                polygon.RemoveAt(index);

                //是否是凹点
                if (!PhysicsMath.IsPointInsidePolygon(points[index], polygon))
                {
                    // 是否是可划分顶点:新的多边形没有顶点在被分割的三角形内
                    if (PhysicsMath.IsFragementIndex(points, index))
                    {
                        //可划分,剖分三角形
                        next = (index == indexs.Count - 1) ? 0 : index + 1;
                        prev = (index == 0) ? indexs.Count - 1 : index - 1;
                        if (isUp)
                        {
                            triangles.Add(indexs[next]);
                            triangles.Add(indexs[prev]);
                            triangles.Add(indexs[index]);
                        }
                        else
                        {
                            triangles.Add(indexs[index]);
                            triangles.Add(indexs[prev]);
                            triangles.Add(indexs[next]);
                        }

                        indexs.RemoveAt(index);
                        points.RemoveAt(index);

                        index = (index + indexs.Count - 1) % indexs.Count;       // 防止出现index超出值域,类似于i--

                        continue;
                    }
                }
                index = (index + 1) % indexs.Count;
            }

            return(triangles);
        }