Unity3d代码创建空心斜口圆柱体

实现算法

public GameObject CreateObliqueClinder(Vector3 ptStart, Vector3 ptEnd, float innerRadius, float outterRadius, Vector3 startPlaneNormal, Vector3 endPlaneNormal)
    {
        //计算垂直于轴的起始向量
        Vector3 vec1 = ptEnd - ptStart;
        Vector3 vec2 = Vector3.up;
        float a = Vector3.Angle(vec1, vec2);
        if (Mathf.Approximately(a, 0.0f))
        {
            vec2 = Vector3.right;
        }
        Vector3 vecStart = Vector3.Cross(vec1, vec2);

        //计算开始面内圆点、外圆点,结束面内圆点、外圆点
        List<Vector3> pointsStartInner = new List<Vector3>();
        List<Vector3> pointsStartOutter = new List<Vector3>();
        List<Vector3> pointsEndtInner = new List<Vector3>();
        List<Vector3> pointsEndOutter = new List<Vector3>();

        GameObject objStartInner = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        GameObject objStartOutter = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        GameObject objEndInner = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        GameObject objEndOutter = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        objStartInner.transform.position = ptStart + innerRadius * vecStart.normalized;
        objStartOutter.transform.position = ptStart + outterRadius * vecStart.normalized;
        objEndInner.transform.position = ptEnd + innerRadius * vecStart.normalized;
        objEndOutter.transform.position = ptEnd + outterRadius * vecStart.normalized;

        int devide = 30;//圆划分为多少等分
        float angleStep = 360.0f / (float)devide;

        float ang = 0.0f;
        for (ang = 0.0f; ang < 360.0f; ang += angleStep)
        {
            objStartInner.transform.RotateAround(ptStart, vec1, angleStep);
            objStartOutter.transform.RotateAround(ptStart, vec1, angleStep);
            objEndInner.transform.RotateAround(ptEnd, vec1, angleStep);
            objEndOutter.transform.RotateAround(ptEnd, vec1, angleStep);

            //轴线在平面上的投影点
            Vector3 ptAxisOnPlane = Vector3.ProjectOnPlane(ptStart, startPlaneNormal);

            //平移量
            Vector3 vecMove = ptStart - ptAxisOnPlane;

            //点在平面上的投影
            Vector3 ptStartInnerOnPlane = Vector3.ProjectOnPlane(objStartInner.transform.position, startPlaneNormal);
            Vector3 ptStartOutterOnPlane = Vector3.ProjectOnPlane(objStartOutter.transform.position, startPlaneNormal);
            pointsStartInner.Add(ptStartInnerOnPlane + vecMove);
            pointsStartOutter.Add(ptStartOutterOnPlane + vecMove);

           //结束端类似
            ptAxisOnPlane = Vector3.ProjectOnPlane(ptEnd, endPlaneNormal);
            vecMove = ptEnd - ptAxisOnPlane;
            Vector3 ptEndInnerOnPlane = Vector3.ProjectOnPlane(objEndInner.transform.position, endPlaneNormal);
            Vector3 ptEndOutterOnPlane = Vector3.ProjectOnPlane(objEndOutter.transform.position, endPlaneNormal);
            pointsEndtInner.Add(ptEndInnerOnPlane + vecMove);
            pointsEndOutter.Add(ptEndOutterOnPlane + vecMove);
        }
        Destroy(objStartInner);
        Destroy(objStartOutter);
        Destroy(objEndInner);
        Destroy(objEndOutter);

        //构建曲面
        List<Vector3> vertexs = new List<Vector3>();
        vertexs.AddRange(pointsStartInner);//开始面内圆点
        vertexs.AddRange(pointsEndtInner); //结束面内圆点
        vertexs.AddRange(pointsStartOutter);//开始面外圆点
        vertexs.AddRange(pointsEndOutter);结束面外圆点

        List<int> triangles = new List<int>();
        //构建内表面
        int startIndex = 0 * devide;
        int EndIndex = 0 * devide + devide;
        for (int i = startIndex; i < EndIndex; i++)
        {
            //边界面处
            int iNext = i + 1;
            int dNext = i + devide + 1;
            if (iNext >= startIndex + devide)
                iNext = startIndex;

            if (dNext >= startIndex + 2 * devide)
                dNext = startIndex + devide;

            triangles.Add(i);
            triangles.Add(i + devide);
            triangles.Add(iNext);

            triangles.Add(iNext);
            triangles.Add(i + devide);
            triangles.Add(dNext);
        }

        //构建外表面
        startIndex = 2 * devide;
        EndIndex = 2 * devide + devide;
        for (int i = startIndex; i < EndIndex; i++)
        {
            //边界面处
            int iNext = i + 1;
            int dNext = i + devide + 1;
            if (iNext >= startIndex + devide)
                iNext = startIndex;

            if (dNext >= startIndex + 2 * devide)
                dNext = startIndex + devide;

            triangles.Add(i);
            triangles.Add(iNext);
            triangles.Add(i + devide);

            triangles.Add(iNext);
            triangles.Add(dNext);
            triangles.Add(i + devide);
        }

        //构建上表面
        startIndex = 0 * devide;
        EndIndex = 0 * devide + devide;
        for (int i = startIndex; i < EndIndex; i++)
        {
            //边界面处
            int iNext = i + 1;
            int dNext = i + 2 * devide + 1;
            if (iNext >= startIndex + devide)
                iNext = startIndex;

            if (dNext >= startIndex + 3 * devide)
                dNext = startIndex + 2 * devide;

            triangles.Add(i);
            triangles.Add(iNext);
            triangles.Add(i + 2 * devide);

            triangles.Add(iNext);
            triangles.Add(dNext);
            triangles.Add(i + 2 * devide);
        }

        //构建下表面
        startIndex = 1 * devide;
        EndIndex = 1 * devide + devide;
        for (int i = startIndex; i < EndIndex; i++)
        {
            //边界面处
            int iNext = i + 1;
            int dNext = i + 2 * devide + 1;
            if (iNext >= startIndex + devide)
                iNext = startIndex;

            if (dNext >= startIndex + 3 * devide)
                dNext = startIndex + 2 * devide;

            triangles.Add(i);
            triangles.Add(i + 2 * devide);
            triangles.Add(iNext);

            triangles.Add(iNext);
            triangles.Add(i + 2 * devide);
            triangles.Add(dNext);
        }

        Mesh chunkMesh = new Mesh();
        chunkMesh.vertices = vertexs.ToArray();
        chunkMesh.triangles = triangles.ToArray();

        chunkMesh.RecalculateNormals();
        chunkMesh.RecalculateBounds();

        GameObject obj = new GameObject("MyClinder");
        MeshFilter mf = obj.AddComponent<MeshFilter>();
        MeshRenderer mr = obj.AddComponent<MeshRenderer>();
        mr.material = Resources.Load<Material>("mat");
        mf.sharedMesh = chunkMesh;

        return obj;
    }

算法调用

public class TunnelManager : MonoBehaviour {
    public GameObject startPlane;
    public GameObject endPlane;

    public void CreateClinder()
    {
        //TunnelEntity.Instance().CreateHollowClinder(new Vector3(-10.0f, 0f, 0f), new Vector3(80.0f, 0f, 0f), 10.0f, 11.0f);
        //TunnelEntity.Instance().CreateHollowClinder(new Vector3(-10.0f, 0f, 0f), new Vector3(-5.0f, 0f, 0f), 11.0f, 12.0f);
        //TunnelEntity.Instance().CreateHollowClinder(new Vector3(-5.0f, 0f, 0f), new Vector3(5.0f, 0f, 0f), 11.0f, 12.0f);
        Vector3 vecStartPlaneNormal = startPlane.transform.up;
        Vector3 vecEndPlaneNormal = endPlane.transform.up;

        Vector3 ptStart = new Vector3(-50.0f, 0f, 0f);
        Vector3 ptEnd = new Vector3(50.0f, 0f, 0f);
        TunnelEntity.Instance().CreateObliqueClinder(ptStart, ptEnd, 11.0f, 12.0f, vecStartPlaneNormal, vecEndPlaneNormal);

    }
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值