2021-05-20 18:49:33 +08:00
|
|
|
// Copyright 2009-2021 Intel Corporation
|
2021-04-21 00:38:09 +08: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);
|
|
|
|
}
|
|
|
|
}
|