// Copyright 2009-2021 Intel Corporation // 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 Vec3 patchEval(const SubdivPatch1Base& patch, const simdf& uu, const simdf& vv); template Vec3 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); } }