diff options
| author | Ben Marsh <[email protected]> | 2019-10-22 09:07:59 -0400 |
|---|---|---|
| committer | Ben Marsh <[email protected]> | 2019-10-22 09:07:59 -0400 |
| commit | bd0027e737c6512397f841c22786274ed74b927f (patch) | |
| tree | f7ffbdb8f3741bb7f24635616cc189cba5cb865c /vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp | |
| download | archived-shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.tar.xz archived-shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.zip | |
Adding Shave-and-a-Haircut 9.6
Diffstat (limited to 'vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp')
| -rw-r--r-- | vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp b/vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp new file mode 100644 index 0000000..b9b3686 --- /dev/null +++ b/vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp @@ -0,0 +1,353 @@ +// Shave and a Haircut +// (c) 2019 Epic Games +// US Patent 6720962 + +/********************************************************************** + *< + FILE: shaveVrayMovingTriVoxelPrim.cpp -- iplementation file + + DESCRIPTION: Static (non motion blurred) instanced hair voxel primitive + + CREATED BY: Vladimir Dubovoy <[email protected]> + + HISTORY: created 20-05-2010 + + *> + **********************************************************************/ + +#include "assert.h" +#include "shaveVrayMovingTriVoxelPrim.h" +#include "shaveVrayInstanceI.h" +#include "misc_ray.h" +#include "vray3_compat.h" + +shaveVrayMovingTriVoxelPrim::shaveVrayMovingTriVoxelPrim( + IHairVoxel* vox, + VR::VRayCore *vray, + shaveVrayInstanceI *inst): + shaveVrayTriVoxelPrim(vox,vray,inst) +{ + _firstid() = -1; + _tris() = NULL; + //_numblur() = 2; + + if(voxel()) + { + VERT pmin; + VERT pmax; + voxel()->GetBbox(pmin,pmax); + + _bbox().init();//MovingBox + _bbox().b[0].pmin.x = pmin.x; + _bbox().b[0].pmin.y = pmin.y; + _bbox().b[0].pmin.z = pmin.z; + + _bbox().b[0].pmax.x = pmax.x; + _bbox().b[0].pmax.y = pmax.y; + _bbox().b[0].pmax.z = pmax.z; + + VR::Vector scnoffs = VR::toVector(sceneOffset()); + _bbox().b[0].pmin -= scnoffs; + _bbox().b[0].pmax -= scnoffs; + + //calc speed box + const HairType& hair = voxel()->GetHair(); + int nv = hair.GetNumVerts(); + for(int i = 0; i < nv; i++) + { + float x, y, z; + hair.GetVelocity(i,x,y,z); + + _bbox().b[1].pmin.x = bbox().b[1].pmin.x > x ? x : bbox().b[1].pmin.x; + _bbox().b[1].pmin.y = bbox().b[1].pmin.y > y ? y : bbox().b[1].pmin.y; + _bbox().b[1].pmin.z = bbox().b[1].pmin.z > z ? z : bbox().b[1].pmin.z; + + _bbox().b[1].pmax.x = bbox().b[1].pmax.x < x ? x : bbox().b[1].pmax.x; + _bbox().b[1].pmax.y = bbox().b[1].pmax.y < y ? y : bbox().b[1].pmax.y; + _bbox().b[1].pmax.z = bbox().b[1].pmax.z < z ? z : bbox().b[1].pmax.z; + } + _bbox().t[0] = 0.0f; + _bbox().t[1] = 1.0f; + + /*DebugPrint("[%f %f %f][%f %f %f]\n", + pmin.x, pmin.y, pmin.z, + pmax.x, pmax.y, pmax.z);*/ + } +} + +shaveVrayMovingTriVoxelPrim::~shaveVrayMovingTriVoxelPrim() +{ +} + +/* +| from MovingPrimitive +*/ +void shaveVrayMovingTriVoxelPrim::getBBox (VR::MovingBox &box) +{ + //DebugPrint("PRIM> shaveVrayMovingTriVoxelPrim::getBBox "); + + box = bbox(); +} + +/* +| from StaticPrimitive +*/ +bool shaveVrayMovingTriVoxelPrim::splittable () +{ + //DebugPrint("PRIM> shaveVrayMovingTriVoxelPrim::splitable\n"); + + return true; +} + +/* +| from StaticPrimitive +*/ +void shaveVrayMovingTriVoxelPrim::split (int dim, VR::real middle, VR::MovingBox &bLeft, VR::MovingBox &bRight) +{ + //DebugPrint("PRIM> shaveVrayMovingTriVoxelPrim::split [%i %f]\n",dim,middle); + + VR::MovingBox bbox; + getBBox(bbox); + bbox.split(dim, middle, bLeft, bRight); +} +/* +| from StaticPrimitive +*/ +int shaveVrayMovingTriVoxelPrim::expandable() +{ + return true; +} +/* +| from StaticPrimitive +*/ +int shaveVrayMovingTriVoxelPrim::expand (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex) +{ + const HairType& hair = voxel()->GetHair(); + int numFaces = hair.GetNumFaces(); + int numVerts = hair.GetNumVerts(); + + if(numFaces == 0) + return 0; + + //int numblur_prims = numblur() - 1; + //float step = 1.0f/(float)numblur_prims; + + if(firstid() == -1) + _firstid() = raycaster->getNewRenderIDArray(numFaces/**numblur_prims*/); + + + _normals().resize(numVerts); + for(int i = 0; i < numVerts; i++) + { + _normal(i) = VR::Vector(0.0f,0.0f,0.0f); + } + + VR::Vector p0[3]; + VR::Vector p1[3]; + VR::Vector v[3]; + float t0 = 0.0f; + float t1 = 0.99f; + float dt = t1 - t0; + _tris() = new VR::MovingTriangle[numFaces]; + VR::Vector scnoffs=VR::toVector(sceneOffset()); + for(int i = 0; i < numFaces; i++) + { + int fs; + int fe; + int k = 0; + //int k = 2; + hair.GetFace(i,fs,fe); + int df = fe - fs; //we expect triangular mesh + if(df != 3) + { + LOGMSGI("PRIM", "triangular face is expected, vertex count:",df); + continue; + } + for(int j = fs; j < fe; j++) + { + int vert_idx = hair.GetFaceVert(j); + //hair.GetVert (vert_idx,_tri(i).p[k].x,_tri(i).p[k].y,_tri(i).p[k].z); + //hair.GetVelocity(vert_idx,_tri(i).d[k].x,_tri(i).d[k].y,_tri(i).d[k].z); + //_tri(i).d[k] = VR::Vector(); + //_tri(i).p[k] -= sceneOffset(); + + hair.GetVert (vert_idx, p0[k].x, p0[k].y, p0[k].z); + hair.GetVelocity(vert_idx, v[k].x, v[k].y, v[k].z); + p0[k] -= scnoffs; + p1[k] = p0[k] + v[k]*dt; + + k++; + } + //_tri(i).t[0] = 0.0f; + //_tri(i).t[1] = 1.0f; + _tri(i).init(p0,p1 /*v*/ /*p0*/,t0,t1); + raycaster->insertPrimitive(threadIndex, &_tri(i), static_cast<GeometryGenerator*>(this), i + firstid()); + + // pre-compute normals + int i0 = hair.GetFaceVert(fs); + int i1 = hair.GetFaceVert(fs+1); + int i2 = hair.GetFaceVert(fs+2); + VR::Vector v0; + VR::Vector v1; + VR::Vector v2; + hair.GetVert(i0,v0.x,v0.y,v0.z); + hair.GetVert(i1,v1.x,v1.y,v1.z); + hair.GetVert(i2,v2.x,v2.y,v2.z); + + VR::Vector e0 = v1-v0; + VR::Vector e1 = v2-v0; + + VR::Vector fn = -normalize(e0^e1); + + _normal(i0) += fn; + _normal(i1) += fn; + _normal(i2) += fn; + } + + for(int i = 0; i < numVerts; i++) + { + _normal(i) = normalize(normal(i)); + } + +#ifdef _DEBUG +#ifdef WIN32 + assert(_CrtCheckMemory()); +#endif +#endif + return numFaces*sizeof(VR::MovingTriangle); +} + +/* +| from StaticPrimitive +*/ +int shaveVrayMovingTriVoxelPrim::collapse (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex) +{ + const HairType& hair = voxel()->GetHair(); + int numFaces = hair.GetNumFaces(); + + if(numFaces == 0) + return 0; + + if(tris()) + { + for (int i=0; i < numFaces; i++) + raycaster->removePrimitive(threadIndex, &_tri(i)); + + delete[] tris(); + _tris() = NULL; + } + _normals().clear(); + + return numFaces*sizeof(VR::MovingTriangle); +} +/* +| from GeometryGenerator +*/ +void shaveVrayMovingTriVoxelPrim::setIntersectionData(VR::RSRay &rsray, void *isd) +{ + VR::IntersectionData &isData=*((VR::IntersectionData*) isd); + VR::RSIntersection &is=rsray.is; + + assert(PRIM_TYPE_MOVING_TRIANGLE == is.primitive->type()); + + shaveVrayMovingTriVoxelPrim* owner =(shaveVrayMovingTriVoxelPrim*) (is.primitive->owner); + assert(owner == this); + + VR::MovingTriangle* T = (VR::MovingTriangle*)is.primitive; + + const HairType& hair = voxel()->GetHair(); + + isData.primitive=is.primitive; + isData.skipTag =is.skipTag; + isData.faceIndex= T->ownerIndex - firstid(); +#ifdef OWN_SHADEABLE_FOR_TRI + isData.sb = shade(); +#else + isData.sb = shdata(); +#endif + isData.sd = shdata(); + isData.si = NULL; //shinst(); + isData.volume=NULL; + + isData.bary=VR::toShadeVec(is.bary); + isData.wpointCoeff=is.t; + + isData.faceBase=VR::toShadeVec(T->p[0]); + isData.faceEdge0=VR::toShadeVec(T->p[1]); + isData.faceEdge1=VR::toShadeVec(T->p[2]); + isData.faceEdge0-=isData.faceBase; + isData.faceEdge1-=isData.faceBase; + + isData.gnormal= -normalize(isData.faceEdge0^isData.faceEdge1); //VR::Vector(); +#if 0 + isData.normal = isData.gnormal;//T->getNormal(rsray); +#else + int fs; + int fe; + hair.GetFace(isData.faceIndex,fs,fe); + + int v0 = hair.GetFaceVert(fs); + int v1 = hair.GetFaceVert(fs+1); + int v2 = hair.GetFaceVert(fs+2); + + VR::ShadeVec n0 = VR::toShadeVec(normal(v0)); + VR::ShadeVec n1 = VR::toShadeVec(normal(v1)); + VR::ShadeVec n2 = VR::toShadeVec(normal(v2)); + VR::ShadeVec N = is.bary.x*n0 + is.bary.y*n1 + is.bary.z*n2; + isData.normal = normalize(N); +#endif + + isData.wpoint=VR::toShadeVec(rsray.p) + VR::toShadeVec(rsray.dir)*is.t; + + // We don't have any meaningful data here + isData.surfaceProps = NULL; // sfprops(); +} + + +#if defined(VRAY30) + +void shaveVrayMovingTriVoxelPrim::setIntersectionData(const VR::RayBunchParams& params, + VR::PrimitiveIntersections& result, + const RAY_IDX* idxs, + size_t count) +{ + for(size_t ii=0; ii<count; ++ii) { + const RAY_IDX idx=idxs[ii]; + + VR::MovingTriangle* T = (VR::MovingTriangle*)(result.primitives()[idx]); + + shaveVrayMovingTriVoxelPrim* owner = static_cast<shaveVrayMovingTriVoxelPrim*>(result.primitives()[idx]->owner); + assert(owner == this); + + const HairType& hair = voxel()->GetHair(); + + // These will be used to get per-vertex attributes like color, transparency, etc. + result.faceIndices()[idx] = T->ownerIndex - firstid(); + + result.skipTags()[idx] = params.parentSkipTags()[idx]; + + //VR::Vector bary(0.5f, 0.5f, segment->getWparam(params, result, idx)); // the length along the segment + double dist = result.rayDistances()[ idx ]; + double isectPtX = params.origins(0)[ idx ] + params.dirs(0)[ idx ] * dist; + double isectPtY = params.origins(1)[ idx ] + params.dirs(1)[ idx ] * dist; + double isectPtZ = params.origins(2)[ idx ] + params.dirs(2)[ idx ] * dist; + + *(result.isectPoints(0) + idx) = isectPtX; + *(result.isectPoints(1) + idx) = isectPtY; + *(result.isectPoints(2) + idx) = isectPtZ; + + VR::Vector gn = T->getGNormal(params, result, idx); + result.geomNormals(0)[idx] = gn[0]; + result.geomNormals(1)[idx] = gn[1]; + result.geomNormals(2)[idx] = gn[2]; + + for(int d=0; d<3; d++) + result.facesBase(d)[idx]=T->p[0][d]; + for(int d=0; d<3; d++) + result.facesEdge0(d)[idx]=T->p[1][d]-T->p[0][d]; + for(int d=0; d<3; d++) + result.facesEdge1(d)[idx]=T->p[2][d]-T->p[0][d]; + } +} + +#endif // VRAY30 |