mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 05:31:01 +00:00 
			
		
		
		
	
		
			
	
	
		
			180 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			180 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|   | // Copyright 2009-2021 Intel Corporation
 | ||
|  | // SPDX-License-Identifier: Apache-2.0
 | ||
|  | 
 | ||
|  | #pragma once
 | ||
|  | 
 | ||
|  | #include "rtcore.h"
 | ||
|  | 
 | ||
|  | namespace embree { | ||
|  | namespace instance_id_stack { | ||
|  | 
 | ||
|  | static_assert(RTC_MAX_INSTANCE_LEVEL_COUNT > 0,  | ||
|  |               "RTC_MAX_INSTANCE_LEVEL_COUNT must be greater than 0."); | ||
|  | 
 | ||
|  | /*******************************************************************************
 | ||
|  |  * Instance ID stack manipulation. | ||
|  |  * This is used from the instance intersector. | ||
|  |  ******************************************************************************/ | ||
|  | 
 | ||
|  | /* 
 | ||
|  |  * Push an instance to the stack.  | ||
|  |  */ | ||
|  | RTC_FORCEINLINE bool push(RTCIntersectContext* context,  | ||
|  |                           unsigned instanceId) | ||
|  | { | ||
|  | #if RTC_MAX_INSTANCE_LEVEL_COUNT > 1
 | ||
|  |   const bool spaceAvailable = context->instStackSize < RTC_MAX_INSTANCE_LEVEL_COUNT; | ||
|  |   /* We assert here because instances are silently dropped when the stack is full. 
 | ||
|  |      This might be quite hard to find in production. */ | ||
|  |   assert(spaceAvailable);  | ||
|  |   if (likely(spaceAvailable)) | ||
|  |     context->instID[context->instStackSize++] = instanceId; | ||
|  |   return spaceAvailable; | ||
|  | #else
 | ||
|  |   const bool spaceAvailable = (context->instID[0] == RTC_INVALID_GEOMETRY_ID); | ||
|  |   assert(spaceAvailable);  | ||
|  |   if (likely(spaceAvailable)) | ||
|  |     context->instID[0] = instanceId; | ||
|  |   return spaceAvailable; | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /* 
 | ||
|  |  * Pop the last instance pushed to the stack.  | ||
|  |  * Do not call on an empty stack.  | ||
|  |  */ | ||
|  | RTC_FORCEINLINE void pop(RTCIntersectContext* context) | ||
|  | { | ||
|  |   assert(context); | ||
|  | #if RTC_MAX_INSTANCE_LEVEL_COUNT > 1
 | ||
|  |   assert(context->instStackSize > 0); | ||
|  |   context->instID[--context->instStackSize] = RTC_INVALID_GEOMETRY_ID; | ||
|  | #else
 | ||
|  |   assert(context->instID[0] != RTC_INVALID_GEOMETRY_ID); | ||
|  |   context->instID[0] = RTC_INVALID_GEOMETRY_ID; | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * Optimized instance id stack copy. | ||
|  |  * The copy() functions will either copy full | ||
|  |  * stacks or copy only until the last valid element has been copied, depending | ||
|  |  * on RTC_MAX_INSTANCE_LEVEL_COUNT. | ||
|  |  */ | ||
|  | RTC_FORCEINLINE void copy_UU(const unsigned* src, unsigned* tgt) | ||
|  | { | ||
|  | #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
 | ||
|  |   tgt[0] = src[0]; | ||
|  |    | ||
|  | #else
 | ||
|  |   for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { | ||
|  |     tgt[l] = src[l]; | ||
|  |     if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) | ||
|  |       if (src[l] == RTC_INVALID_GEOMETRY_ID) | ||
|  |         break; | ||
|  |   } | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | template <int K> | ||
|  | RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt) | ||
|  | { | ||
|  | #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
 | ||
|  |   tgt[0] = src[0]; | ||
|  | 
 | ||
|  | #else
 | ||
|  |   for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { | ||
|  |     tgt[l] = src[l]; | ||
|  |     if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) | ||
|  |       if (src[l] == RTC_INVALID_GEOMETRY_ID) | ||
|  |         break; | ||
|  |   } | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | template <int K> | ||
|  | RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, size_t j) | ||
|  | { | ||
|  | #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
 | ||
|  |   tgt[0][j] = src[0]; | ||
|  | 
 | ||
|  | #else
 | ||
|  |   for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { | ||
|  |     tgt[l][j] = src[l]; | ||
|  |     if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) | ||
|  |       if (src[l] == RTC_INVALID_GEOMETRY_ID) | ||
|  |         break; | ||
|  |   } | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | template <int K> | ||
|  | RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, const vbool<K>& mask) | ||
|  | { | ||
|  | #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
 | ||
|  |   vuint<K>::store(mask, tgt, src[0]); | ||
|  | 
 | ||
|  | #else
 | ||
|  |   for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { | ||
|  |     vuint<K>::store(mask, tgt + l, src[l]); | ||
|  |     if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) | ||
|  |       if (src[l] == RTC_INVALID_GEOMETRY_ID) | ||
|  |         break; | ||
|  |   } | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | template <int K> | ||
|  | RTC_FORCEINLINE void copy_VU(const vuint<K>* src, unsigned* tgt, size_t i) | ||
|  | { | ||
|  | #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
 | ||
|  |   tgt[0] = src[0][i]; | ||
|  | 
 | ||
|  | #else
 | ||
|  |   for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { | ||
|  |     tgt[l] = src[l][i]; | ||
|  |     if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) | ||
|  |       if (src[l][i] == RTC_INVALID_GEOMETRY_ID) | ||
|  |         break; | ||
|  |   } | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | template <int K> | ||
|  | RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, size_t i, size_t j) | ||
|  | { | ||
|  | #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
 | ||
|  |   tgt[0][j] = src[0][i]; | ||
|  | 
 | ||
|  | #else
 | ||
|  |   for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { | ||
|  |     tgt[l][j] = src[l][i]; | ||
|  |     if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) | ||
|  |       if (src[l][i] == RTC_INVALID_GEOMETRY_ID) | ||
|  |         break; | ||
|  |   } | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | template <int K> | ||
|  | RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, const vbool<K>& mask) | ||
|  | { | ||
|  | #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
 | ||
|  |   vuint<K>::store(mask, tgt, src[0]); | ||
|  | 
 | ||
|  | #else
 | ||
|  |   vbool<K> done = !mask; | ||
|  |   for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { | ||
|  |     vuint<K>::store(mask, tgt + l, src[l]); | ||
|  |     if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) { | ||
|  |       done |= src[l] == RTC_INVALID_GEOMETRY_ID; | ||
|  |       if (all(done)) break; | ||
|  |     } | ||
|  |   } | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | } // namespace instance_id_stack
 | ||
|  | } // namespace embree
 |