1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "../geometry/primitive.h"
7#include "bspline_patch.h"
8#include "bezier_patch.h"
9#include "gregory_patch.h"
10#include "gregory_patch_dense.h"
11#include "tessellation.h"
12#include "tessellation_cache.h"
13#include "gridrange.h"
14#include "patch_eval_grid.h"
15#include "feature_adaptive_eval_grid.h"
16#include "../common/scene_subdiv_mesh.h"
17
18namespace embree
19{
20 struct __aligned(64) SubdivPatch1Base
21 {
22 public:
23
24 enum Type {
25 INVALID_PATCH = 0,
26 BSPLINE_PATCH = 1,
27 BEZIER_PATCH = 2,
28 GREGORY_PATCH = 3,
29 EVAL_PATCH = 5,
30 BILINEAR_PATCH = 6,
31 };
32
33 enum Flags {
34 TRANSITION_PATCH = 16,
35 };
36
37 /*! Default constructor. */
38 __forceinline SubdivPatch1Base () {}
39
40 SubdivPatch1Base (const unsigned int gID,
41 const unsigned int pID,
42 const unsigned int subPatch,
43 const SubdivMesh *const mesh,
44 const size_t time,
45 const Vec2f uv[4],
46 const float edge_level[4],
47 const int subdiv[4],
48 const int simd_width);
49
50 __forceinline bool needsStitching() const {
51 return flags & TRANSITION_PATCH;
52 }
53
54 __forceinline Vec2f getUV(const size_t i) const {
55 return Vec2f((float)u[i],(float)v[i]) * (8.0f/0x10000);
56 }
57
58 static void computeEdgeLevels(const float edge_level[4], const int subdiv[4], float level[4]);
59 static Vec2i computeGridSize(const float level[4]);
60 bool updateEdgeLevels(const float edge_level[4], const int subdiv[4], const SubdivMesh *const mesh, const int simd_width);
61
62 public:
63
64 __forceinline size_t getGridBytes() const {
65 const size_t grid_size_xyzuv = (grid_size_simd_blocks * VSIZEX) * 4;
66 return 64*((grid_size_xyzuv+15) / 16);
67 }
68
69 __forceinline void write_lock() { mtx.lock(); }
70 __forceinline void write_unlock() { mtx.unlock(); }
71 __forceinline bool try_write_lock() { return mtx.try_lock(); }
72 //__forceinline bool try_read_lock() { return mtx.try_read_lock(); }
73
74 __forceinline void resetRootRef() {
75 //assert( mtx.hasInitialState() );
76 root_ref = SharedLazyTessellationCache::Tag();
77 }
78
79 __forceinline SharedLazyTessellationCache::CacheEntry& entry() {
80 return (SharedLazyTessellationCache::CacheEntry&) root_ref;
81 }
82
83 public:
84 __forceinline unsigned int geomID() const {
85 return geom;
86 }
87
88 __forceinline unsigned int primID() const {
89 return prim;
90 }
91
92 public:
93 SharedLazyTessellationCache::Tag root_ref;
94 SpinLock mtx;
95
96 unsigned short u[4]; //!< 16bit discretized u,v coordinates
97 unsigned short v[4];
98 float level[4];
99
100 unsigned char flags;
101 unsigned char type;
102 unsigned short grid_u_res;
103 unsigned int geom; //!< geometry ID of the subdivision mesh this patch belongs to
104 unsigned int prim; //!< primitive ID of this subdivision patch
105 unsigned short grid_v_res;
106
107 unsigned short grid_size_simd_blocks;
108 unsigned int time_;
109
110 struct PatchHalfEdge {
111 const HalfEdge* edge;
112 unsigned subPatch;
113 };
114
115 Vec3fa patch_v[4][4];
116
117 const HalfEdge *edge() const { return ((PatchHalfEdge*)patch_v)->edge; }
118 unsigned time() const { return time_; }
119 unsigned subPatch() const { return ((PatchHalfEdge*)patch_v)->subPatch; }
120
121 void set_edge(const HalfEdge *h) const { ((PatchHalfEdge*)patch_v)->edge = h; }
122 void set_subPatch(const unsigned s) const { ((PatchHalfEdge*)patch_v)->subPatch = s; }
123 };
124
125 namespace isa
126 {
127 Vec3fa patchEval(const SubdivPatch1Base& patch, const float uu, const float vv);
128 Vec3fa patchNormal(const SubdivPatch1Base& patch, const float uu, const float vv);
129
130 template<typename simdf>
131 Vec3<simdf> patchEval(const SubdivPatch1Base& patch, const simdf& uu, const simdf& vv);
132
133 template<typename simdf>
134 Vec3<simdf> patchNormal(const SubdivPatch1Base& patch, const simdf& uu, const simdf& vv);
135
136
137 /* eval grid over patch and stich edges when required */
138 void evalGrid(const SubdivPatch1Base& patch,
139 const unsigned x0, const unsigned x1,
140 const unsigned y0, const unsigned y1,
141 const unsigned swidth, const unsigned sheight,
142 float *__restrict__ const grid_x,
143 float *__restrict__ const grid_y,
144 float *__restrict__ const grid_z,
145 float *__restrict__ const grid_u,
146 float *__restrict__ const grid_v,
147 const SubdivMesh* const geom);
148
149 /* eval grid over patch and stich edges when required */
150 BBox3fa evalGridBounds(const SubdivPatch1Base& patch,
151 const unsigned x0, const unsigned x1,
152 const unsigned y0, const unsigned y1,
153 const unsigned swidth, const unsigned sheight,
154 const SubdivMesh* const geom);
155 }
156}
157