Apex NvParameterized

疑问

在看Apex的时候会给破碎模型设置参数,形式如下:

	NvParameterized::setParamBool(*actorDesc, "dynamic", false);
	NvParameterized::setParamBool(*actorDesc, "formExtendedStructures", true);
	NvParameterized::setParamF32(*actorDesc, "supportStrength", 1.9f);
	
	NvParameterized::setParamF32(*actorDesc, "defaultBehaviorGroup.damageThreshold", 5.0f);

很疑惑,为什么要这么做,以及怎么做的?

结构

怎么做到的呢?根据变量的结构,构建一个简单的树形结构Lookup Tree,在此基础上,构建一个字符串对应的树形结构Definition Tree。两颗树形结构的关系一致,根据这个在Definition Tree中找到某个变量的偏移值,就可以在Lookup Tree上找到真正的地址,然后根据类型操作这个地址即可。

Lookup Tree

变量本身的一个树形结构,主要是记录一下某个变量是某个结构体的成员这样的父子关系。这个关系给Definition Tree提供了基础。如下图所示:
Lookup tree

Definition Tree

用变量的结构构造一个字符串对应的树形结构,如下图所示:

definition tree

小结

  • 两棵树的匹配关键是:定义的Children的关系树结构需要完全一样,主要是通过字符串在ParamDefTable中找到offset,然后用这个offset到ParamLookupTable中找到变量的地址以及类型,然后读写这个变量
  • 拿到了指针和类型之后,就把指针强制转换为指定类型,然后设置值了
	Type *Var = (Type *)((char *)ptr);
	*Var = val;
  • 两棵树最大的不同是,Lookup Tree不需要parent的指针关系

创建和使用

创建-构建树

参考存储结构,创建树的时候其实是比较硬核的代码,手K!

  • buildTree
	void DestructibleActorParam::buildTree(void)
	// 定义父节点
	NvParameterized::DefinitionImpl* ParamDef = &ParamDefTable[184];
	ParamDef->init("simulationFilterData", TYPE_STRUCT, "P3FilterData", true);
	// 定义子节点
	NvParameterized::DefinitionImpl* ParamDef = &ParamDefTable[185];
	ParamDef->init("word0", TYPE_U32, NULL, true);
	// 设置父子关系
	static Definition* Children[4];
	Children[0] = PDEF_PTR(185);
	Children[1] = PDEF_PTR(186);
	Children[2] = PDEF_PTR(187);
	Children[3] = PDEF_PTR(188);
	
	ParamDefTable[184].setChildren(Children, 4);

使用-查找树

  • 查找 findParam
    查找的时候会根据longName找到子节点的地址,最主要是拿到offset,因为这个offset是变量树找指针位置用的,为关键点!

  • handle.index
    这个接口是在findParam的时候算出来节点关系,某个子节点在父节点中children数组里面的索引。这个就是用到树的结构,然后查找

总结

  • 这个方式通用性我觉得并不是很强,因为树都是硬编码的。对于用户只是读写来说还好,就只有这么多参数,你就用吧;但是对于其他程序员来使用这个系统的话会很受束缚
  • 树的查找,这里并没有用到二叉树或者BT之类的查找,就把所有的children遍历一遍,应该是量不大,所以随便
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值