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);当你设置的状态来了。可以把这个任务正式加入。就可以提交去处理了。