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/shaveVrayStaticVoxelPrim.cpp | |
| download | shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.tar.xz shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.zip | |
Adding Shave-and-a-Haircut 9.6
Diffstat (limited to 'vrayPlug/plugin/shaveVrayStaticVoxelPrim.cpp')
| -rw-r--r-- | vrayPlug/plugin/shaveVrayStaticVoxelPrim.cpp | 790 |
1 files changed, 790 insertions, 0 deletions
diff --git a/vrayPlug/plugin/shaveVrayStaticVoxelPrim.cpp b/vrayPlug/plugin/shaveVrayStaticVoxelPrim.cpp new file mode 100644 index 0000000..b116873 --- /dev/null +++ b/vrayPlug/plugin/shaveVrayStaticVoxelPrim.cpp @@ -0,0 +1,790 @@ +// Shave and a Haircut +// (c) 2019 Epic Games +// US Patent 6720962 + +/********************************************************************** + *< + FILE: shaveVrayStaticVoxelPrim.cpp -- iplementation file + + DESCRIPTION: Static (non motion blurred) hair primitive + + CREATED BY: Vladimir Dubovoy <[email protected]> + + HISTORY: created 20-08-2008 ( as part of 3ds Max + VRay hair shaders) + merged 31-03-2010 + + *> + **********************************************************************/ + +#include "assert.h" +#include "shaveVrayStaticVoxelPrim.h" +#include "shaveVrayInstance.h" +//#include "HairVrPrimsSharedFunctions.h" +#include "misc_ray.h" + +#if defined(VRAY30) || defined(VRAY40) +using namespace VUtils; +#endif + +shaveVrayStaticVoxelPrim::shaveVrayStaticVoxelPrim(IHairVoxel* voxel,VR::VRayCore *vray, shaveVrayInstance *inst) + :shaveVrayVoxelPrim(voxel,vray,inst) +#if defined(VRAY30) || defined(VRAY40) + ,staticHairTree(NULL) +#endif + +{ + _firstid() = -1; + _pts() = NULL; + _uns() = NULL; + _vns() = NULL; + _strands() = NULL; +#if defined(VRAY30) || defined(VRAY40) + minLeaf=0.0f; + leafCoeff=1.0f; + maxDepth=80; + + const VRaySequenceData &sdata=vray->getSequenceData(); + const VRayFrameData &fdata=vray->getFrameData(); + + threadman=sdata.threadManager; + prog=sdata.progress; +#if VRAY_DLL_VERSION < 0x36000 + tessParams.setFDataParams(fdata.camToWorld.offs, fdata.fov, fdata.imgWidth); +#else + tessParams.setFDataParams(fdata.camToWorld.offs, fdata.fov, fdata.imgWidth, fdata.worldToCam, fdata.projType, fdata.zoomFractor, fdata.devAspect); +#endif + tessParams.setSubdivThresh(inst->plugin->edgeLen); +#else + _pool_Vector().init(sizeof(VR::Vector)*3*numknots(), 1000); +#endif +} + +shaveVrayStaticVoxelPrim::~shaveVrayStaticVoxelPrim() +{ + //these should be released in ::collapse() + //but we add this code here in any case + if(pts()) + delete [] pts(); + + if(uns()) + delete [] uns(); + + if(vns()) + delete [] vns(); +#if defined(VRAY30) || defined(VRAY40) + if(staticHairTree) + delete staticHairTree; +#endif +} + +/* +| from StaticPrimitive +*/ +void shaveVrayStaticVoxelPrim::getBBox (VR::StaticBox &bbox) +{ + //DebugPrint("PRIM> shaveVrayStaticVoxelPrim::getBBox "); + + if(voxel()) + { + VERT pmin; + VERT pmax; + voxel()->GetBbox(pmin,pmax); + + bbox.pmin.x = pmin.x; + bbox.pmin.y = pmin.y; + bbox.pmin.z = pmin.z; + + bbox.pmax.x = pmax.x; + bbox.pmax.y = pmax.y; + bbox.pmax.z = pmax.z; + + /*DebugPrint("[%f %f %f][%f %f %f]\n", + bbox.pmin.x, bbox.pmin.y, bbox.pmin.z, + bbox.pmax.x, bbox.pmax.y, bbox.pmax.z);*/ + + VR::Vector scnoffs = VR::toVector(sceneOffset()); + bbox.pmin -= scnoffs; + bbox.pmax -= scnoffs; + } +} + +/* +| from StaticPrimitive +*/ +bool shaveVrayStaticVoxelPrim::splittable () +{ + //DebugPrint("PRIM> shaveVrayStaticVoxelPrim::splitable\n"); + + return true; +} + +/* +| from StaticPrimitive +*/ +void shaveVrayStaticVoxelPrim::split (int dim, VR::real middle, VR::StaticBox &bLeft, VR::StaticBox &bRight) +{ + //DebugPrint("PRIM> shaveVrayStaticVoxelPrim::split [%i %f]\n",dim,middle); + + VR::StaticBox bbox; + getBBox(bbox); + bbox.split(dim, middle, bLeft, bRight); +} +/* +| from StaticPrimitive +*/ +int shaveVrayStaticVoxelPrim::expandable() +{ + return true; +} + + +/* +| from StaticHairGenerator +*/ +int shaveVrayStaticVoxelPrim::getNumSides() const +{ + return 4; +} + +/* +| from StaticHairGenerator +*/ +int shaveVrayStaticVoxelPrim::getNumKnots() +{ + return numknots(); +} +/* +| from StaticHairGenerator +*/ +void shaveVrayStaticVoxelPrim::getSidesUV(float *&uc, float *&vc) +{ + uc = _puc(); + vc = _pvc(); +} +/* +| from StaticHairGenerator +*/ +void shaveVrayStaticVoxelPrim::getSidesUV(const float *&uc, const float *&vc) const +{ + uc = puc(); + vc = pvc(); + //int size = eNumSides*sizeof(float); + //memcpy((void*)uc,puc(),size); + //memcpy((void*)vc,pvc(),size); +} +/* +| from StaticHairGenerator +*/ +int shaveVrayStaticVoxelPrim::getFlatNormal() const +{ + return true; +} +/* +| from StaticHairGenerator +*/ +float shaveVrayStaticVoxelPrim::getRadius() +{ + return 1.0f; //not sure +} +/* +| from StaticHairGenerator +*/ +float shaveVrayStaticVoxelPrim::getLength() +{ + return 100.f; //not sure +} +/* +| from StaticHairGenerator +*/ +float shaveVrayStaticVoxelPrim::getTaper() +{ + return 0.0f; //not sure +} +/* +| from StaticHairGenerator +*/ +VR::Vector shaveVrayStaticVoxelPrim::getGravity() +{ + return VR::Vector(0.0f, 0.0f, 0.0f); //not sure +} +/* +| from StaticHairGenerator +*/ +float shaveVrayStaticVoxelPrim::getLengthRand() +{ + return 0.0f; +} +/* +| from StaticHairGenerator +*/ +float shaveVrayStaticVoxelPrim::getRadiusRand() +{ + return 0.0f; +} +/* +| from StaticHairGenerator +*/ +float shaveVrayStaticVoxelPrim::getGravityRand() +{ + return 0.0f; +} +/* +| from StaticHairGenerator +*/ +float shaveVrayStaticVoxelPrim::getDirRand() +{ + return 0.0f; +} +/* +| from StaticHairGenerator +*/ +float shaveVrayStaticVoxelPrim::getBend() +{ + return 0.0f; +} +int shaveVrayStaticVoxelPrim::generateStrand(int faceIndex, int strandIndex, + const VR::Vector *pv, const VR::Vector *nv, + VR::Vector *pts, VR::Vector *un, VR::Vector *vn) +{ + assert(false); + //maybe we do not need to change array elementws as far as we passed initalized strands + return true; +} +/* +| from StaticHairGenerator +*/ +VR::Vector shaveVrayStaticVoxelPrim::getStrandBaryCoords(int faceIndex, int strandIndex) const +{ + return VR::Vector(1.0f, 0.0f, 0.f); +} +/* +| from StaticHairGenerator +*/ +VR::Vector* shaveVrayStaticVoxelPrim::newVectors(int threadIndex) +{ +#if defined(VRAY30) || defined(VRAY40) + return NULL; +#else + return (VR::Vector*) _pool_Vector().newElement(); +#endif +} +/* +| from StaticHairGenerator +*/ +void shaveVrayStaticVoxelPrim::deleteVectors(VR::Vector *x, int threadIndex) +{ + _pool_Vector().releaseElement(x); +} + +/* +| from GeometryGenerator +*/ +#if defined(VRAY30) +VR::Vector shaveVrayStaticVoxelPrim::getGNormal(VR::RSRay &rsray) +{ + return rsray.is.primitive->getGNormal(rsray); +} +VR::Vector shaveVrayStaticVoxelPrim::getNormal(VR::RSRay &rsray) +{ + return rsray.is.primitive->getNormal(rsray); +} +#elif defined(VRAY40) +VR::ShadeVec shaveVrayStaticVoxelPrim::getGNormal(VR::RSRay &rsray) +{ + return rsray.is.primitive->getGNormal(rsray); +} +VR::ShadeVec shaveVrayStaticVoxelPrim::getNormal(VR::RSRay &rsray) +{ + return rsray.is.primitive->getNormal(rsray); +} +#endif + +#if defined(VRAY30) || defined(VRAY40) +/* + * ########################################### + * Implementation for V-Ray 3.0+ + * ########################################### + */ +int shaveVrayStaticVoxelPrim::initHairData() { + const HairType &hair=voxel()->GetHair(); + int numHairs=hair.GetNumStrands(); + + //assume all hairs have the same number of segments + _numknots()=hair.face_end[0]-hair.face_start[0]; + + // hair data will hold data from voxel + hairData.numVertices=VR::IntRefList(numHairs); + hairData.vertices=VR::VectorRefList(numHairs*_numknots()); + hairData.widths=VR::FloatRefList(numHairs*_numknots()); + hairData.colors=VR::ColorRefList(numHairs*_numknots()); + + VR::Vector scnoffs=VR::toVector(sceneOffset()); + // fill in our hair data + for(int i=0; i<numHairs; ++i) { + int pts_offset=i*numknots(); + + float root_radius=hair.radiusroot[i]; + float delta_radius=hair.radiustip[i]-root_radius; + + for(int j=0; j<numknots(); ++j) { + int vert_idx=hair.face_start[i] + j; + int pt_idx=pts_offset+j; + + VR::Vector pt; + hair.GetVert(vert_idx, pt.x, pt.y, pt.z); + pt-=scnoffs; + hairData.vertices[pt_idx]=pt; + + float t=float(j)/float(numknots()-1); + float w=VR::Max(0.0001f, root_radius+t*delta_radius); + hairData.widths[pt_idx]=w; + + VR::Color knot_color; + hair.GetVertColor(i, j, knot_color.r, knot_color.g, knot_color.b); + hairData.colors[pt_idx]=knot_color; + } + hairData.numVertices[i]=_numknots(); + } + + hairData.initVertexOffsets(); + + tmHairData.hairData=&hairData; + tmHairData.worldSpaceVertices=hairData.vertices; + tmHairData.initDirs(); + + if (hinst()->plugin->dynHairTessel) { + tesselateHairData(tmHairData, &tessHairData, NULL, NULL, tessParams); + } + + return numHairs; +} + +#if defined(VRAY30) +void shaveVrayStaticVoxelPrim::storeInGlobalTree(VR::RayServerInterface2 *rayserver) +#elif defined(VRAY40) +void shaveVrayStaticVoxelPrim::storeInGlobalTree(VR::RayServerInterface *rayserver) +#endif +{ + if (!staticHairTree) { + int num_hairs=initHairData(); + if(firstid()==-1) + _firstid()=rayserver->getNewRenderIDArray(num_hairs+1); + staticHairTree=new StaticHairTreePrimitive(firstid(), &tmHairData, NULL, 0); + } + rayserver->storeStaticHairData(staticHairTree, this, firstid(), tmHairData); +} + +int shaveVrayStaticVoxelPrim::expand(VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex) { + + int num_hairs=initHairData(); + + if(firstid()==-1) + _firstid()=raycaster->getNewRenderIDArray(num_hairs+1); + +#if VRAY_DLL_VERSION < 0x31000 + staticHairTree=new VR::StaticHairTreePrimitive(firstid()+1, &tmHairData, NULL, true); +#else +#if VRAY_DLL_VERSION >= 0x40000 + RayServerInterface* rayserver = vrayCore->getSequenceData().rayserver; +#else + RayServerInterface2* rayserver = vrayCore->getSequenceData().rayserver; +#endif + VoxelTree * tree = rayserver->newStaticVoxelTree(&tmHairData, voxelTreeType_hairTree); + staticHairTree=new StaticHairTreePrimitive(firstid()+1, &tmHairData, NULL, tree); +#endif + +#if VRAY_DLL_VERSION < 0x36000 + staticHairTree->visibleToCamera=_hinst()->primary_visibility; // should we intersect this hair tree wil cam rays? +#else + staticHairTree->visibleToCamera = _hinst()->getPrimaryVisibility(); +#endif + staticHairTree->build(prog, threadman, maxDepth, minLeaf, leafCoeff); + + raycaster->insertPrimitive(threadIndex, staticHairTree, this, firstid()); + + int totalVertices=numknots()*num_hairs; + uint64 memUsage=staticHairTree->getMemUsage(); + return memUsage+3*sizeof(VR::Vector)*totalVertices; +} + +int shaveVrayStaticVoxelPrim::collapse(VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex) { + raycaster->removePrimitive(threadIndex, staticHairTree); + uint64 memUsage=staticHairTree->getMemUsage(); + delete staticHairTree; + staticHairTree=NULL; + memUsage+=3*sizeof(Vector)*tmHairData.hairData->vertices.size(); + + tmHairData.freeMem(); + hairData.freeMem(); + tessHairData.freeMem(); + + return memUsage; +} + +void shaveVrayStaticVoxelPrim::getStaticIntersectionData(int strandIdx, int segmentIdx, const VR::Vector* &p, const VR::Vector* &dirs) { + int startIdx = tmHairData.hairData->vertexOffsets[strandIdx] + segmentIdx; + p = &tmHairData.worldSpaceVertices[startIdx]; + dirs = &tmHairData.dirs[startIdx]; +} + +void shaveVrayStaticVoxelPrim::setCommonIntersectionData(VR::RSRay &rsray, void *isd, int strandIdx, int segmentIdx, + float wParam, const ShadeVec &gNormal, const ShadeVec &normal) +{ + IntersectionData &isData=*((IntersectionData*) isd); + RSIntersection &is=rsray.is; + + isData.primitive=rsray.is.primitive; + isData.skipTag=is.skipTag; + + isData.sb=getShadeable(); + isData.sd=getExtTexMapping(); + isData.si=getExtShadeData(); + + isData.surfaceProps=NULL; + isData.volume=NULL; + + isData.wpointCoeff=is.t; +#if defined(VRAY30) + isData.wpoint=rsray.p+TracePoint(rsray.dir)*is.t; +#elif defined(VRAY40) + isData.wpoint=rsray.p+rsray.dir*is.t; +#endif + + isData.gnormal=gNormal; + isData.normal=normal; + + // These will be used to get per-vertex attributes like color, transparency, etc. + isData.extra_int[1]=strandIdx; // the hair strand index + isData.faceIndex=segmentIdx; // the segment index within a hair strand + + isData.bary = ShadeVec(wParam, 0.0f, 0.0f); // the length along the segment + + isData.faceBase = ShadeVec(0.0f, 0.0f, 0.0f); + isData.faceEdge0 = ShadeVec(0.0f, 0.0f, 0.0f); + isData.faceEdge1 = ShadeVec(0.0f, 0.0f, 0.0f); +} + +#if defined(VRAY30) +void shaveVrayStaticVoxelPrim::setCommonIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result, + const RAY_IDX idx, int strandIdx, int segmentIdx, float wParam, + const VUtils::Vector &gNormal, const VUtils::Vector &normal) +{ + VR::Ireal t = result.rayDistances()[ idx ]; + for(int d=0; d<3; d++) result.isectPoints(d)[idx] = params.origins(d)[idx] + params.dirs(d)[idx] * t; + + for(int d=0; d<3; d++) result.geomNormals(d)[idx] = gNormal[d]; + + for(int d=0; d<3; d++) result.smoothNormals(d)[idx] = normal[d]; + + // These will be used to get per-vertex attributes like color, transparency, etc. + result.extraInts(1)[idx] = strandIdx; // the hair strand index + result.faceIndices()[idx] = segmentIdx; // the segment index within a hair strand + + VR::Vector bary = VR::Vector(wParam, 0.0f, 0.0f); // the length along the segment + for(int d=0; d<3; d++) result.baryCoords(d)[idx] = bary[d]; + + for(int d=0; d<3; d++) result.facesBase(d)[idx] = 0.0f; + for(int d=0; d<3; d++) result.facesEdge0(d)[idx] = 0.0f; + for(int d=0; d<3; d++) result.facesEdge1(d)[idx] = 0.0f; +} +#endif + +void shaveVrayStaticVoxelPrim::setIntersectionData(VR::RSRay &rsray, void *isd) { + VR::StaticHairTreePrimitive *treePrim=static_cast<VR::StaticHairTreePrimitive*>(rsray.is.primitive); + int strandIdx=treePrim->getStrandIndex(rsray); + int segmentIdx=treePrim->getSegmentIndex(rsray); + + const VR::Vector *p, *dirs; + getStaticIntersectionData(strandIdx, segmentIdx, p, dirs); + + setCommonIntersectionData(rsray, isd, strandIdx, segmentIdx, + treePrim->getWparam(rsray, p), + treePrim->getGNormal(rsray, p), + treePrim->getNormal(rsray, p, dirs, getFlatNormal())); +} + +#if defined(VRAY30) +void shaveVrayStaticVoxelPrim::setIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result, const RAY_IDX* idxs, size_t count) +{ + // Iterate over the active rays + for( size_t i = 0; i < count; i++ ) { + const RAY_IDX idx = idxs[ i ]; + + VR::StaticHairTreePrimitive *treePrim=static_cast<VR::StaticHairTreePrimitive*>(result.primitives()[idx]); + + int strandIdx=treePrim->getStrandIndex(params, result, idx); + int segmentIdx=treePrim->getSegmentIndex(params, result, idx); + + const VR::Vector *p, *dirs; + getStaticIntersectionData(strandIdx, segmentIdx, p, dirs); + + setCommonIntersectionData(params, result, idx, strandIdx, segmentIdx, + treePrim->getWparam(params, result, idx, p), + treePrim->getGNormal(params, result, idx, p), + treePrim->getNormal(params, result, idx, p, dirs, getFlatNormal())); + } +} +#endif + +VR::ShadeVec shaveVrayStaticVoxelPrim::getHairDir(const VR::VRayContext &rc) const { + int strandIdx, segmentIdx; + shaveVrayGetHairParams(rc, strandIdx, segmentIdx); + + int pos=hairData.vertexOffsets[strandIdx]+segmentIdx; + float blend=rc.rayresult.bary[0]; + + VR::ShadeVec result(0.0f, 0.0f, 0.0f); + + const VR::VectorRefList &vertices=tmHairData.worldSpaceVertices; + if (segmentIdx==0) { + VR::ShadeVec v=VR::toShadeVec(vertices[pos]); + VR::ShadeVec vnext=VR::toShadeVec(vertices[pos+1]); + result=normalize0(vnext-v); + } else { + VR::ShadeVec vprev=VR::toShadeVec(vertices[pos-1]); + VR::ShadeVec v=VR::toShadeVec(vertices[pos]); + VR::ShadeVec vnext=VR::toShadeVec(vertices[pos+1]); + VR::ShadeVec prev_dir = normalize0(v-vprev); + VR::ShadeVec curr_dir = normalize0(vnext-v); + + result=normalize0(prev_dir + (curr_dir - prev_dir)*blend); + } + + return result; +} + +#else //VRAY30 not defined below this line +/* + * ########################################### + * Implementation for V-Ray <= 2.99 + * ########################################### + */ +/* +| from StaticPrimitive +*/ +int shaveVrayStaticVoxelPrim::expand (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex) +{ + const HairType& hair = voxel()->GetHair(); + int numHairs = hair.GetNumStrands(); + + if(numHairs == 0) + return 0; + + if(firstid() == -1) + _firstid() = raycaster->getNewRenderIDArray(numHairs); + + //assume all hairs have the same number of segments + _numknots() = hair.face_end[0] - hair.face_start[0]; + + int nalloc = numknots()*numHairs; + _pts() = new VR::Vector[nalloc]; + _uns() = new VR::Vector[nalloc]; + _vns() = new VR::Vector[nalloc]; + + _strands() = new VR::StaticHairStrand[numHairs]; + for(int i = 0; i < numHairs; i++) + { + int pts_offset = i*numknots(); + + float root_radius = hair.radiusroot[i]; + float delta_radius = hair.radiustip[i] - root_radius; + + VR::Vector initialNormal; + VR::Vector sv0, sv1; + hair.GetVert(0, sv0.x, sv0.y, sv0.z); + hair.GetVert(1, sv1.x, sv1.y, sv1.z); + initialNormal=VR::normalize0(sv1-sv0); + + // Compute the initial tangent vectors - these are later on propagated along the + // strand length to avoids issues with flipped tangent vectors. + VR::Vector u,v; + VR::computeTangentVectors(initialNormal, u, v); + + for(int j = 0; j < numknots(); j++) + { + int vert_idx = hair.face_start[i] + j; + int pt_idx = pts_offset + j; + + hair.GetVert(vert_idx,_pt(pt_idx).x,_pt(pt_idx).y,_pt(pt_idx).z); + + _pt(pt_idx) -= sceneOffset(); + + if(j == 0) + { + float radius = root_radius; + if (radius<0.0001f) radius=0.0001f; + + // For the first point, just use the tangent vectors directly + _un(pt_idx) = u*radius; + _vn(pt_idx) = v*radius; + } + else + { + float t = (float)j/(float)(numknots()-1); + float radius = root_radius + t*delta_radius; + if (radius<0.0001f) radius=0.0001f; + + VR::Vector v0, v1; + hair.GetVert(vert_idx, v1.x, v1.y, v1.z); + hair.GetVert(vert_idx-1, v0.x, v0.y, v0.z); + + VR::Vector d=v1-v0; + float dlenSqr=d.lengthSqr(); + if (dlenSqr>1e-12f) { + VR::Vector nu=u-d*((u*d)/sqrtf(dlenSqr)); // Project the previous u vector on the current cross plane + float nuLenSqr=lengthSqr(nu); + if (nuLenSqr>1e-12f) { + u=nu/sqrtf(nuLenSqr); + v=normalize(d^nu); + } + } + + _un(pt_idx) = u*radius; + _vn(pt_idx) = v*radius; + } + } + + _strand(i).init(static_cast<StaticHairGenerator*>(this),pts(pts_offset), uns(pts_offset), vns(pts_offset)); + + raycaster->insertPrimitive(threadIndex, &_strand(i), static_cast<GeometryGenerator*>(this), i + firstid()); + } +#ifdef _DEBUG +#ifdef WIN32 + assert(_CrtCheckMemory()); +#endif +#endif + return numHairs*sizeof(VR::StaticHairStrand) + numknots()*numHairs*3*sizeof(VR::Vector); +} + +/* +| from StaticPrimitive +*/ +int shaveVrayStaticVoxelPrim::collapse (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex) +{ + const HairType& hair = voxel()->GetHair(); + int numHairs = hair.GetNumStrands(); + + if(numHairs == 0) + return 0; + + if(strands()) + { + for (int i=0; i < numHairs; i++) + raycaster->removePrimitive(threadIndex, &_strand(i)); + + delete[] strands(); + _strands() = NULL; + } + if(pts()) + { + delete [] pts(); + _pts() = NULL; + } + if(uns()) + { + delete [] uns(); + _uns() = NULL; + } + if(vns()) + { + delete [] vns(); + _vns() = NULL; + } + _pool_Vector().freeMem(); + + return numHairs*sizeof(VR::StaticHairStrand) + numknots()*numHairs*3*sizeof(VR::Vector); +} + +/* +| from GeometryGenerator +*/ +void shaveVrayStaticVoxelPrim::setIntersectionData(VR::RSRay &rsray, void *isd) +{ + VR::IntersectionData &isData=*((VR::IntersectionData*) isd); + VR::RSIntersection &is=rsray.is; + + //assert(PRIM_TYPE_STATIC_HAIR_SEGMENT_LINE == is.primitive->type()); + + VR::StaticHairStrand *s=(VR::StaticHairStrand*) (is.primitive->owner); + +// VR::RayParams* rayparams = (VR::RayParams*)rsray.rayparams; +// assert( rayparams->currentPass == RPASS_GI); +// assert( rayparams->currentPass == RPASS_LIGHTMAP); + + isData.primitive=is.primitive; + isData.skipTag =is.skipTag; + isData.faceIndex= s->ownerIndex - firstid(); + + if(ownbsdf()) + isData.sb = shade(); + else + isData.sb = shdata(); + + isData.sd = shdata(); + isData.si = /*NULL;*/ shinst(); + isData.volume=NULL; + + isData.bary= VR::Vector(0.5f, 0.5f, 0.5f); + isData.wpointCoeff=is.t; + isData.gnormal=getGNormal(rsray); + isData.gnormal.makeNormalized(); + //if(isData.gnormal.length() < 0.99f) + //{ + // printf("gn %f %f %f\n",isData.gnormal.x, isData.gnormal.y, isData.gnormal.z); + // fflush(stdout); + //} + isData.normal =getNormal(rsray); + + isData.wpoint=rsray.p + VR::TracePoint(rsray.dir)*is.t; + isData.extraf=(float) s->getSegmentIndex((VR::StaticHairSegmentLine*) is.primitive); + isData.bary[2]=((VR::StaticHairSegmentLine*) is.primitive)->getWparam(rsray); + +// Vector *verts=fface->getVerts(); +// isData.faceBase=verts[0]; +// isData.faceEdge0=verts[1]-verts[0]; +// isData.faceEdge1=verts[2]-verts[0]; + + // We don't have any meaningful data here + isData.surfaceProps = NULL; // sfprops(); +} + +void shaveVrayStaticVoxelPrim::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::StaticHairSegmentLine *segment=static_cast<VR::StaticHairSegmentLine*>(result.primitives()[idx]); + VR::StaticHairStrand *strand=static_cast<VR::StaticHairStrand*>(segment->owner); + + float t=result.rayDistances()[idx]; + for(int d=0; d<3; d++) + result.isectPoints(d)[idx]=params.origins(d)[idx]+double(params.dirs(d)[idx])*t; + + VR::Vector gnormal = segment->getGNormal(params, result, idx); + for(int d=0; d<3; d++) + result.geomNormals(d)[idx]=gnormal[d]; + + VR::Vector normal = segment->getNormal(params, result, idx); + for(int d=0; d<3; d++) + result.smoothNormals(d)[idx]=normal[d]; + + // These will be used to get per-vertex attributes like color, transparency, etc. + result.faceIndices()[idx]=strand->getSegmentIndex(segment); + +// result.extraFloats(6)[idx]=(float)strand->getSegmentIndex(segment); // the segment index within a hair strand + result.extraInts(1)[idx]=strand->ownerIndex - firstid(); // emil 10 Nov + + VR::Vector bary(0.5f, 0.5f, segment->getWparam(params, result, idx)); // the length along the segment + for(int d=0; d<3; d++) + result.baryCoords(d)[idx]=bary[d]; + + for(int d=0; d<3; d++) + result.facesBase(d)[idx]=0.0f; + for(int d=0; d<3; d++) + result.facesEdge0(d)[idx]=0.0f; + for(int d=0; d<3; d++) + result.facesEdge1(d)[idx]=0.0f; + } +} + +#endif //VRAY30 |