• LayaAir2.0 自定义Mesh-画圆环


      这是在上一篇文章画扇形的基础上实现的,基本上还是来源于Laya官方提供的画圆柱的Mesh代码实现。

      圆环相较于扇形或者圆柱,是增加了内径,要切除掉一部分中间区域。最终的表现为上下部分的圆环,内部、外部的封边。在画扇形、圆柱的基础上,需要改一下上下圆环,然后增加一个内部的封边。

      一开始觉得画上下的圆环很简单,就是圆环半径,减去圆环内径,然后把剩下的区域画出来就行,但是代码该咋写呢。。。后来想一下,圆柱体外部封边也可以看成画了一个环,那是不是就可以直接基于那部分代码来修改呢?

    // 画出上圆环
    for (let bv = 0; bv <= slices; bv++) {
        curAngle = bv * sliceAngle
    
        posY = halfHeight
    
        vertices[vc++] = Math.cos(curAngle) * innerRadius
        vertices[vc + (slices + 1) * 8 - 1] = Math.cos(curAngle) * radius
    
        vertices[vc++] = posY
        vertices[vc + (slices + 1) * 8 - 1] = posY
    
        vertices[vc++] = Math.sin(curAngle) * innerRadius
        vertices[vc + (slices + 1) * 8 - 1] = Math.sin(curAngle) * radius
    
        vertices[vc++] = 0
        vertices[vc + (slices + 1) * 8 - 1] = 0
    
        vertices[vc++] = 1
        vertices[vc + (slices + 1) * 8 - 1] = 1
    
        vertices[vc++] = 0
        vertices[vc + (slices + 1) * 8 - 1] = 0
    
        vertices[vc++] = 1 - bv * 1 / slices
        vertices[vc + (slices + 1) * 8 - 1] = 1 - bv * 1 / slices
    
        vertices[vc++] = 0
        vertices[vc + (slices + 1) * 8 - 1] = 1
    }
    vc += (slices + 1) * 8
    // 上环显示的是正面,所以顶点索引要顺序
    for (let ri = 0; ri < slices; ri++) {
        indices[ic++] = ri + verticeCount + (slices + 1)
        indices[ic++] = ri + verticeCount + 1
        indices[ic++] = ri + verticeCount
        indices[ic++] = ri + verticeCount + (slices + 1)
        indices[ic++] = ri + verticeCount + (slices + 1) + 1
        indices[ic++] = ri + verticeCount + 1
    }
    verticeCount += 2 * (slices + 1)

      上述代码就是在画圆柱外部封边的基础上修改而来的,红色标记的就是修改的地方,把坐标改成内外径而已。

      内部封边,则基本上可以照着外封边的代码来改:

    // 画出厚度内圈
        for (let rv = 0; rv <= slices; rv++) {
            curAngle = rv * sliceAngle
            posX = Math.cos(curAngle) * innerRadius
            posY = halfHeight
            posZ = Math.sin(curAngle) * innerRadius
    
            vertices[vc++] = posX
            vertices[vc + (slices + 1) * 8 - 1] = posX
    
            vertices[vc++] = posY
            vertices[vc + (slices + 1) * 8 - 1] = -posY
    
            vertices[vc++] = posZ
            vertices[vc + (slices + 1) * 8 - 1] = posZ
    
            vertices[vc++] = posX
            vertices[vc + (slices + 1) * 8 - 1] = posX
    
            vertices[vc++] = 0
            vertices[vc + (slices + 1) * 8 - 1] = 0
    
            vertices[vc++] = posZ
            vertices[vc + (slices + 1) * 8 - 1] = posZ
    
            // 内圈显示的是背面,这里将数值调一下,显示背面
            vertices[vc++] = rv * 1 / slices - 1
            vertices[vc + (slices + 1) * 8 - 1] = rv * 1 / slices - 1
    
            vertices[vc++] = 0
            vertices[vc + (slices + 1) * 8 - 1] = 1
        }
        vc += (slices + 1) * 8
        // z轴三角 显示背面,逆序
        for (let ri = 0; ri < slices; ri++) {
            indices[ic++] = ri + verticeCount + (slices + 1)
            indices[ic++] = ri + verticeCount
            indices[ic++] = ri + verticeCount + 1
            indices[ic++] = ri + verticeCount + (slices + 1)
            indices[ic++] = ri + verticeCount + 1
            indices[ic++] = ri + verticeCount + (slices + 1) + 1
        }
        verticeCount += 2 * (slices + 1)

      改动的地方基本上就是坐标值用的是内径的长度。然后有两个地方要注意,首先是索引顺序,因为内径在表现上来说是看到了3D物体的背面,所以顶点索引是逆序的;再者是8个数据中倒数第二位UV坐标X值,这个是我猜着改的,改动之后,内部封边的贴图显示就正常了。

      如果要画半环,那还是跟画扇形一样,改一下顶点数,就能画出正常的3D环形了。

      自定义Mesh画出来的模型,也是可以添加物理碰撞器和刚体的,只是碰撞形状的数据,要用模型的数据,例如:

    let ring = createRing(...)
    // 碰撞器
    let ringCollider = ring.addComponent(Laya.PhysicsCollider)
    let ringShape = new Laya.MeshColliderShape()
    ringShape.mesh = ring.meshFilter.sharedMesh
    ringCollider.colliderShape = ringShape

      之前在这个地方卡了很久,一直不生效,后来再改动改动坐标,发现是在3D世界中,物体相对位置不对,直接没有做到碰撞检测。

  • 相关阅读:
    混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况
    静态static与方法重载
    编写的一个“手机”的类
    面向对象编程(OOP)————修饰符
    POJO
    设计模式——单例模式
    矩形类 求面积
    面向对象编程(OOP)————类
    面向对象编程(OOP)
    for、if循环直至输入正确
  • 原文地址:https://www.cnblogs.com/zhong-dev/p/11215294.html
Copyright © 2020-2023  润新知