dragonBones使用Sprite换肤后mesh问题

简介: dragonBones使用Sprite换肤后mesh问题

image.png

其实原来的_updateFrame逻辑中是有处理mesh的情况,当时项目中并没有使用到mesh,所以我也就没有处理。

js
复制代码
  _updateFrame () {
        this._indices.length = 0;
        let indices = this._indices,
            localVertices = this._localVertices;
        let indexOffset = 0, vfOffset = 0;
        let currentTextureData = this._textureData;
        if (!this._display || this._displayIndex < 0 || !currentTextureData || !currentTextureData.spriteFrame) return;
        let texture = currentTextureData.spriteFrame.getTexture();
        let textureAtlasWidth = texture.width;
        let textureAtlasHeight = texture.height;
        let region = currentTextureData.region;
        const currentVerticesData = (this._deformVertices !== null && this._display === this._meshDisplay) ? this._deformVertices.verticesData : null;
        if (currentVerticesData) {
            const data = currentVerticesData.data;
            const intArray = data.intArray;
            const floatArray = data.floatArray;
            const vertexCount = intArray[currentVerticesData.offset + BinaryOffset.MeshVertexCount];
            const triangleCount = intArray[currentVerticesData.offset + BinaryOffset.MeshTriangleCount];
            let vertexOffset = intArray[currentVerticesData.offset + BinaryOffset.MeshFloatOffset];
            if (vertexOffset < 0) {
                vertexOffset += 65536; // Fixed out of bouds bug. 
            }
            const uvOffset = vertexOffset + vertexCount * 2;
            const scale = this._armature._armatureData.scale;
            for (let i = 0, l = vertexCount * 2; i < l; i += 2) {
                localVertices[vfOffset++] = floatArray[vertexOffset + i] * scale; // 顶点的x
                localVertices[vfOffset++] = -floatArray[vertexOffset + i + 1] * scale; // 顶点的y
                // 下边是处理uv,魔改时注意region应该是SpriteFrame的区域,let region = spriteFrame.getRect();
                if (currentVerticesData.rotated) {
                    localVertices[vfOffset++] = (region.x + (1.0 - floatArray[uvOffset + i]) * region.width) / textureAtlasWidth;
                    localVertices[vfOffset++] = (region.y + floatArray[uvOffset + i + 1] * region.height) / textureAtlasHeight;
                } else {
                    localVertices[vfOffset++] = (region.x + floatArray[uvOffset + i] * region.width) / textureAtlasWidth;
                    localVertices[vfOffset++] = (region.y + floatArray[uvOffset + i + 1] * region.height) / textureAtlasHeight;
                }
            }
            // 顶点索引
            for (let i = 0; i < triangleCount * 3; ++i) {
                indices[indexOffset++] = intArray[currentVerticesData.offset + BinaryOffset.MeshVertexIndices + i];
            }
            localVertices.length = vfOffset;
            indices.length = indexOffset;
            let isSkinned = !!currentVerticesData.weight;
            if (isSkinned) {
                this._identityTransform();
            }
        }
}

详细的逻辑分析就不展开了,之前的文章有详细的解释。

Engine的mesh的更新逻辑如下

js
复制代码
  _updateMesh () {
        const scale = this._armature._armatureData.scale;
        const deformVertices = this._deformVertices.vertices;
        const bones = this._deformVertices.bones;
        const verticesData = this._deformVertices.verticesData;
        const weightData = verticesData.weight;
        const hasDeform = deformVertices.length > 0 && verticesData.inheritDeform;
        let localVertices = this._localVertices;
        if (weightData) {
            const data = verticesData.data;
            const intArray = data.intArray;
            const floatArray = data.floatArray;
            const vertexCount = intArray[verticesData.offset + BinaryOffset.MeshVertexCount];
            let weightFloatOffset = intArray[weightData.offset + BinaryOffset.WeigthFloatOffset];
            if (weightFloatOffset < 0) {
                weightFloatOffset += 65536; // Fixed out of bouds bug. 
            }
            for (
                let i = 0, iB = weightData.offset + BinaryOffset.WeigthBoneIndices + bones.length, iV = weightFloatOffset, iF = 0, lvi = 0;
                i < vertexCount;
                i++, lvi+=4
            ) {
                const boneCount = intArray[iB++];
                let xG = 0.0, yG = 0.0;
                for (let j = 0; j < boneCount; ++j) {
                    const boneIndex = intArray[iB++];
                    const bone = bones[boneIndex];
                    if (bone !== null) {
                        const matrix = bone.globalTransformMatrix;
                        const weight = floatArray[iV++];
                        let xL = floatArray[iV++] * scale;
                        let yL = floatArray[iV++] * scale;
                        if (hasDeform) {
                            xL += deformVertices[iF++];
                            yL += deformVertices[iF++];
                        }
                        xG += (matrix.a * xL + matrix.c * yL + matrix.tx) * weight; 
                        yG += (matrix.b * xL + matrix.d * yL + matrix.ty) * weight;
                    }
                }
                localVertices[lvi] = xG; // lvi=0
                localVertices[lvi + 1] = -yG;// lvi=1
            }
        }
        else if (hasDeform) {
            const isSurface = this._parent._boneData.type !== BoneType.Bone;
            const data = verticesData.data;
            const intArray = data.intArray;
            const floatArray = data.floatArray;
            const vertexCount = intArray[verticesData.offset + BinaryOffset.MeshVertexCount];
            let vertexOffset = intArray[verticesData.offset + BinaryOffset.MeshFloatOffset];
            if (vertexOffset < 0) {
                vertexOffset += 65536; // Fixed out of bouds bug. 
            }
            for (let i = 0, l = vertexCount, lvi = 0; i < l; i ++, lvi += 4) {
                const x = floatArray[vertexOffset + i*2] * scale + deformVertices[i*2];
                const y = floatArray[vertexOffset + i*2 + 1] * scale + deformVertices[i*2 + 1];
                if (isSurface) {
                    const matrix = this._parent._getGlobalTransformMatrix(x, y);
                    localVertices[lvi] = matrix.a * x + matrix.c * y + matrix.tx;
                    localVertices[lvi + 1] = -matrix.b * x + matrix.d * y + matrix.ty;
                }
                else {
                    localVertices[lvi] = x;
                    localVertices[lvi + 1] = -y;
                }
            }
        }
        if (weightData) {
            this._identityTransform();
        }
    },

我们的关注点还是落在localVertices上,可以看到lvi=0, lvi=1

0和1其实就是顶点的x,y,mesh动画的本质就是顶点坐标的变化。

这样想来,只需要在我们实现的setSpriteFrame中更新uv即可,将原来的uv位置套到SpriteFrame的区域即可。

image.png

借鉴Engine的_updateFrame逻辑,去掉xy的计算,因为渲染前会每次调用我们写的这个函数,mesh的xy已经在渲染前计算好了,我们需要强制将uv桥接上即可,注意region我注释中有详细的说明

顺便开发了一个顶点uv查看工具



目录
相关文章
|
1月前
|
前端开发
ThreeJs通过canvas和Sprite添加标签
这篇文章介绍了在Three.js中利用Canvas和Sprite实现动态文本标签的方法,使得标签可以跟随模型并在3D空间中始终保持面向摄像机。
53 0
ThreeJs通过canvas和Sprite添加标签
|
5月前
|
编解码 前端开发 Java
【推荐100个unity插件之12】UGUI的粒子效果(UI粒子)—— Particle Effect For UGUI (UI Particle)
【推荐100个unity插件之12】UGUI的粒子效果(UI粒子)—— Particle Effect For UGUI (UI Particle)
355 0
|
5月前
|
开发工具 图形学
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
324 0
|
6月前
dragonBones.CCFactory.getInstance()导致的dragonBones突然不播放
dragonBones.CCFactory.getInstance()导致的dragonBones突然不播放
38 0
DragonBones骨骼动画事件系统详解
DragonBones骨骼动画事件系统详解
129 0
Egret 碰撞检测总结
Egret 碰撞检测总结
87 0
threejs实战_camera
threejs的相机光影配置
79 0
threejs实战_camera
dragonBones龙骨利用网格实现简单的眨眼效果
dragonBones龙骨利用网格实现简单的眨眼效果
Sprite渲染流程-TrianglesCommand
Sprite渲染流程-TrianglesCommand
102 0
|
图形学
Unity里实现Sprite Renderer的阴影
将以下脚本附到产生Shadow的物体上: voidOnEnable(){ GetComponent().receiveShadows =true; GetComponent().castShadows =true; } 但是这是不够的,还需要Shader帮忙,下面的Shader请放到产生Shado...
3166 0