mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 05:31:01 +00:00 
			
		
		
		
	 767e374dce
			
		
	
	
		767e374dce
		
	
	
	
	
		
			
			Since Embree v3.13.0 supports AARCH64, switch back to the official repo instead of using Embree-aarch64. `thirdparty/embree/patches/godot-changes.patch` should now contain an accurate diff of the changes done to the library.
		
			
				
	
	
		
			207 lines
		
	
	
	
		
			9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
	
		
			9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright 2009-2021 Intel Corporation
 | |
| // SPDX-License-Identifier: Apache-2.0
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include "grid_soa.h"
 | |
| #include "../common/ray.h"
 | |
| #include "triangle_intersector_pluecker.h"
 | |
| 
 | |
| namespace embree
 | |
| {
 | |
|   namespace isa
 | |
|   {
 | |
|     class GridSOAIntersector1
 | |
|     {
 | |
|     public:
 | |
|       typedef void Primitive;
 | |
|       
 | |
|       class Precalculations
 | |
|       { 
 | |
|       public:
 | |
|         __forceinline Precalculations (const Ray& ray, const void* ptr)
 | |
|           : grid(nullptr) {}
 | |
|         
 | |
|       public:
 | |
|         GridSOA* grid;
 | |
|         int itime;
 | |
|         float ftime;
 | |
|       };
 | |
|       
 | |
|       template<typename Loader>
 | |
|         static __forceinline void intersect(RayHit& ray,
 | |
|                                             IntersectContext* context, 
 | |
|                                             const float* const grid_x,
 | |
|                                             const size_t line_offset,
 | |
|                                             const size_t lines,
 | |
|                                             Precalculations& pre)
 | |
|       {
 | |
|         typedef typename Loader::vfloat vfloat;
 | |
|         const size_t dim_offset    = pre.grid->dim_offset;
 | |
|         const float* const grid_y  = grid_x + 1 * dim_offset;
 | |
|         const float* const grid_z  = grid_x + 2 * dim_offset;
 | |
|         const float* const grid_uv = grid_x + 3 * dim_offset;
 | |
|         Vec3<vfloat> v0, v1, v2;
 | |
|         Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);       
 | |
|         GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
 | |
|         PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
 | |
|         intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
 | |
|       };
 | |
|       
 | |
|       template<typename Loader>
 | |
|         static __forceinline bool occluded(Ray& ray,
 | |
|                                            IntersectContext* context, 
 | |
|                                            const float* const grid_x,
 | |
|                                            const size_t line_offset,
 | |
|                                            const size_t lines,
 | |
|                                            Precalculations& pre)
 | |
|       {
 | |
|         typedef typename Loader::vfloat vfloat;
 | |
|         const size_t dim_offset    = pre.grid->dim_offset;
 | |
|         const float* const grid_y  = grid_x + 1 * dim_offset;
 | |
|         const float* const grid_z  = grid_x + 2 * dim_offset;
 | |
|         const float* const grid_uv = grid_x + 3 * dim_offset;
 | |
| 
 | |
|         Vec3<vfloat> v0, v1, v2;
 | |
|         Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);
 | |
|         
 | |
|         GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
 | |
|         PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
 | |
|         return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
 | |
|       }
 | |
|       
 | |
|       /*! Intersect a ray with the primitive. */
 | |
|       static __forceinline void intersect(Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node) 
 | |
|       {
 | |
|         const size_t line_offset   = pre.grid->width;
 | |
|         const size_t lines         = pre.grid->height;
 | |
|         const float* const grid_x  = pre.grid->decodeLeaf(0,prim);
 | |
|         
 | |
| #if defined(__AVX__)
 | |
|         intersect<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);
 | |
| #else
 | |
|         intersect<GridSOA::Gather2x3>(ray, context, grid_x            , line_offset, lines, pre);
 | |
|         if (likely(lines > 2))
 | |
|           intersect<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre);
 | |
| #endif
 | |
|       }
 | |
|       
 | |
|       /*! Test if the ray is occluded by the primitive */
 | |
|       static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node)
 | |
|       {
 | |
|         const size_t line_offset   = pre.grid->width;
 | |
|         const size_t lines         = pre.grid->height;
 | |
|         const float* const grid_x  = pre.grid->decodeLeaf(0,prim);
 | |
|         
 | |
| #if defined(__AVX__)
 | |
|         return occluded<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);
 | |
| #else
 | |
|         if (occluded<GridSOA::Gather2x3>(ray, context, grid_x            , line_offset, lines, pre)) return true;
 | |
|         if (likely(lines > 2))
 | |
|           if (occluded<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre)) return true;
 | |
| #endif
 | |
|         return false;
 | |
|       }      
 | |
|     };
 | |
| 
 | |
|     class GridSOAMBIntersector1
 | |
|     {
 | |
|     public:
 | |
|       typedef void Primitive;
 | |
|       typedef GridSOAIntersector1::Precalculations Precalculations;
 | |
|       
 | |
|       template<typename Loader>
 | |
|         static __forceinline void intersect(RayHit& ray, const float ftime,
 | |
|                                             IntersectContext* context, 
 | |
|                                             const float* const grid_x,
 | |
|                                             const size_t line_offset,
 | |
|                                             const size_t lines,
 | |
|                                             Precalculations& pre)
 | |
|       {
 | |
|         typedef typename Loader::vfloat vfloat;
 | |
|         const size_t dim_offset    = pre.grid->dim_offset;
 | |
|         const size_t grid_offset   = pre.grid->gridBytes >> 2;
 | |
|         const float* const grid_y  = grid_x + 1 * dim_offset;
 | |
|         const float* const grid_z  = grid_x + 2 * dim_offset;
 | |
|         const float* const grid_uv = grid_x + 3 * dim_offset;
 | |
| 
 | |
|         Vec3<vfloat> a0, a1, a2;
 | |
|         Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
 | |
| 
 | |
|         Vec3<vfloat> b0, b1, b2;
 | |
|         Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
 | |
| 
 | |
|         Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
 | |
|         Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
 | |
|         Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
 | |
| 
 | |
|         GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
 | |
|         PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
 | |
|         intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
 | |
|       };
 | |
|       
 | |
|       template<typename Loader>
 | |
|         static __forceinline bool occluded(Ray& ray, const float ftime,
 | |
|                                            IntersectContext* context, 
 | |
|                                            const float* const grid_x,
 | |
|                                            const size_t line_offset,
 | |
|                                            const size_t lines,
 | |
|                                            Precalculations& pre)
 | |
|       {
 | |
|         typedef typename Loader::vfloat vfloat;
 | |
|         const size_t dim_offset    = pre.grid->dim_offset;
 | |
|         const size_t grid_offset   = pre.grid->gridBytes >> 2;
 | |
|         const float* const grid_y  = grid_x + 1 * dim_offset;
 | |
|         const float* const grid_z  = grid_x + 2 * dim_offset;
 | |
|         const float* const grid_uv = grid_x + 3 * dim_offset;
 | |
| 
 | |
|         Vec3<vfloat> a0, a1, a2;
 | |
|         Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
 | |
| 
 | |
|         Vec3<vfloat> b0, b1, b2;
 | |
|         Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
 | |
|        
 | |
|         Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
 | |
|         Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
 | |
|         Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
 | |
|         
 | |
|         GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
 | |
|         PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
 | |
|         return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
 | |
|       }
 | |
|       
 | |
|       /*! Intersect a ray with the primitive. */
 | |
|       static __forceinline void intersect(Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node) 
 | |
|       { 
 | |
|         const size_t line_offset   = pre.grid->width;
 | |
|         const size_t lines         = pre.grid->height;
 | |
|         const float* const grid_x  = pre.grid->decodeLeaf(pre.itime,prim);
 | |
|         
 | |
| #if defined(__AVX__)
 | |
|         intersect<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);
 | |
| #else
 | |
|         intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x, line_offset, lines, pre);
 | |
|         if (likely(lines > 2))
 | |
|           intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre);
 | |
| #endif
 | |
|       }
 | |
|       
 | |
|       /*! Test if the ray is occluded by the primitive */
 | |
|       static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node)
 | |
|       {
 | |
|         const size_t line_offset   = pre.grid->width;
 | |
|         const size_t lines         = pre.grid->height;
 | |
|         const float* const grid_x  = pre.grid->decodeLeaf(pre.itime,prim);
 | |
|         
 | |
| #if defined(__AVX__)
 | |
|         return occluded<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);
 | |
| #else
 | |
|         if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x            , line_offset, lines, pre)) return true;
 | |
|         if (likely(lines > 2))
 | |
|           if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre)) return true;
 | |
| #endif
 | |
|         return false;
 | |
|       }      
 | |
|     };
 | |
|   }
 | |
| }
 |