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);
當你設置的狀態來了。可以把這個任務正式加入。就可以提交去處理了。