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



目录
相关文章
|
3月前
|
存储 JavaScript
ThreeJS创建关键帧动画
这篇文章讲解了如何在Three.js中利用关键帧轨道 (`KeyframeTrack`) 创建动画效果,并提供了详细的步骤和代码示例。
96 0
|
7月前
|
开发工具 图形学
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
521 0
DragonBones骨骼动画事件系统详解
DragonBones骨骼动画事件系统详解
143 0
Egret 碰撞检测总结
Egret 碰撞检测总结
96 0
|
编解码
unity3dUGUI之UI粒子特效自适应缩放
using UnityEngine; using System.Collections; using System.Collections.Generic; public class UIParticleScale : MonoBehaviour...
1597 0
|
前端开发 API Python
自定义控件扫盲-canvas
自定义控件扫盲-canvas
135 0
自定义控件扫盲-canvas
【ThreeJs】(1)四大组件:场景、相机、物体、渲染器 | 创建一个矩形 | THREE脑图
【ThreeJs】(1)四大组件:场景、相机、物体、渲染器 | 创建一个矩形 | THREE脑图
383 0
【ThreeJs】(1)四大组件:场景、相机、物体、渲染器 | 创建一个矩形 | THREE脑图
SwiftUI—使用withAnimation制作缩放和渐隐动画
SwiftUI—使用withAnimation制作缩放和渐隐动画
1032 0
|
前端开发
UGUI系列-屏幕自适应多分配率适配(Untiy3D)
1、Canvas的属性配置 2、Canvas Scaler的属性配置 3、根据不同的屏幕的比例动态修改缩放基准
|
容器
Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)
原文:Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)   正如你所看到的,Blend是一个非常强大的节约时间的设计工具,在Blend下能够设计出很多满意的动画作品,或许他具体是怎么实现的,通过什么方式实现的我们还是一无所知。
951 0

热门文章

最新文章