骨骼控制(一)——动画动态节点(AnimDynamics)
文章目录
- 一、引言
- 二、骨骼控制
- 三、UE蓝图中提供的骨骼控制节点——AnimDynamics动画蓝图节点
- 1、什么是AnimDynamics动画蓝图节点
- ①使用盒体计算惯性
- ②使用约束来限制移动
- 2、AnimDynamics节点的几种常用例子
- ①单骨骼模拟
- ②骨骼链模拟 <h2 id=1>
- ③群魔乱舞(这是错误示范)
- ④平面限制
- ⑤球体限制
- 四、引用
一、引言
第一印象:已经有这么多动画混合方式了,为什么还有这么多骨骼控制节点,带着这个疑问往下看
二、骨骼控制
骨骼控制: 顾名思义就是直接控制角色的骨架,举个残酷的例子,一个人下半身截肢了并且安上了机械假肢,此时下半身的运动就不再受身体的控制,而是由机器及其里面的逻辑控制。
骨骼控制的概念也是如此,控制角色身上的某部分骨骼,使其不再受角色整体的运动(或者说既定的动画)运动,而是由一套独立的逻辑去控制。
当然了,游戏中大概是不会真的直接把下半身“截肢”的,但是可以利用骨骼控制来模拟部分不受身体驱动,或者既定动画不能完美展示的部分,比如飘动的头发。
三、UE蓝图中提供的骨骼控制节点——AnimDynamics动画蓝图节点
1、什么是AnimDynamics动画蓝图节点
AnimDynamics动画蓝图节点 是一种 轻量级的物理模拟 解决方案,它能让角色的部分骨骼网格体实现基于物理的附属动画。
看到这里,其实已经能够区分出开头的问题——动画融合实际上是将两个动画按照一定的函数运算进行混合叠加;而骨骼控制能够控制骨骼按照物理规律进行运动。前者某种程度上来说还是既定动画,而后者是基于现实世界的物理,与外界有交互的。
在UE的官方文档中对“AnimDynamics节点”给出了如下两行说明,通过代码来简要分析一下原因
需要看代码了解一下上面说的两个事
①使用盒体计算惯性
EvaluateSkeletalControl_AnyThread 中进行模拟,并对物理进行初始化InitPhysics,需要注意的是虽然EvaluateSkeletalControl_AnyThread是逐帧去tick的,但是InitPhysics在整个过程中只会被调用一次。
InitPhysics中对盒体进行初始化,在骨骼链模拟 还有解析
// AnimNode_AnimDynamics.cpp line:673void FAnimNode_AnimDynamics::InitPhysics(FComponentSpacePoseContext& Output)
{
...for (FAnimPhysBodyDefinition& PhysicsBodyDef : PhysicsBodyDefinitions){TArray<FAnimPhysShape> BodyShapes;BodyShapes.Add(FAnimPhysShape::MakeBox(PhysicsBodyDef.BoxExtents));PhysicsBodyDef.BoundBone.Initialize(BoneContainer);FTransform BodyTransform = GetBoneTransformInSimSpace(Output, PhysicsBodyDef.BoundBone.GetCompactPoseIndex(BoneContainer));BodyTransform.SetTranslation(BodyTransform.GetTranslation() + BodyTransform.GetRotation().RotateVector(PhysicsBodyDef.LocalJointOffset)); // Transform for physics body in Sim Space.FAnimPhysLinkedBody NewChainBody(BodyShapes, BodyTransform.GetTranslation(), PhysicsBodyDef.BoundBone);FAnimPhysRigidBody& PhysicsBody = NewChainBody.RigidBody.PhysBody;PhysicsBody.Pose.Orientation = BodyTransform.GetRotation();PhysicsBody.PreviousOrientation = PhysicsBody.Pose.Orientation;PhysicsBody.NextOrientation = PhysicsBody.Pose.Orientation;PhysicsBody.CollisionType = PhysicsBodyDef.CollisionType;...}
...
}
②使用约束来限制移动
UpdateLimits 中进行 “角速度”、“线速度” 以及后面提到的 “平面限制”、“球体限制” 等限制的更新,在每次tick的时候都会更新。
在看下面代码之前需要了解存储限制的数据结构:
// AnimNode_AnimDynamics.h line:87struct FAnimPhysConstraintSetup
{...FAnimPhysConstraintSetup(): LinearXLimitType(AnimPhysLinearConstraintType::Limited), LinearYLimitType(AnimPhysLinearConstraintType::Limited), LinearZLimitType(AnimPhysLinearConstraintType::Limited), bLinearFullyLocked(false), LinearAxesMin(ForceInitToZero), LinearAxesMax(ForceInitToZero)...
}// AnimNode_AnimDynamics.h line:238
struct FAnimPhysBodyDefinition
{...FAnimPhysConstraintSetup ConstraintSetup;...
}
也就是 FAnimPhysBodyDefinition ->FAnimPhysConstraintSetup ->(LinearAxesMin/LinearAxesMax)、(AngularLimitsMin/AngularLimitsMax)这样的一种结构
// AnimNode_AnimDynamics.cpp line:858void FAnimNode_AnimDynamics::UpdateLimits(FComponentSpacePoseContext& Output)
{...const FAnimPhysBodyDefinition& PhysicsBodyDef = PhysicsBodyDefinitions[ActiveIndex];...if (PhysicsBodyDef.ConstraintSetup.bLinearFullyLocked){// Rather than calculate prismatic limits, just lock the transform (1 limit instead of 6)FAnimPhys::ConstrainPositionNailed(NextTimeStep, LinearLimits, PrevBody, ShapeTransform.GetTranslation(), &RigidBody, Body1JointOffset);}else{// 线速度if (PhysicsBodyDef.ConstraintSetup.LinearXLimitType != AnimPhysLinearConstraintType::Free){FAnimPhys::ConstrainAlongDirection(NextTimeStep, LinearLimits, PrevBody, ShapeTransform.GetTranslation(), &RigidBody, Body1JointOffset, ShapeTransform.GetRotation().GetAxisX(), FVector2D(PhysicsBodyDef.ConstraintSetup.LinearAxesMin.X, PhysicsBodyDef.ConstraintSetup.LinearAxesMax.X));}...}...// 平面限制if(PlanarLimits.Num() > 0 && bUsePlanarLimit){for(FAnimPhysPlanarLimit& PlanarLimit : PlanarLimits){...FAnimPhys::ConstrainPlanar(NextTimeStep, LinearLimits, &RigidBody, LimitPlaneTransform);}}// 球体限制if(SphericalLimits.Num() > 0 && bUseSphericalLimits){for(FAnimPhysSphericalLimit& SphericalLimit : SphericalLimits){...switch(SphericalLimit.LimitType){case ESphericalLimitType::Inner:FAnimPhys::ConstrainSphericalInner(NextTimeStep, LinearLimits, &RigidBody, SphereTransform, SphericalLimit.LimitRadius);break;case ESphericalLimitType::Outer:FAnimPhys::ConstrainSphericalOuter(NextTimeStep, LinearLimits, &RigidBody, SphereTransform, SphericalLimit.LimitRadius);break;default:break;}}}
}
2、AnimDynamics节点的几种常用例子
可以通过为骨骼添加 AnimDynamics动画蓝图节点,进而让骨骼控制的区域不再“死气沉沉”。下面以UE自带的 欧若拉资源 展示。
①单骨骼模拟
1、仔细观察下面的头发,可以看到头发是没有动画的,仅仅是跟随着头部运动,下面我们为其添加上 AnimDynamics节点
2、再看下面角色头部 左侧的第一缕头发, 可以看到头发随着人物的运动而晃动,飘逸起来了!
3、添加的碰撞盒位置如下
4、配置如下(没有勾选链条!)
②骨骼链模拟
1、没有给骨骼链添加 AnimDynamics节点 时的样子
2、给添加骨骼链添加 AnimDynamics节点 后,左侧头发随风飘扬
3、添加的碰撞盒位置如下
4、配置如下
在使用骨骼链的时候要注意,在UE文档中明确表明了一下:
结合代码来看:在初始化物理的时候会根据骨骼链上的骨骼数进行迭代产生对应数量的碰撞盒,因此有更高的物理消耗(PhysicsBodyDefinitions中存放了骨骼所需的物理信息及骨骼本身的信息),下面是选择了thumb_01_l——thumb_03_l 这条链。
// AnimNode_AnimDynamics.cpp line:673void FAnimNode_AnimDynamics::InitPhysics(FComponentSpacePoseContext& Output)
{
...for (FAnimPhysBodyDefinition& PhysicsBodyDef : PhysicsBodyDefinitions){TArray<FAnimPhysShape> BodyShapes;BodyShapes.Add(FAnimPhysShape::MakeBox(PhysicsBodyDef.BoxExtents));...}
...
}
③群魔乱舞(这是错误示范)
④平面限制
如下所示,可以将骨骼限制在平面之下
// AnimPhysicsSolver.cpp line:766void FAnimPhys::ConstrainPlanar
...
⑤球体限制
效果是设置一个球体,依据驱动骨骼设置了限制的活动区域,可以设置是对内碰撞还是对外碰撞,“外部”则骨骼只能在球体外进行运动,“内部”则骨骼只能在内部进行运动,下面分别举例外部和内部的例子:
1、内部如下:
可以看到,我们绑定的骨骼只能在求体内运动,一旦脱离则会被强制收束到球上
2、外部如下:
只需将上面配置中的“内部”改为“外部”即可,效果如下,此时骨骼只能在球外运动
// AnimPhysicsSolver.cpp line:785void FAnimPhys::ConstrainSphericalInner
...
void FAnimPhys::ConstrainSphericalOuter
...
四、引用
UE5AnimDynamics文档
相关文章:
骨骼控制(一)——动画动态节点(AnimDynamics)
文章目录一、引言二、骨骼控制三、UE蓝图中提供的骨骼控制节点——AnimDynamics动画蓝图节点1、什么是AnimDynamics动画蓝图节点①使用盒体计算惯性②使用约束来限制移动2、AnimDynamics节点的几种常用例子①单骨骼模拟②骨骼链模拟 <h2 id1>③群魔乱舞(这是错…...
Linux系统下搭建maven环境
文章目录前述从官网下载安装包安装 maven修改maven配置修改环境变量测试前述 安装 maven 环境前,需要先安装 java 环境,如果没有安装 java 环境,可以参考:https://blog.csdn.net/weixin_45583303/article/details/118631855 从官…...
English Learning - L2 语音作业打卡 Day3 2023.2.23 周四
English Learning - L2 语音作业打卡 Day3 2023.2.23 周四💌 发音小贴士:💌 当日目标音发音规则/技巧:🍭 Part 1【热身练习】🍭 Part2【练习内容】🍭【练习感受】🍓元音[ ɔ: ]&…...
RK3568平台开发系列讲解(驱动基础篇)GIC v3中断控制器
🚀返回专栏总目录 文章目录 一、什么是GIC二、GIC v3中断类型三、GIC v3基本结构3.1、Distributor3.2、CPU interface简介3.3、Redistributor简介3.4、ITS(Interrupt translation service)4、中断状态和处理流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢ARM多核…...
决策树、随机森林、极端随机树(ERT)
声明:本文仅为个人学习记录所用,参考较多,如有侵权,联系删除 决策树 通俗来说,决策树分类的思想类似于找对象。现想象一个女孩的母亲要给这个女孩介绍男朋友,于是有了下面的对话: 女儿&#x…...
软件测试之因果图法
因果图法 1. 概述 因果图法是一种**利用图解法分析输入条件、输出结果的各种组合情况,**从而设计测试用例的方法. 因果图法适用于有多个输入和多个输出,而且输入和输入之间有相互的组合关系,输入和输出之间有相互的制约和依赖关系. 使用场景和判定表…...
vue中子组件间接修改父组件传递过来的值
一、前言 Vue官方文档Props单向数据流讲解 Vue中遵循单向数据流,所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。这避免了子组件意外修改父组件的状态的情况&a…...
Java I/O
前言 关于IO, 想必你听过很多中I/O方式, 有的是OS视角的, 有的是JDK本身支持的, 有的是纯实现视角。但是作为一个developer, 我希望你能先搞清楚上下文之后, 再去理解内容, 否则容易抬杠。这个上下文有横向和纵向两个维度。纵向维度包括JDK底层, JDK上层包装库, 开发框架(如Ne…...
pytorch学习日记之图片的简单卷积、池化
导入图片并转化为张量 import torch import torch.nn as nn import matplotlib.pyplot as plt import numpy as np from PIL import Image mymi Image.open("pic/123.png") # 读取图像转化为灰度图片转化为numpy数组 myimgray np.array(mymi.convert("L"…...
【java基础】抽象类和抽象方法
文章目录基本介绍抽象类抽象方法使用总结基本介绍 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就…...
RDD的内核调度【博学谷学习记录】
RDD的依赖关系RDD的依赖: 指的一个RDD的形成可能是有一个或者多个RDD得出, 此时这个RDD和之前的RDD之间产生依赖关系在Spark中, RDD之间的依赖关系,主要有二种依赖关系:1- 窄依赖:目的: 为了实现并行计算操作, 并且提高容错的能力指的: 一个RDD上的一个分区的数据, 只能完整的交…...
二叉树——二叉搜索树的最小绝对差
二叉搜索树的最小绝对差 链接 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数,其数值等于两值之差的绝对值。 示例 1: 输入:root [4,2,6,1,3] 输出:1 示例 2&…...
git的使用(终端输入指令)下
文章目录前言1、git 分支创建分支查看分支切换分支合并分支删除分支2.提交到远程仓库远程提交链接一下自己仓库总结前言 上章链接 :git的使用(终端输入指令)上 我们接着上着来说 上章把 git 的 功能实现了一部分,本章我们接着上文…...
python使用influxdb-client管理InfluxDB的bucket
bucket的概念类似数据库的“库”,同时每个库中的数据都因为存在“时间戳”,每个数据都会有一个对应的时间点 influxdb-client-python官方github页面:https://github.com/influxdata/influxdb-client-python 管理bucket的官方示例࿱…...
【c++】模板2—类模板
文章目录类模板语法类模板与函数模板区别类模板中成员函数常见时机类模板对象做函数参数类模板与继承类模板成员函数类外实现类模板分文件编写类模板与友元类模板语法 类模板作用: 建立一个通用类,类中的成员数据类型可以不具体制定,用一个虚…...
基于SpringCloud的可靠消息最终一致性03:项目骨架代码(下)
上一节把整个项目的演示内容、项目结构、POM文件和配置文件都讲完了,接下来继续。 先安装并启动Nacos,然后在其中建立一个名为xiangwang-payment-dev.yaml的配置文件,内容为: # 指定运行环境 spring:autoconfigure:exclude: com.alibaba.druid.spring.boot.autoconfigure.D…...
linux如何彻底的删除文件
一、使用rm命令删除 直接用rm 先用ls -alt看下文件信息及拥有者等 可以看到拥有者是eve用户,所以在eve用户的终端中rm命令即可, 如果是root或者其他,则优先用root或其他账号进行删除 (base) eveEve:~$ ls -alt a.txt -rw-rw-r-- 1 eve eve …...
数据仓库Hive的安装和部署
1)去apache.hive.org官网下载hive 目前hive主要有三大版本,Hive1.x、Hive2.x、Hive3.x Hive1.x已经2年没有更新了,所以这个版本后续基本不会再维护了,不过这个版本已经迭代了很多年了,也是比较稳定的 Hive2.x最近一直…...
Python调用CANoe常见问题
一、Win32com已经安装成功但是在pycharm中提示错误 No module named win32com.clientPyCharm中出现unresolved reference的解决方法 一直提示需要升级pip版本Pywin32已成功安装,但仍提示没有win32com模块...
一起Talk Android吧(第五百零七回:图片滤镜ImageFilterView)
文章目录背景介绍功能介绍图片滤镜图片圆角图片缩放图片旋转图片平移各位看官们大家好,上一回中咱们说的例子是"如何调整组件在约束布局中的角度",这一回中咱们说的例子是" 图片滤镜ImageFilterView"。闲话休提,言归正转,…...
Java 解释器和即时解释器(JIT)之间的区别
区别是: 翻译 .class (字节码文件) 的粒度和方式不同 解释器是一个逐条解释并执行字节码指令的组件,每次**只翻译一条**指令并执行,然后再翻译下一条指令。 它的翻译粒度是一条指令,而且是按需翻译&#x…...
Acwing 蓝桥杯 第二章 二分与前缀和
今天来补一下之前没写的总结,题是写完了,但是总结没写感觉没什么好总结的啊,就当打卡了789. 数的范围 - AcWing题库思路:一眼二分,典中典先排个序,再用lower_bound和upper_bound维护相同的数的左界和右界就…...
CSDN原力增长规则解读 实测一个月
CSDN原力越来越难了,当然,这对生态发展来说也是好事。介绍下原力增长有哪些渠道吧。发布原创文章:10分/次,每日上限为15分、2篇回答问题:1分/次,每日上限2分,2回答发动态:1分/次&…...
HDMI协议介绍(三)--InfoFrame
目录 Auxiliary Video information (AVI) InfoFrame AVI InfoFrame包结构 Header Body 举个例子 附录 Audio InfoFrame Audio InfoFrame包结构 Header Body Vendor Specific InfoFrame Vendor Specific InfoFrame包结构 Header Body AVI/AUDIO/VSI Infoframe都…...
【RocketMQ】源码详解:Broker端消息储存流程、消息格式
消息存储流程 入口: org.apache.rocketmq.remoting.netty.NettyRemotingAbstract#processRequestCommand org.apache.rocketmq.broker.processor.SendMessageProcessor#asyncProcessRequest 消息到达broker后会经过netty的解码、消息处理器等,最后根据…...
IoT项目系统架构案例2
项目背景 1.这个项目是对之前的案例的升级改造参考:IoT项目系统架构案例_iot案例_wxgnolux的博客-CSDN博客2.基于方案1的项目实施过程中碰到的问题,对硬件设备标准化的理念及新的功能需求(如根据天气预报温度调水温,APP界面可操作性优化等)•采用目前IoT主流厂商的架…...
Vue echarts封装
做大屏的时候经常会遇到 echarts 展示,下面展示在 Vue2.7 / Vue3 中对 echarts (^5.4.0) 的简单封装。 文章首发于https://blog.fxss.work/vue/echarts封装.html,样例查看 echarts 封装使用 props 说明 参数说明类型可选值默认…...
蓝桥杯入门即劝退(二十二)反转字符(不走寻常路)
欢迎关注点赞评论,共同学习,共同进步! ------持续更新蓝桥杯入门系列算法实例-------- 如果你也喜欢Java和算法,欢迎订阅专栏共同学习交流! 你的点赞、关注、评论、是我创作的动力! -------希望我的文章…...
数据仓库Hive
HIve介绍 Hive是建立在Hadoop上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载,可以简称为ETL。 Hive 定义了简单的类SQL查询语言,称为HQL,它允许熟悉SQL的用户直接查询Hadoop中的数据…...
嵌入式 STM32 步进电机驱动,干货满满,建议收藏
目录 步进电机 1、步进电机驱动原理 2、步进电机驱动 3、步进电机应用 1、第一步:初始化IO口 2、设置行进方式 四、源码 步进电机 步进电机被广泛应用于ATM机、喷绘机、刻字机、写真机、喷涂设备、医疗仪器及设备、计算机外设及海量存储设备、精密仪器、工业…...
威海网站优化/网站免费推广方式
javaScript RegExp对象: global——Boolean值、表示g(全局选项)是否已设置 ignoreCase——Boolean值、表示i(忽略大小写选项)是否已设置 lastIndex——整数、代表下次匹配将会从哪个字符位置开始(只有当使用exec()或test()函数才会填入、否则为0) mult…...
如何管理好一个网站/360搜索建站
版本管理工具GIT篇 一、版本管理工具干什么用的? 备份文件 作用同U盘 网盘 保存每天的成果 若是本地文件丢失 损坏 找备份如 打游戏时候的存档记录历史网盘 U盘存储的是文件最新状态 历史操作没有 作用同 history命令 找到历史操作的版本 记录 修改时间 修改内容等(提交…...
网站建设域名怎么选择/商丘网络推广公司
变量:可以改变的量,具体指的是内存的一段空间 (一)变量的命名 字母数字下划线, 首字符不能为数字 严格区分大小写, 且不能使用关键字 变量命名有意义, 且不能使用中文哦 (二)变量的声明 (1) 分行写 a 1 b 2 print(a,b) (2) 写在一行,用逗号隔开 a,b 3…...
wordpress特色缩略图/百度网站制作
1.1概念Oracle在9i引入了merge命令,通过这个merge你能够在一个SQL语句中对一个表同时执行inserts和updates操作。当然是update还是insert是依据于你的指定的条件判断的,Mergeinto可以实现用B表来更新A表数据,如果A表中没有,则把B表…...
如需手机网站建设/网站的营销推广方案
#服务器重启故障、服务器异常死机故障。#温度过高 会自动关机#CPU内存负载过大会宕机或者重启 1、chkconfig acpid offservice acpid stop 2、vi /boot/grub/grub.conf在kernel一行最后加上acpioff noacip#kernel... acpioff noacip 3、reboot转载于:https://blog.51cto.com/ki…...
永州高端网站建设/酒店seo是什么意思
1、作用 权重分析是通过熵权法对问卷调查的指标的重要性进行权重输出,根据信息熵的定义,对于某项指标,可以用熵值来判断某个指标的离散程度,其信息熵值越小,指标的离散程度越大, 该指标对综合评价的影响&a…...