// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 #include "shaveVrayShadeData.h" #include "shaveVrayInstance.h" #include "shaveVrayStaticVoxelPrim.h" #include "shaveVrayMovingVoxelPrim.h" shaveVrayShadeData::shaveVrayShadeData(shaveVrayInstance *instance/*, MayaHairPrimitiveType *hairPrimitive*/) : BaseShadeData(instance) { } shaveVrayVoxelPrim* shaveVrayShadeData::getIntersectedPrimitive(const VR::VRayContext &rc) { if (rc.rayresult.primitive) { if (rc.rayresult.primitive->type()==PRIM_TYPE_STATIC_HAIR_SEGMENT_LINE) { VUtils::StaticHairSegmentLine *prim=static_cast(rc.rayresult.primitive); return static_cast(prim->owner->owner); } if (rc.rayresult.primitive->type()==PRIM_TYPE_MOVING_HAIR_SEGMENT_LINE) { VUtils::MovingHairSegmentLine *prim=static_cast(rc.rayresult.primitive); return static_cast(prim->owner->owner); } #if defined(VRAY30) || defined(VRAY40) if (rc.rayresult.primitive->type()==PRIM_TYPE_STATIC_HAIR_TREE) { VUtils::StaticHairTreePrimitive *prim=static_cast(rc.rayresult.primitive); return static_cast(prim->owner); } if (rc.rayresult.primitive->type()==PRIM_TYPE_MOVING_HAIR_TREE) { VUtils::MovingHairTreePrimitive *prim=static_cast(rc.rayresult.primitive); return static_cast(prim->owner); } #endif } return NULL; } VR::Color shaveVrayShadeData::getColor(const VR::VRayContext &rc) { shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc); if (voxelPrim) { int strandIdx, segmentIdx; float segmentOffset; shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset); VR::Color result=VR::Color(0.0f, 1.0f, 0.0f); if (voxelPrim->IsColorConst(strandIdx)) voxelPrim->GetRootColor(strandIdx, result); else voxelPrim->GetInterpColor(segmentIdx, strandIdx, segmentOffset, result); return result; } return VR::Color(0.0, 0.0, 0.0); } //VR::Vector shaveVrayShadeData::getVelocity(const VR::VRayContext &rc) //{ // shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc); // if (voxelPrim) { // int strandIdx=rc.rayresult.faceIndex; // int segmentIdx=(int)rc.rayresult.extraf; // float segmentOffset=rc.rayresult.bary[2]; // // VR::Vector result=VR::Vector(0.0f, 1.0f, 0.0f); // //if (voxelPrim->IsColorConst(strandIdx)) // // voxelPrim->GetRootColor(strandIdx, result); // //else // // voxelPrim->GetInterpColor(segmentIdx, strandIdx, segmentOffset, result); // return result; // } // return VR::Vector(0.0, 0.0, 0.0); //} VR::Color shaveVrayShadeData::getIncandescence(const VR::VRayContext &rc) { return VR::Color(1.0, 1.0, 1.0); //temp //int pos; //float blend; //getPositionAndBlend(rc, pos, blend); //return hairData.incandescence[pos]*(1.0f-blend) + hairData.incandescence[pos+1]*blend; } VR::Color shaveVrayShadeData::getTransparency(const VR::VRayContext &rc) { shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc); if (voxelPrim) { int strandIdx, segmentIdx; float segmentOffset; shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset); float opacity=1.0f; if (voxelPrim->GetTipFade()) opacity=voxelPrim->GetInterpOpacity(segmentIdx, strandIdx, segmentOffset); else opacity=voxelPrim->GetOpacity(strandIdx); float t=1.0f-opacity; return VR::Color(t, t, t); } return VR::Color(1.0, 1.0, 1.0); } void shaveVrayShadeData::getShadeData(const VR::VRayContext &rc, VR::VRayMayaHairShadeData &result) { shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc); if (voxelPrim) { int strandIdx, segmentIdx; float segmentOffset; shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset); result.hairDirection=voxelPrim->GetHairDir(rc.rayresult.origPoint, segmentIdx, strandIdx, segmentOffset); result.color=VR::Color(0.0f, 1.0f, 0.0f); if (voxelPrim->IsColorConst(strandIdx)) voxelPrim->GetRootColor(strandIdx, result.color); else voxelPrim->GetInterpColor(segmentIdx, strandIdx, segmentOffset, result.color); float opacity=1.0f; if (voxelPrim->GetTipFade()) opacity=voxelPrim->GetInterpOpacity(segmentIdx, strandIdx, segmentOffset); else opacity=voxelPrim->GetOpacity(strandIdx); float t=1.0f-opacity; result.transparency=VR::Color(t, t, t); } } float shaveVrayShadeData::getDistanceAlongStrand(const VR::VRayContext &rc) { int primType=rc.rayresult.primitive->type(); float k=0.0f; int strandIdx, segmentIdx; float segmentOffset; shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset); if (PRIM_TYPE_STATIC_HAIR_SEGMENT_LINE==primType) { VR::StaticHairSegmentLine *seg=static_cast(rc.rayresult.primitive); k=seg->getWCoord(segmentOffset); } else if (PRIM_TYPE_MOVING_HAIR_SEGMENT_LINE==primType) { VR::MovingHairSegmentLine *seg=static_cast(rc.rayresult.primitive); k=seg->getWCoord(segmentOffset); #if defined(VRAY30) || defined(VRAY40) } else if (PRIM_TYPE_STATIC_HAIR_TREE==primType) { VR::StaticHairTreePrimitive *treePrim=static_cast(rc.rayresult.primitive); k=treePrim->getWCoord(strandIdx, segmentIdx, segmentOffset); } else if (PRIM_TYPE_MOVING_HAIR_TREE==primType) { VR::MovingHairTreePrimitive *treePrim=static_cast(rc.rayresult.primitive); k=treePrim->getWCoord(strandIdx, segmentIdx, segmentOffset); #endif } return k; } #if defined(VRAY30) VR::Transform shaveVrayShadeData::getLocalUVWTransform(const VR::VRayContext &rc, int channel) { VR::Transform result(0); shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc); if (voxelPrim) { int strandIdx, segmentIdx; float segmentOffset; shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset); result.offs=voxelPrim->GetUVW(segmentIdx, strandIdx, segmentOffset, channel); } return result; } #elif defined(VRAY40) void shaveVrayShadeData::getLocalUVWTransform(const VR::VRayContext &rc, int channel, VR::ShadeTransform &result) { result.m.makeZero(); getLocalUVWCoordinates(rc, channel, result.offs); } void shaveVrayShadeData::getLocalUVWCoordinates(const VR::VRayContext &rc, int channel, VR::ShadeVec &result) { shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc); if (voxelPrim) { int strandIdx, segmentIdx; float segmentOffset; shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset); result=VR::toShadeVec(voxelPrim->GetUVW(segmentIdx, strandIdx, segmentOffset, channel)); } } int shaveVrayShadeData::getLocalUVWTransformByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeTransform &result) { return channelNotFound; } int shaveVrayShadeData::getUVWCoordinatesByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeVec &result) { return channelNotFound; } VR::ShadeVec shaveVrayShadeData::getMapChannelVertexVector(int mapChannelIdx, int vertexIdx) { return VR::ShadeVec(0.0f); } VR::ShadeVec shaveVrayShadeData::getUVWcoords(const VR::VRayContext &rc, int channel) { return getMappedUVWcoords(rc, *this, channel); } void shaveVrayShadeData::getUVWderivs(const VR::VRayContext &rc, int channel, VR::ShadeVec derivs[2]) { getMappedUVWderivs(rc, *this, channel, derivs); } void shaveVrayShadeData::getUVWbases(const VR::VRayContext &rc, int channel, VR::ShadeVec bases[3]) { getMappedUVWbases(rc, *this, channel, bases); } VR::ShadeVec shaveVrayShadeData::getUVWnormal(const VR::VRayContext &rc, int channel) { return getMappedUVWnormal(rc, *this, channel); } #endif #if defined(VRAY30) || defined(VRAY40) float shaveVrayShadeData::getRandByStrand(const VR::VRayContext &rc, int seedOffset) { int index=getStrandIndex(rc); VR::Random rnd(index+seedOffset); float res=rnd.rnd(); return res; } int shaveVrayShadeData::getStrandIndex(const VR::VRayContext &rc) { int strandIdx, segmentIdx; shaveVrayGetHairParams(rc, strandIdx, segmentIdx); return strandIdx; } int shaveVrayShadeData::getSegmentIndexInStrand(const VR::VRayContext &rc) { int strandIdx, segmentIdx; shaveVrayGetHairParams(rc, strandIdx, segmentIdx); return segmentIdx; } void shaveVrayShadeData::getIndexAndBlend(const VR::VRayContext &rc, int &out_index, float &out_blend) { out_index = 0; out_blend = 0.0f; } #if VRAY_DLL_VERSION >= 0x36000 float shaveVrayShadeData::getStrandLength(const VR::VRayContext &rc) { shaveVrayVoxelPrim* voxelPrim = getIntersectedPrimitive(rc); if (!voxelPrim) return 0; int strandIdx, segmentIdx; shaveVrayGetHairParams(rc, strandIdx, segmentIdx); int vStart, vEnd; voxelPrim->_voxel()->GetStrand(strandIdx, vStart, vEnd); VR::Vector prev, next; float length = 0; voxelPrim->_voxel()->GetVert(vStart, prev.x, prev.y, prev.z); for (int i = vStart + 1; i < vEnd; i++) { voxelPrim->_voxel()->GetVert(i, next.x, next.y, next.z); length += VR::length(next - prev); prev = next; } return length; } #endif #endif