| 
									
										
										
										
											2021-05-20 12:49:33 +02:00
										 |  |  | // Copyright 2009-2021 Intel Corporation
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:38:09 +02:00
										 |  |  | // SPDX-License-Identifier: Apache-2.0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "../geometry/primitive.h"
 | 
					
						
							|  |  |  | #include "bspline_patch.h"
 | 
					
						
							|  |  |  | #include "bezier_patch.h"
 | 
					
						
							|  |  |  | #include "gregory_patch.h"
 | 
					
						
							|  |  |  | #include "gregory_patch_dense.h"
 | 
					
						
							|  |  |  | #include "tessellation.h"
 | 
					
						
							|  |  |  | #include "tessellation_cache.h"
 | 
					
						
							|  |  |  | #include "gridrange.h"
 | 
					
						
							|  |  |  | #include "patch_eval_grid.h"
 | 
					
						
							|  |  |  | #include "feature_adaptive_eval_grid.h"
 | 
					
						
							|  |  |  | #include "../common/scene_subdiv_mesh.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace embree | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct __aligned(64) SubdivPatch1Base | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enum Type { | 
					
						
							|  |  |  |       INVALID_PATCH          = 0, | 
					
						
							|  |  |  |       BSPLINE_PATCH          = 1,   | 
					
						
							|  |  |  |       BEZIER_PATCH           = 2,   | 
					
						
							|  |  |  |       GREGORY_PATCH          = 3, | 
					
						
							|  |  |  |       EVAL_PATCH             = 5, | 
					
						
							|  |  |  |       BILINEAR_PATCH         = 6, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enum Flags { | 
					
						
							|  |  |  |       TRANSITION_PATCH       = 16,  | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*! Default constructor. */ | 
					
						
							|  |  |  |     __forceinline SubdivPatch1Base () {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SubdivPatch1Base (const unsigned int gID, | 
					
						
							|  |  |  |                       const unsigned int pID, | 
					
						
							|  |  |  |                       const unsigned int subPatch, | 
					
						
							|  |  |  |                       const SubdivMesh *const mesh, | 
					
						
							|  |  |  |                       const size_t time, | 
					
						
							|  |  |  |                       const Vec2f uv[4], | 
					
						
							|  |  |  |                       const float edge_level[4], | 
					
						
							|  |  |  |                       const int subdiv[4], | 
					
						
							|  |  |  |                       const int simd_width); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline bool needsStitching() const { | 
					
						
							|  |  |  |       return flags & TRANSITION_PATCH;       | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline Vec2f getUV(const size_t i) const { | 
					
						
							|  |  |  |       return Vec2f((float)u[i],(float)v[i]) * (8.0f/0x10000); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static void computeEdgeLevels(const float edge_level[4], const int subdiv[4], float level[4]); | 
					
						
							|  |  |  |     static Vec2i computeGridSize(const float level[4]); | 
					
						
							|  |  |  |     bool updateEdgeLevels(const float edge_level[4], const int subdiv[4], const SubdivMesh *const mesh, const int simd_width); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline size_t getGridBytes() const { | 
					
						
							|  |  |  |       const size_t grid_size_xyzuv = (grid_size_simd_blocks * VSIZEX) * 4; | 
					
						
							|  |  |  |       return 64*((grid_size_xyzuv+15) / 16); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline void write_lock()     { mtx.lock();   } | 
					
						
							|  |  |  |     __forceinline void write_unlock()   { mtx.unlock(); } | 
					
						
							|  |  |  |     __forceinline bool try_write_lock() { return mtx.try_lock(); } | 
					
						
							|  |  |  |     //__forceinline bool try_read_lock()  { return mtx.try_read_lock(); }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline void resetRootRef() { | 
					
						
							|  |  |  |       //assert( mtx.hasInitialState() );
 | 
					
						
							|  |  |  |       root_ref = SharedLazyTessellationCache::Tag(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline SharedLazyTessellationCache::CacheEntry& entry() { | 
					
						
							|  |  |  |       return (SharedLazyTessellationCache::CacheEntry&) root_ref; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public:     | 
					
						
							|  |  |  |     __forceinline unsigned int geomID() const  { | 
					
						
							|  |  |  |       return geom; | 
					
						
							|  |  |  |     }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline unsigned int primID() const  { | 
					
						
							|  |  |  |       return prim; | 
					
						
							|  |  |  |     }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |     SharedLazyTessellationCache::Tag root_ref; | 
					
						
							|  |  |  |     SpinLock mtx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned short u[4];                        //!< 16bit discretized u,v coordinates
 | 
					
						
							|  |  |  |     unsigned short v[4]; | 
					
						
							|  |  |  |     float level[4]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned char flags; | 
					
						
							|  |  |  |     unsigned char type; | 
					
						
							|  |  |  |     unsigned short grid_u_res; | 
					
						
							|  |  |  |     unsigned int geom;                          //!< geometry ID of the subdivision mesh this patch belongs to
 | 
					
						
							|  |  |  |     unsigned int prim;                          //!< primitive ID of this subdivision patch
 | 
					
						
							|  |  |  |     unsigned short grid_v_res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned short grid_size_simd_blocks; | 
					
						
							|  |  |  |     unsigned int time_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct PatchHalfEdge { | 
					
						
							|  |  |  |       const HalfEdge* edge; | 
					
						
							|  |  |  |       unsigned subPatch; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Vec3fa patch_v[4][4]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const HalfEdge *edge() const { return ((PatchHalfEdge*)patch_v)->edge; } | 
					
						
							|  |  |  |     unsigned time() const { return time_; } | 
					
						
							|  |  |  |     unsigned subPatch() const { return ((PatchHalfEdge*)patch_v)->subPatch; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void set_edge(const HalfEdge *h) const { ((PatchHalfEdge*)patch_v)->edge = h; } | 
					
						
							|  |  |  |     void set_subPatch(const unsigned s) const { ((PatchHalfEdge*)patch_v)->subPatch = s; } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   namespace isa | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     Vec3fa patchEval(const SubdivPatch1Base& patch, const float uu, const float vv); | 
					
						
							|  |  |  |     Vec3fa patchNormal(const SubdivPatch1Base& patch, const float uu, const float vv); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     template<typename simdf> | 
					
						
							|  |  |  |       Vec3<simdf> patchEval(const SubdivPatch1Base& patch, const simdf& uu, const simdf& vv);  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<typename simdf> | 
					
						
							|  |  |  |       Vec3<simdf> patchNormal(const SubdivPatch1Base& patch, const simdf& uu, const simdf& vv);  | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* eval grid over patch and stich edges when required */       | 
					
						
							|  |  |  |     void evalGrid(const SubdivPatch1Base& patch, | 
					
						
							|  |  |  |                   const unsigned x0, const unsigned x1, | 
					
						
							|  |  |  |                   const unsigned y0, const unsigned y1, | 
					
						
							|  |  |  |                   const unsigned swidth, const unsigned sheight, | 
					
						
							|  |  |  |                   float *__restrict__ const grid_x, | 
					
						
							|  |  |  |                   float *__restrict__ const grid_y, | 
					
						
							|  |  |  |                   float *__restrict__ const grid_z, | 
					
						
							|  |  |  |                   float *__restrict__ const grid_u, | 
					
						
							|  |  |  |                   float *__restrict__ const grid_v, | 
					
						
							|  |  |  |                   const SubdivMesh* const geom); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* eval grid over patch and stich edges when required */       | 
					
						
							|  |  |  |     BBox3fa evalGridBounds(const SubdivPatch1Base& patch, | 
					
						
							|  |  |  |                            const unsigned x0, const unsigned x1, | 
					
						
							|  |  |  |                            const unsigned y0, const unsigned y1, | 
					
						
							|  |  |  |                            const unsigned swidth, const unsigned sheight, | 
					
						
							|  |  |  |                            const SubdivMesh* const geom); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |