gamebryo--NiStream和NiMesh和NiMeshModifier的关系

GB里面的自定义几何体几乎都是用NiMesh。要添加程序方式的数据的时候需要用到。

比如编辑器的刷水。就需要程序动态产生。

首先定义Mesh的图元方式

NiMesh* pkMesh = NiNew NiMesh();

pkMesh->SetPrimitiveType();

接着为这个Mesh绑定数据流这样是保证了Mesh的可编辑可变。因为到时候你改变数据流的数据就OK.也就是数据和封装的问题.

数据流可以用2个方式去创建

如果你的数据流是公共的。那么可以

NiDataStream::CreateSingleElementDataStream 记录下返回的数据流。其他mesh用了还可以用。

pkMesh->AddStreamRef(pkDataStream , NiCommonSemantics::POSITION(), 0); 这样可以把数据流和Mesh的一个属性绑定.

当然如果你的数据流不需要和别人分享也可以

pkMesh->AddStream 直接加一个。两个差不多的.

要修改流数据怎么修改呢?

NiDataStreamLock。 NiDataStreamElementLock, NiDataStreamPrimitiveLock 等锁了以后就可以了。其实就是dx的vectexBuffer等等的封装和lock

 

NiMeshModifier 的使用和原理:

每一个Mesh都可以为其实现一个MeshModifier用来改变他morphing.GB推荐尽量的用这个修改器来调正Mesh让变动起来。而且推荐变形器用Floodgate来做。Floodgate是一个平行处理系统。他会根据当前你有多少cpu或者gpu来平行的处理一些数据。这个是非常高效的。也是非常有前瞻性的。Floodgate再写一篇详细的吧。现在不管。

要实现一个Modifier需要实现4-6个函数:之所以说4-6是因为最后2个函数在工具里才需要实现。

  • virtual bool Attach()

  • virtual bool Detach()

  • virtual bool SubmitTasks()

  • virtual bool CompleteTasks()

  • virtual bool AreRequirementsMet() const

  • virtual void RetrieveRequirements() const

  • Attach的作用是把修改器和Mesh绑定。同时做一些数据的初始化.

    修改器通过NiSPTask(有SP就说明用floodgate),NiSPStram,NiSPWorkflow,NiSPKenerl等来处理数据。

    每一个Kenerl应该有很多task而这些task由workflow来分配管理。每一个任务完成都是把wordflow的引用计数降低。如果workflow为NULL了说明所有task完成了。可以提交下一步了。

    所有的数据要在Attach的是时候加载和分配。在Detach的时候释放回收。

    SubmitTask提交任务。让floodgate处理。但是每一个submitTask的任务。必须是complete的。如果没有完成的任务是不会submit成功了。可以主动调用complete去完成他。

    RetrieveRequirements在工具里可能经常会反复操作。用来重新请求一次任务。

    AreRequirementsMet用来判断当前的数据。结构是否是正确的。用来判断为何modifier工作不正确。

    细看一下流程:

    首先需要在attach的时候定义这个修改器正式计算的同步点

    AddSubmitSyncPoint, AddCompleteSyncPoint 有很多参数可选。

    设置好同步点后。设置输入和输出

    NiSPTask::GetNewTask 可以指定有几个流输入几个输出

     NiDataStreamRef*pkDSRef = pkMesh->FindStreamRef(NiCommonSemantics::POSITION(), 0);
      NIASSERT(pkDSRef);
      m_pkOutputPositionsSPStream = NiNew NiTSPStream<NiPoint3>;
      m_pkOutputPositionsSPStream->SetDataSource(pkDSRef->GetDataStream());
      m_pkOutputPositionsSPStream->SetBlockCount(pkDSRef->GetTotalCount());
      m_spTask->AddOutput(m_pkOutputPositionsSPStream);

    如上方式设置每一个输出数据

    m_spTask->AddInput类似的定义输入

    可以指定数据是否是压缩过的SetIsCompacted 如果我们输出输入不改变数据流。那么可以指定为压缩。具体为啥还没看

    然后设置什么时候提交。根据你的同步点来决定

    NiUInt32 uiTaskGroup = NiSyncArgs::GetTaskGroupID(NiSyncArgs::SYNC_VISIBLE, NiSyncArgs::SYNC_RENDER);
    m_spWorkflow = pkWFManager->AddRelatedTask(m_spTask, uiTaskGroup, false);

    当你设置的状态来了。可以把这个任务正式加入。就可以提交去处理了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值