软件工具

brew 会员管理系统 iopaint yaml Rider Auto GPT Airtest Stable Diffusion 飞书 Programmer AI Copilot X softwares for windows softwares for website softwares for mac softwares for ios softwares for android Filezilla Cocoapods wireshark pyCharm Microsoft Edge vscode 短信关键字 Ubuntu 阿里云 视频下载 百度贴吧 百度云管家 爬虫 模拟器与手机 晨风QQ机器人 文件下载 按键精灵 抖音 微信 京东 云手机 yarn virtualbox vim truffle tor browser tomcat telegram sqlite3 spine shell shadowsocks scrapy scons rust repo pyenv preact pp助手 phpstorm pgAdmin pear pecl parity nvm npm nginx markdown magnet loadrunner laravel jekyll itunes iPhone heroku govendor google chrome gitlab github git eclipse docker cygwin composer cocos studio cmake carthage batch command apktool apachectl apache adobe photoshop adb aapt ZeroNet Xcode Windows WinHex WebStorm Visual Studio VMware TortoiseSVN ThinkSNS TexturePacker TeamViewer Subversion Sublime Text SourceTree SecureCRT SVN RTX QQ PostgreSQL OpenIM OpenGL Shader Builder OD Notepadplusplus Navicat for MySQL Mono MongoDB MinIO MinGW Microsoft Visual Studio Mac OS X Linux Laradock Kafka Jenkins Genymotion FontCreator ETCD CocosBuilder CentOS Bootstrap Beyond Compare Angular2 Android Studio 3ds Max 360 Visual Studio2010快捷键及设置 ChatGPT HRESULT 0x80004005 E_FAIL 美团开店宝 搜狗输入法 ohmyzsh meson golang mobile library gitea fvm _ WireGuard V2Ray RocketChat Fork Clash _ ChatGPT局限性研究

编程开发

Unity3D 开源项目 Unity3D超链接 Unity3D spine Unity3D shader lua热重载 Bloom chrome extension Particle System Sprite Renderer Overdraw 字体描边 Unity3D热门插件 TronLink Bmfont TextMeshPro Behaviour Tree ThinkPHP ajax Hexagonal Grids python基础知识 python argparse和optparse eth eth layer2 ios点滴积累 exr UGUI优化 lua定义不允许定义变量的class 7za源码 打印堆栈 C C++点滴积累 android基础知识 xLua java基础知识 Unity DOTS Unity3D大规模角色渲染 Flutter metamask andriod源码编译 React Native git as a database android逆向 越狱 ios逆向开发 ipfs链编程 cocos2d-x3.x文字模糊 lua创建class v3quick 智能合约升级方案 gitlab服务器迁移 go调用C++ 区块链编程 cocos2dx lua项目转html5项目 SSL aar转jar unity热更方案 unity升级 源码 反编译获取任何微信小程序源码 基础知识 cocos2dx ipv6支持 ClippingNode sprite的触摸事件 redis 加密算法 protobuf JAR creation failed. See details for additional information cocos2dx内存管理 SDK服务器 vpn服务器搭建 获取焦点 某些android系统下自动优化代码 异常处理 内存泄露分析 代码混淆 生成唯一id oauth2 IIS和tomcat共用80端口 enum MultiValueMap 易语言基础知识 MySQL eclipse的devices上不显示调试程序包名 搭建服务器下载文件 switch case的效率问题 获取版本号和版本名 cocos2d-js js语法 meta-data的获取 cocos2d-js安装 Paper2D rapidjson unreal源码赏析 NEON reload lua scripts go发邮件 smali语法 Spring lua枚举实现 PainTown编译 STL各容器操作 ios性能测试 UI Engines Game Engines Comparison CCActionInterval cocos bugs variadic templates singleton class POSIX g3log 不能在非主线程中使用OpenGL ES的UI函数 Menu get class name based on class #type 宏的含义 类模板的部分特化 各编译器对C++的支持度 Open Source Log Systems Comparison 百度语音识别SDK 锚点anchorPoint Unity3D插件 View Frustum Culling Matrix Layouts, DirectX and OpenGL DirectX基础知识 详解Cocos2d-X中宏CC_DLL android 国际化语言 locale缩写 android error solutions unity调用webservice Unity3D调用C++的dll Unity Error Solutions 非组合BCD码VS组合BCD码 磁盘的磁道(track) use static Variables in static library ndk编译出错-Werror UNICODE字符集之 UTF-8、UTF-16 SpringBoard 无法启动应用程序 -4 Setting up a Code Repository on Google 透视投影变换 编译ogre_src_v1-7-4 windows 编译 ogre 1.9.0 ios undo 绘制次序 纹理寻址模式设置不当 显存带宽 bandwidth 分析碰撞检测库Opcode 《Fighting, Antiquity》遇见的各种问题 send TEXCOORD from DirectX9.0 to HLSL mul(inPos, matViewProjection) and mul(matViewProjection, inPos) A* Pathfinding X File Hierarchy Loading VS高亮HLSL关键字 Umbra 3:次世代的遮挡裁剪 Steering Behaviors For Autonomous Charac Rendering the Great Outdoors/Fast Occlusion Culling for Outdoor Environments Programming OpenGL ES with ios Perlin Noise OpenGL中freeglut的安装 OpenGL OpenGL ES hardware support OgreSDK_vc10_v1-7-4第一次编译程序运行crash Missing texture object named 'Texture0' in pixel shader 'Pixel Shader' in pass 'Pass 1' Loading .x files the easy way Load .obj model Get Texture Coordinates from DirectX in Vertex Shader Fx Composer Effect Framework DirectX 9.0中BeginPass和EndPass放置问题 DirectInput Coding in RenderMonkey Bézier curve Bullet Advanced Collision Detection Techniques 3D游戏引擎中的室外大场景渲染技术研究与实现 3D实时渲染中的BSP树和多边形剔除 fxc的使用及调试技巧 编译注意点 点滴积累 windows搭建android和cocos2dx环境 sprite::create("*.png")崩溃 Unknown EABI object attribute 44 CCUserDefault使用注意点 APP_STL := gnustl_static APP_CPPFLAGS := -frtti APP_CPPFLAGS += -fexceptions #pragma once与 #ifndef的区别 #ifdef _DEBUG 重载识别多重继承 返回值尽量返回const值 缺省实参编译时刻决定 编译器优化 纯虚析构函数必须定义 类继承中调用函数 类模板运用之实现委托类 类模板运用 类模板的友元 类成员函数声明为另外一个类的友元 析构函数出域就析构 指针的运用 成员函数模板和自动转换的选择 成员函数指针的运用 成员函数和非成员函数重载问题 在if里面请写入语句 使得打印出 hello world。 typedef作用 —— 定义机器无关的类型 static_cast注意点 static DWORD成员变量定义 operator<<重载 multimap容器不能用greater_equal case语句内定义变量 boost使用 本地函数定义是非法的 __attribute__ Type Conversion Override controls override and final OSI七层网络模型与TCP:IP四层网络模型 C:C++里面变量名的最大长度是多少? C++模板初始化 .h和.hpp区别 游戏崩溃查找dump crash堆栈信息 未签名的apk无法安装到手机上 延迟执行任务 平台接入 安装apk到手机中,elipse并非完全拷贝整个apk 多线程用多少个线程最合适 使用NDK编译so动态库 中国移动第三方接入 onNewIntent eclipse调试android程序 eclipse下android环境搭建 apk重启程序代码 apk 签名 ant 自动编译 android开发中遇到sqlite3 not found android制作九宫格图 android.database.CursorIndexOutOfBoundsException android 指定类 android ndk 开发之Application.mk android assets常见问题 android 4.0 NetworkOnMainThreadException ZXing竖屏解决(完美版) XP环境下java环境变量配置 Unable to execute dex/Multiple dex files define The nested fileset element is deprectated, use a nested path instead Re-installation failed due to different application signatures. ROM修改 NDK工具之 addr2line NDK和Eclipse的集成 MySQL相关 ListView无法在onCreate的时候getChildCount() JNI运用 Database Design/UUID vs Integer Auto-Increment Android点滴积累 Android查看内存 Android.mk文件详解 Android string Android NDK 官方下载地址 Adding ActionBar Items From Within Your Fragments Activity 生命周期 php环境搭建 Objective-C的方法原型和重载 c#反射机制 .NET入门 mac 下搭建lua环境 objective c点滴积累 OGRE点滴积累 Unity3D点滴积累 Unity3D NGUI lua基础知识 typescript基础知识 solidity基础知识 php基础知识 nodejs基础知识 kotlin基础知识 javascript基础知识 html基础知识 C#基础知识 css基础知识 golang基础知识 破解技术 assembly点滴积累 _ _ Unity3D优化 Unity3D 模型 Unity3D Editor HybridCLR _ _ _ meteor kodi gopeed generative_agents _ VLC Media Player MPV MLN ChatDev _ _ Copay _ _ gradle _ _ _

errors

MacOS 升级BigSur后无法使用git svn Unit php-fpm.service could not be found Uncaught ReferenceError process is not defined Uncaught ReferenceError Buffer is not defined thread.cc Throwing new exception length=433 index=1340 ArrayIndexOutOfBoundsException Provisioning profile doesn't include signing certificate indenting spaces must be used in groups of 2 Nokogiri install failures eth合约报错 xcode __nwlog_err_simulate_crash_libsystem pod生成工程后编译lib The SSL certificate is invalid php编译错误 not a valid ELF invalid resource directory name appcompat_v7 res crunch Invalid Code Signing Entitlements 该文件没有与之关联的程序来执行该操作 dyld Library not loaded rpathlibfmodL a2003- cant connect to MYSQL server on localhost android.view.WindowManager BadTokenException is your activity running android.view.WindowLeaked no suitable device found no device found for connection git push Server error goroutine 1 efrror RPC failed result=18 HTTP code 200 This version of the rendering library is more recent than your err 1005 Can't create table error 150 could not initialize proxy no Session could not execute query nested exception ArtifactDescriptorException Failed to read artifact descriptor is not a valid JNI reference INSTALL_FAILED_DEXOPT brut.androlib.AndrolibException ARSCDecoder.decode error 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序 无法解析 __imp__printf 无法定位程序输入点sdl_strlcpy LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 lwebsockets is not an object file Failed to git submodule update --recursive --init libpng error CgBI unhandled critical chunk symbol not found for architecture armv7 provider: 共享内存提供程序, error: 0 管道的另一端上无任何进程 and sa登陆失败 错误:18456 file is universal 3 slices but does not contain an armv7s slice error 126 无法解析的外部符号:error LNK2019 无法解析的外部符号 RegQueryValueEx、RegCloseKey、RegOpenKeyEx、RegSetValueEx... 无法解析外部符号 __imp__CoUninitialize@0、_TID_D3DRMFrameTransformMatrix 无法解析_c_dfDIMouse、_c_dfDIKeyboard、_DirectInput8Create@20、_c_dfDIJoystick2 无法解析 __imp__ExtractIconW@12、 __imp__ExtractIconW@12 无法打开文件"dxerr9.lib" 无法打开文件 d3dx9.lib 无法启动应用程序 1>------ 已启动生成: 项目: Init Direct3D, 配置: D 1>------ 已启动生成/项目/Font, 配置/Debug Win3 安装DirectXSDK时提示Error Code s1023 不允许使用不完整的类型 warning:DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800 warning MSB8004: Output 目录未以斜杠结尾。此生成实例将添 warning C4996: 'strcpy': This function or variable may be unsafe. warning C4355: “this”: 用于基成员初始值设定项列表 warning C4290: 忽略 C++ 异常规范,但指示函数不是 __declspec(nothrow) warning C4003: “max”宏的实参不足 vs2010出现link2005 static_cast(pStr) release版本下静态链接库无法解析外部符号 pragma warning(disable:4996) gult32.dll gorm查询sqlite3报错 general error c101008a_ Failed to save the updated manifest to the ft2build.h file not found with include, use “quotes” instead error X3025 error LNK2019 __imp__InitCommonControls@0 error LNK2001 无法解析的外部符号_mainCRTStartup error C2443: 操作数大小冲突 crosses initialization cmath(19): error C2061: 语法错误: 标识符“acosf” ava.io.IOException Cannot run program jarsigner.exe __imp__InitCommonControlsEx@4 __imp__EndDialog __gmsl:512:*** non-numeric second argument to `wordlist' function: ''. _ITERATOR_DEBUG_LEVEL”的不匹配项问题 _ITERATOR_DEBUG_LEVEL XCode: duplicate symbol error when using global variable - Stack Overflow Application does not specify an API level requirement! VS2010 fatal error C1902: 程序数据库管理器不匹配;请检查安装 S1023 error on installing DirectX SDK LNK4006 symbol already defined in object; second definition ignored LNK2001 : unresolved externals IDirectSound8无法使用 Failure Reason Message from debugger Terminated due to memory issue DirectX Preview window: WARNING: Pixel shader 'Pixel Shader' cannot be created on hardware rendering COMMON ERROR - python 无法解析的外部符号 __imp__ExtractIconW@12 _

左右互搏

Git Repositories Unity3D GUI 通讯协议 nodejs开源项目 Unity3D逆向工具 ps软件 NFT游戏 开源音乐项目 视频编辑软件 IM React Native Chat Library Messaging server backend go服务框架 浏览器 本地硬盘作服务器 自动按键 接码平台 数据清洗 go library for git go library for android ios React Native Apps Flutter Apps 加密算法 golang logging library python数据库框架 持续集成工具/Continuous integration(CI) 压缩存储 github guis git guis Gateway Server 图床工具 爬虫工具 lua远程调试器 去中心化数据库 去中心化云存储 noserver softwares php数据库框架 无服务器模式 服务器平台 宝塔 域名租用 php框架 文档管理工具 共识机制 库管理工具 区块链平台 量化交易 数字货币资讯软件 扩容方案 Web服务器 包管理工具 Web前端框架 交易所 Wallets DAPP Root工具 通用应用层协议 数据库 开发框架 数字货币 h5引擎 开源云盘 日志统计工具 博彩 团队协作工具 外包平台 ftp工具 remote control softwares log4j与slf4j 翻墙工具VPN scripting language low level graphics library Cygwin MinGW Build Tools 格斗引擎 shader tools UML Books 版本控制软件 开源语音识别库 Physics Engines 远程控制软件 跨平台开发框架 自动测试工具 思维导图 工作流CI CD工具 局域网传输 telegram server go library for server git in go app热更 _ PM常用工具 Optical Character Recognition(OCR) Open Source Video Player Open Source Magnet Websites

数据结构与算法

背包问题 文件读取效率研究 随机选项和宽字符输出 过桥最短时间 输入一个正整数 设计一个程序 表达式求值 罗马数字与整数相互转换 编程求两个矩形的相交矩形 给定一个字串X 砝码称重 母函数问题 模拟实现乘法运算 某人有三个儿子 有一个长度为N的数字串 有5座不同颜色的房子 最长子串 最大子矩阵之和 在字符串S中寻找最 写一个程序 写一个函数 二维数组排序 一个线段随机分成三段能够构成三角形的概率 一个int数组,里面数据无任何限制,要求求出所有这样的数a[i], 其左边的数都小于等于它,右边的数都大于等于它。 能否只用一个额外数组和少量其它空间实现。 How many 0 appears Fabonacci数列定义为 Do remember 骆驼吃香蕉问题 错排原理 逻辑推理宴会握手 输入一个整数n 设计一个系统处理词语搭配问题 设计一个不能被继承的 设七位数是 编写代码把16进制表示的串转换为3进制表示的串 每个飞机只有一个油箱 概率问题 桌面上有24张光滑面扑克牌 根据上排给出十个数 有一个长度为998的数组 有一个复杂链表 有81个选手 有5个人比赛 有2.5亿个整数存放在一个文件中 有10个文件 无限容量的体育馆 数列L中有n个整数 把一个钝角三角形 循环队列 外星人打算将地球用来种蘑菇 在一天的24小时之中 判断另一字符串的所有字母是否在母串中都有 判断一个数是4的整数次幂 全部有火柴根组成 你有一个横6竖6的方格 九宫图解法 两个数组 不能使用库函数 下一个数是什么 一道小学数学题可以证明你是否可以玩股票 一个猜测游戏中 一个文件 一个教授逻辑学的教授 \[约瑟夫环\]n个数字 Longest Common Subsequence Fibonacci 12个高矮不同的人 100层楼 1000瓶药水 0-1背包 随机洗牌:哪种算法正确 求连续自然数平方和的公式 各种算法复杂度比较 教你如何迅速秒杀掉:99%的海量数据处理面试题 _ _

标签

software 152

android 61

andriod源码编译 自制脱壳rom aar转jar JAR creation failed. See details for additional information 获取焦点 某些android系统下自动优化代码 异常处理 内存泄露分析 代码混淆 enum MultiValueMap eclipse的devices上不显示调试程序包名 获取版本号和版本名 js语法 meta-data的获取 smali语法 mobile devices information android 国际化语言 locale缩写 android error solutions 游戏崩溃查找dump crash堆栈信息 未签名的apk无法安装到手机上 延迟执行任务 平台接入 安装apk到手机中,elipse并非完全拷贝整个apk 多线程用多少个线程最合适 使用NDK编译so动态库 中国移动第三方接入 onNewIntent eclipse调试android程序 eclipse下android环境搭建 apk重启程序代码 apk 签名 ant 自动编译 android开发中遇到sqlite3 not found android制作九宫格图 android.database.CursorIndexOutOfBoundsException android 指定类 android ndk 开发之Application.mk android assets常见问题 android 4.0 NetworkOnMainThreadException ZXing竖屏解决(完美版) XP环境下java环境变量配置 Unable to execute dex/Multiple dex files define The nested fileset element is deprectated, use a nested path instead Re-installation failed due to different application signatures. ROM修改 NDK工具之 addr2line NDK和Eclipse的集成 MySQL相关 ListView无法在onCreate的时候getChildCount() JNI运用 Database Design/UUID vs Integer Auto-Increment Android点滴积累 Android查看内存 Android.mk文件详解 Android string Android NDK 官方下载地址 Adding ActionBar Items From Within Your Fragments Activity 生命周期 gradle _
Unit php-fpm.service could not be found Uncaught ReferenceError process is not defined Uncaught ReferenceError Buffer is not defined thread.cc Throwing new exception length=433 index=1340 ArrayIndexOutOfBoundsException Provisioning profile doesn't include signing certificate indenting spaces must be used in groups of 2 Nokogiri install failures eth合约报错 xcode __nwlog_err_simulate_crash_libsystem pod生成工程后编译lib The SSL certificate is invalid php编译错误 not a valid ELF invalid resource directory name appcompat_v7 res crunch Invalid Code Signing Entitlements 该文件没有与之关联的程序来执行该操作 dyld Library not loaded rpathlibfmodL a2003- cant connect to MYSQL server on localhost android.view.WindowManager BadTokenException is your activity running android.view.WindowLeaked no suitable device found no device found for connection git push Server error goroutine 1 efrror RPC failed result=18 HTTP code 200 This version of the rendering library is more recent than your err 1005 Can't create table error 150 could not initialize proxy no Session could not execute query nested exception ArtifactDescriptorException Failed to read artifact descriptor is not a valid JNI reference INSTALL_FAILED_DEXOPT brut.androlib.AndrolibException ARSCDecoder.decode error 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序 无法解析 __imp__printf 无法定位程序输入点sdl_strlcpy LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 lwebsockets is not an object file Failed to git submodule update --recursive --init libpng error CgBI unhandled critical chunk symbol not found for architecture armv7 provider: 共享内存提供程序, error: 0 管道的另一端上无任何进程 and sa登陆失败 错误:18456 file is universal 3 slices but does not contain an armv7s slice HRESULT 0x80004005 E_FAIL error 126 无法解析的外部符号:error LNK2019 无法解析的外部符号 RegQueryValueEx、RegCloseKey、RegOpenKeyEx、RegSetValueEx... 无法解析外部符号 __imp__CoUninitialize@0、_TID_D3DRMFrameTransformMatrix 无法解析_c_dfDIMouse、_c_dfDIKeyboard、_DirectInput8Create@20、_c_dfDIJoystick2 无法解析 __imp__ExtractIconW@12、 __imp__ExtractIconW@12 无法打开文件"dxerr9.lib" 无法打开文件 d3dx9.lib 无法启动应用程序 1>------ 已启动生成: 项目: Init Direct3D, 配置: D 1>------ 已启动生成/项目/Font, 配置/Debug Win3 安装DirectXSDK时提示Error Code s1023 不允许使用不完整的类型 warning:DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800 warning MSB8004: Output 目录未以斜杠结尾。此生成实例将添 warning C4996: 'strcpy': This function or variable may be unsafe. warning C4355: “this”: 用于基成员初始值设定项列表 warning C4290: 忽略 C++ 异常规范,但指示函数不是 __declspec(nothrow) warning C4003: “max”宏的实参不足 vs2010出现link2005 static_cast(pStr) release版本下静态链接库无法解析外部符号 pragma warning(disable:4996) gult32.dll gorm查询sqlite3报错 general error c101008a_ Failed to save the updated manifest to the ft2build.h file not found with include, use “quotes” instead error X3025 error LNK2019 __imp__InitCommonControls@0 error LNK2001 无法解析的外部符号_mainCRTStartup error C2443: 操作数大小冲突 crosses initialization cmath(19): error C2061: 语法错误: 标识符“acosf” ava.io.IOException Cannot run program jarsigner.exe __imp__InitCommonControlsEx@4 __imp__EndDialog __gmsl:512:*** non-numeric second argument to `wordlist' function: ''. _ITERATOR_DEBUG_LEVEL”的不匹配项问题 _ITERATOR_DEBUG_LEVEL XCode: duplicate symbol error when using global variable - Stack Overflow Application does not specify an API level requirement! VS2010 fatal error C1902: 程序数据库管理器不匹配;请检查安装 S1023 error on installing DirectX SDK LNK4006 symbol already defined in object; second definition ignored LNK2001 : unresolved externals IDirectSound8无法使用 Failure Reason Message from debugger Terminated due to memory issue DirectX Preview window: WARNING: Pixel shader 'Pixel Shader' cannot be created on hardware rendering COMMON ERROR - python 无法解析的外部符号 __imp__ExtractIconW@12 _
Behaviour Tree Hexagonal Grids 背包问题 域名 ipa重新打包 苹果过审 cocos2dx ipv6支持 redis 加密算法 protobuf 生成唯一id 文件读取效率研究 随机选项和宽字符输出 过桥最短时间 输入一个正整数 设计一个程序 表达式求值 罗马数字与整数相互转换 编程求两个矩形的相交矩形 给定一个字串X 砝码称重 母函数问题 模拟实现乘法运算 某人有三个儿子 有一个长度为N的数字串 有5座不同颜色的房子 最长子串 最大子矩阵之和 在字符串S中寻找最 写一个程序 写一个函数 二维数组排序 一个线段随机分成三段能够构成三角形的概率 一个int数组,里面数据无任何限制,要求求出所有这样的数a[i], 其左边的数都小于等于它,右边的数都大于等于它。 能否只用一个额外数组和少量其它空间实现。 How many 0 appears Fabonacci数列定义为 Do remember 骆驼吃香蕉问题 错排原理 逻辑推理宴会握手 输入一个整数n 设计一个系统处理词语搭配问题 设计一个不能被继承的 设七位数是 编写代码把16进制表示的串转换为3进制表示的串 每个飞机只有一个油箱 概率问题 桌面上有24张光滑面扑克牌 根据上排给出十个数 有一个长度为998的数组 有一个复杂链表 有81个选手 有5个人比赛 有2.5亿个整数存放在一个文件中 有10个文件 无限容量的体育馆 数列L中有n个整数 把一个钝角三角形 循环队列 外星人打算将地球用来种蘑菇 在一天的24小时之中 判断另一字符串的所有字母是否在母串中都有 判断一个数是4的整数次幂 全部有火柴根组成 你有一个横6竖6的方格 九宫图解法 两个数组 不能使用库函数 下一个数是什么 一道小学数学题可以证明你是否可以玩股票 一个猜测游戏中 一个文件 一个教授逻辑学的教授 \[约瑟夫环\]n个数字 Longest Common Subsequence Fibonacci 12个高矮不同的人 100层楼 1000瓶药水 0-1背包 正则表达式 随机洗牌:哪种算法正确 求连续自然数平方和的公式 各种算法复杂度比较 教你如何迅速秒杀掉:99%的海量数据处理面试题 _
exr xLua Paper2D rapidjson unreal源码赏析 NEON PainTown编译 scripting language low level graphics library 格斗引擎 ios性能测试 UI Engines Game Engines Comparison g3log Open Source Log Systems Comparison View Frustum Culling Matrix Layouts, DirectX and OpenGL DirectX基础知识 Physics Engines 透视投影变换 编译ogre_src_v1-7-4 windows 编译 ogre 1.9.0 ios undo 绘制次序 纹理寻址模式设置不当 显存带宽 bandwidth 分析碰撞检测库Opcode 《Fighting, Antiquity》遇见的各种问题 send TEXCOORD from DirectX9.0 to HLSL mul(inPos, matViewProjection) and mul(matViewProjection, inPos) A* Pathfinding X File Hierarchy Loading VS高亮HLSL关键字 Umbra 3:次世代的遮挡裁剪 Steering Behaviors For Autonomous Charac Rendering the Great Outdoors/Fast Occlusion Culling for Outdoor Environments Programming OpenGL ES with ios Perlin Noise OpenGL中freeglut的安装 OpenGL OpenGL ES hardware support OgreSDK_vc10_v1-7-4第一次编译程序运行crash Missing texture object named 'Texture0' in pixel shader 'Pixel Shader' in pass 'Pass 1' Loading .x files the easy way Load .obj model Get Texture Coordinates from DirectX in Vertex Shader Fx Composer Effect Framework DirectX 9.0中BeginPass和EndPass放置问题 DirectInput Coding in RenderMonkey Bézier curve Bullet Advanced Collision Detection Techniques 3D游戏引擎中的室外大场景渲染技术研究与实现 3D实时渲染中的BSP树和多边形剔除 fxc的使用及调试技巧 OGRE点滴积累

java 59

java基础知识 andriod源码编译 aar转jar JAR creation failed. See details for additional information 获取焦点 某些android系统下自动优化代码 异常处理 内存泄露分析 代码混淆 enum MultiValueMap eclipse的devices上不显示调试程序包名 获取版本号和版本名 js语法 meta-data的获取 smali语法 mobile devices information android 国际化语言 locale缩写 android error solutions 游戏崩溃查找dump crash堆栈信息 未签名的apk无法安装到手机上 延迟执行任务 平台接入 安装apk到手机中,elipse并非完全拷贝整个apk 多线程用多少个线程最合适 使用NDK编译so动态库 中国移动第三方接入 onNewIntent eclipse调试android程序 eclipse下android环境搭建 apk重启程序代码 apk 签名 ant 自动编译 android开发中遇到sqlite3 not found android制作九宫格图 android.database.CursorIndexOutOfBoundsException android 指定类 android ndk 开发之Application.mk android assets常见问题 android 4.0 NetworkOnMainThreadException ZXing竖屏解决(完美版) XP环境下java环境变量配置 Unable to execute dex/Multiple dex files define The nested fileset element is deprectated, use a nested path instead Re-installation failed due to different application signatures. ROM修改 NDK工具之 addr2line NDK和Eclipse的集成 MySQL相关 ListView无法在onCreate的时候getChildCount() JNI运用 Database Design/UUID vs Integer Auto-Increment Android点滴积累 Android查看内存 Android.mk文件详解 Android string Android NDK 官方下载地址 Adding ActionBar Items From Within Your Fragments Activity 生命周期

X File Hierarchy Loading

2014年09月04日

Introduction to X file loading {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; BACKGROUND-COLOR: #b7b4df; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 16pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

This page describes how you can load mesh data in the x file format maintaining a mesh hierarchy. If you are not interested in keeping the hierarchy you can simply use the D3DXLoadMeshFromX set of functions that are described in the X File Simple notes. However if you wish to implement animation or skinning you will need to read on. These notes are meant to be read in conjunction with the demo application.

Note that if you do not wish to implement this code I have written a small library to do it for you. See the XAnimator page.

Demo Application (with source code) {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; BACKGROUND-COLOR: #b7b4df; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 16pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

New: updated August 2010 to include some fixes I discovered while creating XAnimator. These include the ability to handle multiple skinned mesh and some bug fixes

Updated demo code download: XFileAnimationCode.rar

The demo has the following features

  • Loads x files and maintains their hierarchy (press L to load)

  • Handles animation and allows merging between animations.

  • Handles skinning with software rendering.

The bouncy skinned model was created using 3DS Max. The process of creating it and exporting it as a DirectX x file is described in more detail here: Art Creation.The demo has a couple of limitations: it does not load effect files that are referenced in the x file and it does not do hardware skinning (it uses software skinning).

Contents {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 12pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

Hierarchy Concept {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; BACKGROUND-COLOR: #b7b4df; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 16pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

In order to animate our 3D models we need to maintain a model hierarchy. The hierarchy consists of frames containing matrix and mesh data for different parts of the model (when skinning these frames are seperate from the mesh and known as bones).

E.g. if we had a 3D model of the human body it might be divided into head, body, arms and legs. The body might be the top frame with each part in frames below defining their own matrix and mesh data. The frame matrix provides the offset position and orientation from the body matrix.


skeleton ———————————————————————————–

Ignoring the legs and head the hierarchy for the above may look like this:


skeleton hierarchy ————————————————————————————————————-

\

When rendering we start from the top and recursively travel down through the hierarchy. Each frame has an associated matrix, so you can see that by altering the rotation of the left arm frame all the upper and lower arm are also rotated. Note: in skinning frames are called bones and there tends to be just one mesh controlled by these bones.

When the model is positioned in the 3D world the first frame (known as the root) is transformed to the correct position. Each part of the model is positioned based on the frame matrix translating and rotating it from the frame above. By maintaining this structure we can animate parts of the model simply by altering one frame matrix. We could name frames in our 3D package and then use the names in our code to find the correct frames to animate. Alternatively we can create animation in our 3D package and load it into our game and use the D3DX helper functions to animate it. This process is described in LINK below.

Loading the X File {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; BACKGROUND-COLOR: #b7b4df; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 16pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

The main method for loading animation data, skin info and hierarchy is D3DXLoadMeshHierarchyFromX.

Note: there is another similar function called D3DXLoadSkinMeshFromXof which loads from a ID3DXFileData object. We could load the x file data into our own formats and bypass the Direct3D functionality using this object and the ID3DXFileEnumObject. This method is not covered by these notes but if you interested there is an article on Gamedev about this (see further reading).

The D3DXLoadMeshHierarchyFromX function {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 12pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

HRESULT D3DXLoadMeshHierarchyFromX( \ LPCTSTR Filename, \ DWORD MeshOptions,\ LPDIRECT3DDEVICE9 pDevice,\ LPD3DXALLOCATEHIERARCHY pAlloc,\ LPD3DXLOADUSERDATA pUserDataLoader,\ LPD3DXFRAME* ppFrameHeirarchy,\ LPD3DXANIMATIONCONTROLLER* ppAnimController );

  • Filename - the file name of the .x file to be loaded

  • MeshOptions - various options can be specified here defining creation.

  • pDevice - a D3D Device pointer.

  • pAlloc - allows you to specify a class that will handle the allocation of memory for all the frames and mesh data. More on this below.

  • pUserDataLoader - as mentioned previously the .x file format is highly flexible using a template system to define data chunks. If you add your own templates you can specify a class here that knows how to load your specific data. If you do not use this then you can ignore it and set it to 0.

  • ppFrameHeirarchy - once loading complete this points to the top of the loaded frame hierarchy.

  • ppAnimController - once loading complete this points to an animation controller containing animation data loaded from the x file (if it has any). The animation section describes this.

Before calling this function we need to create a ID3DXAllocateHierarchy** **derived class to handle the creation of memory for our frame and mesh data. This is where a lot of our work will take place. ID3DXAllocateHierarchy is an interface class that defines the functions we must implement. We must implement the following functions:

  1. CreateFrame - requests allocation of a frame object

  2. CreateMeshContainer - requests allocation of a mesh container object

  3. DestroyFrame - deallocation of frame object

  4. DestroyMeshContainer - deallocation of mesh container object

These will be called during the internal processing of the x file carried out by the D3DXLoadMeshHierarchyFromX function. The header for our class will look like this:

class CMeshHeirarchy : public ID3DXAllocateHierarchy\ {\ public:\ // The format of these interfaces is defined by D3DXLoadMeshHierarchyFromX\ \ // callback to create a D3DXFRAME derived object and initialize it\ STDMETHOD( CreateFrame )( THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame );\ \ // callback to create a D3DXMESHCONTAINER derived object and initialise it\ STDMETHOD( CreateMeshContainer )( THIS_ LPCSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL * pMaterials, CONST D3DXEFFECTINSTANCE * pEffectInstances, DWORD NumMaterials, CONST DWORD * pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER * ppNewMeshContainer );\ \ // callback to release a D3DXFRAME derived object\ STDMETHOD( DestroyFrame )( THIS_ LPD3DXFRAME pFrameToFree );\ \ // callback to release a D3DXMESHCONTAINER derived object\ STDMETHOD( DestroyMeshContainer )( THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree );\ };

The implementation of each of these functions is described below and can be seen, in full, in the sample code.

CreateFrame {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 12pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

This function is called during processing of the .x file by the D3DXLoadMeshHierarchyFromX call when a new frame is encountered. If you look back at the diagram above you can see that a frame contains either other frames (children or siblings,which is accessed by pFrameFirstChild or pFrameSibling) and / or the mesh data itself(stored in pMeshContainer). By maintaining this hierarchy we can carry out animation and other functions on our mesh data.

This function is called with a frame name and requires us to create a frame in memory. This memory is returned to the caller via the ppNewFrame parameter. Therefore we will need to look at this frame structure in more detail.

The D3DXFRAME Structure

This is a structure provided by Direct3D to hold information for a frame in our hierarchy. It contains all the basic data required:

  • LPSTR Name - the frame name

  • D3DXMATRIX TransformationMatrix - a transformation matrix that should be applied to this and child frames

  • LPD3DXMESHCONTAINER pMeshContainer - if this frame has mesh data this will point to a container of mesh data.

  • D3DXFRAME *pFrameSibling - if this frame has a sibling this points to it

  • D3DXFRAME *pFrameFirstChild - if this frame has a child this points to it

When we come to render our mesh hierarchy we will traverse the frame tree applying each frame transformation matrix and rendering our mesh data. We will combine transformation matrix as we go down the hierarchy. This allows us to, for example, move the top part of the arm and have the lower part and hand and fingers all transform accordingly. It is useful therefore to also maintain a combined transformation matrix per frame (updated during our FrameMove function). This information is not held in the frame structure but we can extend the structure ourselves and add this bit of data:

struct D3DXFRAME_DERIVED: public D3DXFRAME\ {\ D3DXMATRIXA16 exCombinedTransformationMatrix;\ };

You could of course add more data if required for a particular purpose.

Note: Direct3D provides a number of functions for working with frame hierarchies like D3DXFrameDestroy,
D3DXFrameFind,D3DXFrameCalculateBoundingSphere etc.

CreateMeshContainer {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 12pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

This function is called during processing of the x file by the D3DXLoadMeshHierarchyFromX call when mesh data is encountered. This function is called with a large number of parameters:

HRESULT CreateMeshContainer(\ LPCSTR Name,\ const D3DXMESHDATA *pMeshData,\ const D3DXMATERIAL *pMaterials,\ const D3DXEFFECTINSTANCE *pEffectInstances,\ DWORD NumMaterials,\ const DWORD *pAdjacency,\ LPD3DXSKININFO pSkinInfo,\ LPD3DXMESHCONTAINER *ppNewMeshContainer);

  • Name - name of the mesh

  • pMeshData - pointer to a mesh data structure containing details on this mesh

  • pMaterials - an array of material structures describing the materials used by this mesh

  • pEffectInstances - array of effect instance structures used by this mesh

  • NumMaterials - number of materials in the mesh

  • pAdjacency - array of adjacency information for the mesh

  • pSkinInfo - if the mesh uses skinning this points to an ID3DXSkinInfo object containing skinning data

  • ppNewMeshContainer - once we have created a mesh container we return the pointer via this parameter

All but the last parameter are input data defining the mesh. Our function needs to take this data and create and return a new mesh container structure. This is a Direct3D provided structure and is described below:

The D3DXMESHCONTAINER structure

This is a structure provided by D3D to hold information about a mesh in our hierarchy. The data is:

  • LPSTR Name - the mesh name

  • D3DXMESHDATA MeshData - a structure containing the mesh triangle data itself in one of the D3DX mesh interface objects (ID3DXMesh, ID3DXPMesh orID3DXPatchMesh)

  • LPD3DXMATERIAL pMaterials - array of mesh materials (we will not use this) *

  • LPD3DXEFFECTINSTANCE pEffects - array of effect instances

  • DWORD NumMaterials - number of materials

  • DWORD *pAdjacency - adjacency information

  • LPD3DXSKININFO pSkinInfo - skinning information

  • D3DXMESHCONTAINER *pNextMeshContainer - pointer to a sibling mesh structure

It is our responsibility to allocate and fill out this structure. It is not as complex as it may look at first as a lot of this information can be directly copied from the data that is passed to us. Note: we must make a copy of this data i.e. we must leave the caller data alone.

MyView:so ga, each bone node container multiply meshes, which is stored in D3DXMESHCONTAINER(it is a container of meshes.), and each frame has a sibiling or child.

As with the D3DXFRAME structure we can add more information to this structure based on our application needs. We will normally load any textures specified for this mesh and so the addition of a texture pointer is useful. Other information commonly added includes skinning data. The structure used in the demo is shown below:

struct D3DXMESHCONTAINER_EXTENDED: public D3DXMESHCONTAINER\ {\ IDirect3DTexture9** exTextures; // Array of texture pointers \ D3DMATERIAL9* exMaterials; // Array of materials\ \ // Skinned mesh variables\ ID3DXMesh* exSkinMesh; // The skin mesh\ D3DXMATRIX* exBoneOffsets; // The bone matrix Offsets\ D3DXMATRIX** exFrameCombinedMatrixPointer; // Array of frame matrix\ };

The base D3DXMESHCONTAINER has a pMaterials member which is a D3DXMATERIAL structure that contains a texture filename and material data. It is easier to ignore this and instead store the data in arrays of created textures and materials in our derived structure (exTextures and exMaterials).

The final three variables are for skinning purposes only and are described in the section on skinning below.

DestroyFrame and DestroyMeshContainer {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 12pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

These functions should deallocate the memory we created in the above two functions. They are invoked when we destroy the frame hierarchy. This is achieved using the D3DXFrameDestroy function. Look at the demo code for the implementation.

Rendering the Hierarchy {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; BACKGROUND-COLOR: #b7b4df; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 16pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

After loading the x file we have our hierarchy loaded in as a tree of frames and mesh data (like the diagram). We hold a pointer to the top of our frame hierarchy (returned from D3DXLoadMeshHierarchyFromX in the ppFrameHeirarchy \ pointer). In addition, if our x file contained animation, we have a pointer to an animation controller (returned from \ D3DXLoadMeshHierarchyFromX in the ppAnimController pointer).

I will look first at how we can render this hierarchy without animation or skinning. I will talk about animation and skinning later.

Rendering the Hierarchy {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 12pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

To render the model with a hierarchy involves traversing the hierarchy maintaining matrix and rendering mesh as we encounter them. At regular intervals the demo calls CXFileEntity::UpdateFrameMatrices in order to calculate the combined matrix for each frame in the hierarchy. This could be done in the render function itself but later on we will also want to handle animation so we keep this separate.

The function Render simply calls DrawFrame with the topmost frame in the hierarchy. DrawFrame renders any mesh that it owns via a call to DrawMeshContainer. Then if the frame has any siblings it recursively calls DrawFrame with them (these calls will only return once that branch has been completed) and then any child frames.

Animation {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; BACKGROUND-COLOR: #b7b4df; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 16pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

As already mentioned if we have a model hierarchy we can carry out animation simply by altering a frame matrix. E.g. if we alter a shoulder matrix then the rest of the arm below will be transformed as well.

The provided x file bones_all.x contains a number of animation sets that is worth viewing while understanding these notes.

In Direct3D animation is held in animation sets maintained by an animation controller object. This is passed initially to our application in the D3DXLoadMeshHierarchyFromX function (m_animController). This controller wraps a lot of the functionality required to carry out animation.

In FrameMove we tell the animation controller what time it is by calling AdvanceTime. This allows the controller to determine the matrices for each frame in our hierarchy at that particular time. The frame controller will alter the frame matrices (the TransformationMatrix held in the frame structure) and when we update our frame hierarchy matrices during UpdateFrameMatrices we use this new matrix to create our combined frame matrix. The controller object carries out interpolation of matrix between key frames for us.

We can change which animation set is active by calling the frame controller SetTrackAnimationSet** **with the new animation set. First of all we have to retrieve this set via a call to GetAnimationSet.

Switching between animations abruptly would look wrong. Imagine our skeleton went from running to dying - the arms and legs etc, would suddenly change position. So Direct3D provides a way of interpolating into the new animation smoothly.

This is achieved via the use of tracks. Our current track is running the original animation so we use a second track for our new animation. We slowly fade out the effect of the first animation and fade in the second. We do this by inserting keys into the track using the animation controller functions. We can turn tracks on and off, change the track speed and change how much that track effects the animation (via a weighting value).

This process can be seen in the demo code SetAnimationSet function. The speed with which the transition between animations occurs is held in a global constant variable: kMoveTransitionTime. To understand how this process works try changing this value. Setting it to a higher value will slow down the transition and help you to see what is happening.

Note: the provided file bones_all.x has a number of animation sets that were added using the Mesh View tool from the SDK. If you have a number of .x files produced from an art package with the same model but different animations you can combine them into one using the Mesh View tool or do it programmatically using the animation controller \ RegisterAnimationSet unction.

Skinning {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; BACKGROUND-COLOR: #b7b4df; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 16pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

Introduction to Skinning {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 12pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

Skinning takes data in a mesh-skeleton hierarchy and applies geometry blending to transform the mesh vertices. Skinning uses a set of interconnected bones (frames) that form a hierarchy as shown above. When bones are moved or rotated the mesh surface moves or rotates accordingly (like skin does). The mesh surface is simply described with vertices forming triangles and so skinning works by altering the vertex position dependant on the bones attached to it. If you run the demo and turn on wireframe mode you can see how the vertex positions are altered.

If you think about the skin on your elbow it is affected both by the movement of the lower arm and the movement of the upper arm. Hence the position of the elbow vertices depends on two inputs (bones). The transformation of the vertices is calculated by combining a matrix from the upper arm with the one from the lower arm. How much each matrix affects each vertex is controlled by a blending weight.

Advanced: the actual geometry blending operation applies each bones matrix to the vertices to create a number of differently positioned vertices and then interpolates between them based on the blending weight.

Skinned Mesh Matrices {style=”LINE-HEIGHT: normal; WIDOWS: 2; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; TEXT-INDENT: 0px; FONT-FAMILY: ‘Times New Roman’, Times, serif; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: #000000; FONT-SIZE: 12pt; WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px”}

The skeleton is a hierarchical set of bones. Each bone has a matrix which translates and rotates that bone relative to its parent (this is just the same process as the frame hierarchy discussed above but the mesh is normally separate to the hierarchy). Since the matrix are relative to the parent rather than the character itself we say they are defined in bone space. We want to place the bones relative to the character itself so must convert these matrices into character space(角色空间) by combining them with their parent matrix.

We add a variable to our extended mesh container structure for this combined matrix (called exFrameCombinedMatrixPointer- one entry per bone). Since we already maintain a combined matrix for each frame in the hierarchy (exCombinedTransformationMatrix) we do not need to duplicate it therefore our exFrameCombinedMatrixPointer is an array of pointers to the correct frames’ exCombinedTransformationMatrix. Finding the correct frame is carried out during SetupBoneMatrices using the Direct3D D3DXFrameFind function.

Combined Bone Matrix = Local Bone Matrix * Parent Combined Bone Matrix.

There is one further matrix required when doing skinning and that is a matrix to connect the bones to the mesh, this is known as a bone offset matrix. We add this to our structure as exBoneOffsets. These are assigned during the\ CMeshHierarchy::CreateMeshContainer function - one per bone. This allows us to create our final matrix:

Final Bone Matrix = Bone Offset Matrix * Combined Bone Matrix

This final matrix transforms the mesh into bone space then applies the bone matrix to the mesh. This is calculated during the frame move function and fed into the UpdateSkinnedMesh function.

Note: the amount each vertex is affected by the bones is determined by a weighting. This is contained in the ID3DXSKININFO object and is automatically calculated into the equation for us by the function UpdateSkinnedMesh.

To summarise this rather complicated process: we have a mesh that needs to be altered based on a skeleton hierarchy of bones (frames). Each bone is positioned and oriented to its parent via a local bone matrix. We store a pointer to the correct frames combined matrix in our mesh container structure (exFrameCombinedMatrixPointer). In order to wrap the mesh skin around the bones we use a bone offset matrix. By combining these two matrices we can create a final matrix that can be fed into the Direct3D UpdateSkinnedMesh function. This function will alter the mesh vertices based on the matrix and a set of weights to carry out the actual skinning.

Skinning Mesh Rendering

There are a number of methods of carrying out skinning with Direct3D. The demo code uses software skinning but there are other methods that use hardware acceleration for greater speed. The Skinned Mesh sample that comes with the DirectX SDK describes three other methods: Fixed Function Non Indexed Skinning, Fixed Function Indexed Skinning and Shader Based Skinning.

The software skinning method used by the demo is carried out in FrameMove. The process is:

/* Create the bone matrices that transform each bone from bone space into character space (via exFrameCombinedMatrixPointer) and also wraps the mesh around the bones using the bone offsets in exBoneOffsetsArray */\ \ for (UINT i = 0; i < Bones; ++i)\

D3DXMatrixMultiply(&m_boneMatrices[i],&pMesh->exBoneOffsets[i],</span>

pMesh->exFrameCombinedMatrixPointer[i]);\ \ void *srcPtr;\ pMesh->MeshData.pMesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&srcPtr);\ \ void *destPtr;\ pMesh->exSkinMesh->LockVertexBuffer(0, (void**)&destPtr);\ \ // Update the skinned mesh \ pMesh->pSkinInfo->UpdateSkinnedMesh(m_boneMatrices, NULL, srcPtr, destPtr);\ \ // Unlock the meshes vertex buffers\ pMesh->exSkinMesh->UnlockVertexBuffer();\ pMesh->MeshData.pMesh->UnlockVertexBuffer();

We lock the vertex buffer of our original unaltered mesh for read. We also lock the vertex buffer of the destination mesh vertices to write into (this is why we stored a copy of the mesh in our D3DXMESHCONTAINER_EXTENDED structure. It was copied during SetupBoneMatrices). We then call the Direct3D UpdateSkinnedMesh function which takes the transformation matrices and our locked vertex buffers and carries out the skinning. It does this by combining the matrix and a set of bone weights to alter the position of the original vertices and write them into the output buffer.

Locking vertex buffers is to be avoided as much as possible if we want our graphic card to work at maximum speed. A lock can cause a stall in the graphics processing leading to slow down. To avoid this there are a number of methods that use the hardware to carry out the skinning itself. As previously mentioned these methods are beyond the scope of these notes (for the time being - I may add notes on them later) and if you are interested I suggest you look at the skinned mesh sample that comes with the DirectX SDK.