00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef NVBLASTFAMILY_H
00030 #define NVBLASTFAMILY_H
00031
00032
00033 #include "NvBlastAsset.h"
00034 #include "NvBlastPreprocessor.h"
00035 #include "NvBlastDLink.h"
00036 #include "NvBlastAtomic.h"
00037 #include "NvBlastMemory.h"
00038
00039 #include <cstring>
00040
00041
00042 struct NvBlastAsset;
00043
00044
00045 namespace Nv
00046 {
00047 namespace Blast
00048 {
00049
00050
00051 class FamilyGraph;
00052 class Actor;
00053 class Asset;
00054
00055
00061 struct FamilyHeader : public NvBlastDataBlock
00062 {
00066 NvBlastID m_assetID;
00067
00074 NvBlastBlockArrayData(Actor, m_actorsOffset, getActors, m_asset->m_graph.m_nodeCount);
00075
00081 NvBlastBlockArrayData(IndexDLink<uint32_t>, m_visibleChunkIndexLinksOffset, getVisibleChunkIndexLinks, m_asset->m_chunkCount);
00082
00088 NvBlastBlockArrayData(uint32_t, m_chunkActorIndicesOffset, getChunkActorIndices, m_asset->m_firstSubsupportChunkIndex);
00089
00095 NvBlastBlockArrayData(uint32_t, m_graphNodeIndexLinksOffset, getGraphNodeIndexLinks, m_asset->m_graph.m_nodeCount);
00096
00104 NvBlastBlockArrayData(float, m_lowerSupportChunkHealthsOffset, getLowerSupportChunkHealths, m_asset->getLowerSupportChunkCount());
00105
00113 float* getSubsupportChunkHealths() const
00114 {
00115 NVBLAST_ASSERT(m_asset != nullptr);
00116 return (float*)((uintptr_t)this + m_lowerSupportChunkHealthsOffset) + m_asset->m_graph.m_nodeCount;
00117 }
00118
00124 NvBlastBlockArrayData(float, m_graphBondHealthsOffset, getBondHealths, m_asset->getBondCount());
00125
00132 NvBlastBlockData(FamilyGraph, m_familyGraphOffset, getFamilyGraph);
00133
00134
00136
00140 volatile uint32_t m_actorCount;
00141
00146 union
00147 {
00148 const Asset* m_asset;
00149 uint64_t m_runtimePlaceholder;
00150 };
00151
00152
00154
00162 Actor* borrowActor(uint32_t index);
00163
00169 void returnActor(Actor& actor);
00170
00176 uint32_t getActorBufferSize() const;
00177
00183 bool isActorActive(uint32_t index) const;
00184
00192 Actor* getActorByIndex(uint32_t index) const;
00193
00201 uint32_t getGetChunkActorIndex(uint32_t chunkIndex) const;
00202
00210 uint32_t getGetNodeActorIndex(uint32_t nodeIndex) const;
00211
00219 Actor* getGetChunkActor(uint32_t chunkIndex) const;
00220
00228 Actor* getGetNodeActor(uint32_t nodeIndex) const;
00229
00230
00232
00242 void fractureSubSupportNoEvents(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks);
00243
00260 void fractureSubSupport(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks, NvBlastChunkFractureData* outBuffer, uint32_t* currentIndex, const uint32_t maxCount);
00261
00270 void fractureNoEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* chunkFractures, Actor* filterActor, NvBlastLog logFn);
00271
00286 void fractureWithEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* commands, NvBlastChunkFractureData* events, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn);
00287
00303 void fractureInPlaceEvents(uint32_t chunkFractureCount, NvBlastChunkFractureData* inoutbuffer, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn);
00304
00316 void applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, Actor* filterActor, NvBlastLog logFn, NvBlastTimers* timers);
00317 };
00318
00319 }
00320 }
00321
00322
00323 #include "NvBlastActor.h"
00324
00325
00326 namespace Nv
00327 {
00328 namespace Blast
00329 {
00330
00332
00333 NV_INLINE Actor* FamilyHeader::borrowActor(uint32_t index)
00334 {
00335 NVBLAST_ASSERT(index < getActorBufferSize());
00336 Actor& actor = getActors()[index];
00337 if (actor.m_familyOffset == 0)
00338 {
00339 const uintptr_t offset = (uintptr_t)&actor - (uintptr_t)this;
00340 NVBLAST_ASSERT(offset <= UINT32_MAX);
00341 actor.m_familyOffset = (uint32_t)offset;
00342 atomicIncrement(reinterpret_cast<volatile int32_t*>(&m_actorCount));
00343 }
00344 return &actor;
00345 }
00346
00347
00348 NV_INLINE void FamilyHeader::returnActor(Actor& actor)
00349 {
00350 if (actor.m_familyOffset != 0)
00351 {
00352 actor.m_familyOffset = 0;
00353
00354 NVBLAST_ASSERT(m_actorCount > 0);
00355 atomicDecrement(reinterpret_cast<volatile int32_t*>(&m_actorCount));
00356 }
00357 }
00358
00359
00360 NV_INLINE uint32_t FamilyHeader::getActorBufferSize() const
00361 {
00362 NVBLAST_ASSERT(m_asset);
00363 return m_asset->getLowerSupportChunkCount();
00364 }
00365
00366
00367 NV_INLINE bool FamilyHeader::isActorActive(uint32_t index) const
00368 {
00369 NVBLAST_ASSERT(index < getActorBufferSize());
00370 return getActors()[index].m_familyOffset != 0;
00371 }
00372
00373
00374 NV_INLINE Actor* FamilyHeader::getActorByIndex(uint32_t index) const
00375 {
00376 NVBLAST_ASSERT(index < getActorBufferSize());
00377 Actor& actor = getActors()[index];
00378 return actor.isActive() ? &actor : nullptr;
00379 }
00380
00381
00382 NV_INLINE uint32_t FamilyHeader::getGetChunkActorIndex(uint32_t chunkIndex) const
00383 {
00384 NVBLAST_ASSERT(m_asset);
00385 NVBLAST_ASSERT(chunkIndex < m_asset->m_chunkCount);
00386 if (chunkIndex < m_asset->getUpperSupportChunkCount())
00387 {
00388 return getChunkActorIndices()[chunkIndex];
00389 }
00390 else
00391 {
00392 return chunkIndex - (m_asset->getUpperSupportChunkCount() - m_asset->m_graph.m_nodeCount);
00393 }
00394 }
00395
00396
00397 NV_INLINE uint32_t FamilyHeader::getGetNodeActorIndex(uint32_t nodeIndex) const
00398 {
00399 NVBLAST_ASSERT(m_asset);
00400 NVBLAST_ASSERT(nodeIndex < m_asset->m_graph.m_nodeCount);
00401 const uint32_t chunkIndex = m_asset->m_graph.getChunkIndices()[nodeIndex];
00402 return isInvalidIndex(chunkIndex) ? chunkIndex : getChunkActorIndices()[chunkIndex];
00403 }
00404
00405
00406 NV_INLINE Actor* FamilyHeader::getGetChunkActor(uint32_t chunkIndex) const
00407 {
00408 uint32_t actorIndex = getGetChunkActorIndex(chunkIndex);
00409 return !isInvalidIndex(actorIndex) ? getActorByIndex(actorIndex) : nullptr;
00410 }
00411
00412
00413 NV_INLINE Actor* FamilyHeader::getGetNodeActor(uint32_t nodeIndex) const
00414 {
00415 uint32_t actorIndex = getGetNodeActorIndex(nodeIndex);
00416 return !isInvalidIndex(actorIndex) ? getActorByIndex(actorIndex) : nullptr;
00417 }
00418
00419
00421
00428 size_t getFamilyMemorySize(const Asset* asset);
00429
00430 }
00431 }
00432
00433
00434 #endif // ifndef NVBLASTFAMILY_H