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查看工具



目录
相关文章
|
2月前
|
C++ UED
C++ Qt开发:Slider滑块条组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍`Slider`滑块条组件的常用方法及灵活运用。当涉及到C++ Qt开发中的`Slider`滑块条组件时,你可能会用到`QSlider`类。`QSlider`是一个用于选择整数值的控件,常用于调整范围内的数值,如音量、亮度等。在水平方向上的`Slider`通常被称为水平滑块(Horizontal Slider),而在垂直方向上的Slider被称为垂直滑块(Vertical Slider)。
66 0
|
8月前
DragonBones骨骼动画事件系统详解
DragonBones骨骼动画事件系统详解
88 0
dragonBones龙骨利用网格实现简单的眨眼效果
dragonBones龙骨利用网格实现简单的眨眼效果
Sprite渲染流程-TrianglesCommand
Sprite渲染流程-TrianglesCommand
81 0
|
Dart 开发者
【Flutter】Animation 动画 ( Flutter 动画的核心类 | Animation | CurvedAnimation | AnimationController | Tween )(二)
【Flutter】Animation 动画 ( Flutter 动画的核心类 | Animation | CurvedAnimation | AnimationController | Tween )(二)
157 0
【Flutter】Animation 动画 ( Flutter 动画的核心类 | Animation | CurvedAnimation | AnimationController | Tween )(一)
【Flutter】Animation 动画 ( Flutter 动画的核心类 | Animation | CurvedAnimation | AnimationController | Tween )(一)
190 0
|
图形学
Unity里实现Sprite Renderer的阴影
将以下脚本附到产生Shadow的物体上: voidOnEnable(){ GetComponent().receiveShadows =true; GetComponent().castShadows =true; } 但是这是不够的,还需要Shader帮忙,下面的Shader请放到产生Shado...
3117 0
|
图形学
Unity动画机制 Animator与Animator Controller教程
Unity动画机制Animator 本文提供全流程,中文翻译。 Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) Chinar —.
4328 0