- 好友
- 6
- 在线时间
- 0 小时
- 最后登录
- 2024-11-18
见习骑士
- UID
- 3102512
- 第纳尔
- 2375
- 精华
- 0
- 互助
- 30
- 荣誉
- 0
- 贡献
- 0
- 魅力
- 74
- 注册时间
- 2019-9-6
鲜花( 54) 鸡蛋( 0)
|
本帖最后由 huagao 于 2024-6-18 14:07 编辑
最近和@战争傀儡阿格兰 讨论自制捏脸界面的时候,顺手翻了一下以前的一些笔记,今天研究了一下关于facekey的一些操作,从此开始细说一下,落笔时尚未完全摸索完毕,但大框架已经探寻的差不多了,剩下的会逐步补充。
一,Facekey的结构
1. 我们首先明确一点,facekey的结构构成并不一定是要64位的十六进制数字的,可以是更多位的一组数字。下面这四个是同一个面部代码,即引擎调用的时候引擎调用的时候从高到低(从左往右)的64位,更低位的会被直接忽略,这个后面有用。
- # 0x00000000160c020136db6db6db6db6db00000000001db6db0000000000000000
- # 0x00000000160c020136db6db6db6db6db00000000001db6db000000000000000000000
- # 0x00000000160c020136db6db6db6db6db00000000001db6db000000000000000012345
- # 0x00000000160c020136db6db6db6db6db00000000001db6db0000000000000000abcde
复制代码
2.在module_skins里面,我们可以看到如下声明,指的是捏脸界面里面右侧滑条从下到上的序号,即界面里面相对代码序号是倒着排列的,这个后面有用。
- chin_size = 0
- chin_shape = 1
- chin_forward = 2
- jaw_width = 3
- jaw_position = 4
- mouth_nose_distance = 5
- mouth_width = 6
- cheeks = 7
- nose_height = 8
- nose_width = 9
- nose_size = 10
- nose_shape = 11
- nose_bridge = 12
- cheek_bones = 13
- eye_width = 14
- eye_to_eye_dist = 15
- eye_shape = 16
- eye_depth = 17
- eyelids = 18
- eyebrow_position = 19
- eyebrow_height = 20
- eyebrow_depth = 21
- eyebrow_shape = 22
- temple_width = 23
- face_depth = 24
- face_ratio = 25
- face_width = 26
复制代码
3.看的出来这些序号的脸部细节对应着facekey里面的一段一段的数值,即每个滑条overlay在click触发器里面获取到的值会被存进新的facekey里面,故而假设我们足够耐心,挨个比对就可以区分出每个脸部细节对应的区间了。
但是如果只是区间比对的话,那获取对应脸部细节的操作只需要除法取商再取余就可以了,完全不需要这两个op
- face_keys_get_morph_key = 2766 # (face_keys_get_morph_key, <destination>, <string_no>, <key_no>), #Stores face key's morph key value (0-7) into <destination>
- face_keys_set_morph_key = 2767 # (face_keys_set_morph_key, <string_no>, <key_no>, <value>), #Sets face key's morph key value (0-7)
复制代码 另外我们可以自行测试,会发现有的位,动不同控件时都会改变,即两个不同控件都会影响到输出的facekay的同一个位上的值,似乎很奇怪,例如:
- # 0x0000000 00 0 0c030136db6db6db6db6db00000000001db6db0000000000000000 (1) 仅对年龄做多次随机选择,输出的facekey
- # 0x0000000 40 0 0c030136db6db6db6db6db00000000001db6db0000000000000000 (2)
- # 0x0000000 70 0 0c030136db6db6db6db6db00000000001db6db0000000000000000 (3)
- # 0x0000000 9c 0 0c030136db6db6db6db6db00000000001db6db0000000000000000 (4)
- # 0x0000000 fc 0 0c030136db6db6db6db6db00000000001db6db0000000000000000 (5)
- # 0x0000000 fd c 0c030136db6db6db6db6db00000000001db6db0000000000000000 (6) 在5的基础上,对发色做随机选择,输出的facekey
- # 0x0000000 ff a 0c030136db6db6db6db6db00000000001db6db0000000000000000 (7)
复制代码 前五条为我们不动其他,仅对年龄做多次随机选择,输出的facekey,很容易会发现第8-9位发生了变化,疑似是第8-9位存放的是年龄的值;
接下来(6)(7)是在(5)的基础上,对发色做两次随机选择,输出的facekey,会发现第9-10位发生了变化。
这里有三个疑点,一个是为什么不同的控件会影响到同一位的数值;另一个是如果两位存放一个脸部细节的话,那么27个脸部细节需要至少54位数参与,但是在我测试的过程中发现有不止10位数都没有参与facekey的输出;以及face keys get/set morph key看似多此一举的两个函数。
这三个疑点直接指向了解决思路:转换进制的位运算。
我将很多测试结果转二进制发现事实上每6个字符控制了1个脸部细节,为了方便理解,我将上述七条例子转四进制展示,并将多余高低位省略,即为:
- # ...000 000 003000030... (1)
- # ...100 000 003000030... (2)
- # ...130 000 003000030... (3)
- # ...213 000 003000030... (4)
- # ...333 000 003000030... (5)
- # ...333 130 003000030... (6)
- # ...333 322 003000030... (7)
复制代码 可以观察到,在(1)到(5)我们只改变年龄的输出结果里面,发生变化的是前三位,而在(5)的基础上改变发色的(6)(7)的输出结果里,发生变化的是后三位。
由此可得,对于“皮肤”,“胡子”,“发型”,“年龄” 等等捏脸界面左侧的控件,facekey的真正结构是每3个十六进制位对应4个不同的脸部细节。
4.关于module_skins里声明的一些东西
module_skins里声明的是捏脸界面右侧从 “面部宽度” 到 “下巴大小” 这些脸部细节,那么为什么这些序号里面没有包括 “皮肤”,“胡子”,“发型”,“年龄” 等等捏脸界面左侧的控件呢?
事实上这两部分的存放方式不一样,module_skins里声明的控件的值另有存放方式(太晚了,先睡觉,明天继续写)
二,Facekey的处理手段(太晚了,先睡觉,明天继续写)
三,Facekey关于自制捏脸界面的一些实现(太晚了,先睡觉,明天继续写)
|
评分
-
查看全部评分
|