1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
// 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<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);
}
}
|