godot/thirdparty/embree/kernels/subdiv/subdivpatch1base.h
2021-01-14 18:02:07 +01:00

157 lines
5.1 KiB
C++

// Copyright 2009-2020 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);
}
}