From bd0027e737c6512397f841c22786274ed74b927f Mon Sep 17 00:00:00 2001 From: Ben Marsh Date: Tue, 22 Oct 2019 09:07:59 -0400 Subject: Adding Shave-and-a-Haircut 9.6 --- vrayPlug/plugin/hairAPIimp.cpp | 1464 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1464 insertions(+) create mode 100644 vrayPlug/plugin/hairAPIimp.cpp (limited to 'vrayPlug/plugin/hairAPIimp.cpp') diff --git a/vrayPlug/plugin/hairAPIimp.cpp b/vrayPlug/plugin/hairAPIimp.cpp new file mode 100644 index 0000000..8253672 --- /dev/null +++ b/vrayPlug/plugin/hairAPIimp.cpp @@ -0,0 +1,1464 @@ +// Shave and a Haircut +// (c) 2019 Epic Games +// US Patent 6720962 + +/********************************************************************** + *< + FILE: hairAPIImp.cpp -- iplementation file + + DESCRIPTION: Implementation of C++ Intefraces for SHAVE2 functions + + CREATED BY: Vladimir Dubovoy + + HISTORY: created 20-08-2008 + + *> + **********************************************************************/ + +#include "hairAPIimp.h" +#include "assert.h" + +#include "shaveVrayPlugin.h" + +#include +#include + +#ifdef _WIN32 +#define fileno _fileno +#define fstat _fstat +typedef struct _stat StatType; +#else +#include +typedef struct stat StatType; +#endif + + + + + +extern "C" +{ +#include "shaveSDKFUNCS2.h" +// +// Some shave stuff need to implement +// +extern VERT SHAVE2apply_GI(VERT vv, CURVEINFO *ci) +{ + VERT retValue; + retValue.x = 0.0f; + retValue.y = 0.0f; + retValue.z = 0.0f; + return retValue; +} + +extern void SHAVE2draw_tile_callback(VERT *a,VERT *b) +{ +} + +} //end "C" + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +| Creates an instace of hairStack | +/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +static bool doNeedYZswap = false; + +HAIRAPI IHairStack* LoadHair(char* dra_file, bool needYZswap) +{ + return new HairStack(dra_file,needYZswap); +} + +HAIRAPI IHairStack* LoadHair(void* dra_data, long data_size, bool needYZswap) +{ + return new HairStack(dra_data,data_size,needYZswap); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +| HairStack wrapper | +/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + +char* IHairStack::GetVersion() +{ + return SHAVE2query_version(); +} +void init_threads( void ); + +HAIRAPI HairStack::HairStack(char* fname, bool needYZswap) +{ +#ifdef WIN32 + InitializeCriticalSection(&csect); +#else + pthread_mutex_init( &mutex, NULL ); +#endif + + //its called in shaveVrayPlugin::renderBegin + //SHAVE2init(); // uncommented joe - oct 10 + + LOGMSG("SHAVE","SHAVE2clear_stack"); + SHAVE2clear_stack(); // uncommented joe - oct 10 + + //init_threads(); // uncommented joe - oct 10 + + _needyzswap() = needYZswap; + _draname() = NULL; + if(fname) + { + Init(fname); + } +} + +HAIRAPI HairStack::HairStack(void* bdata, long size, bool needYZswap) +{ +#ifdef WIN32 + InitializeCriticalSection(&csect); +#else + pthread_mutex_init( &mutex, NULL ); +#endif + + //its called in shaveVrayPlugin::renderBegin + //SHAVE2init(); // uncommented joe - oct 10 + + LOGMSG("SHAVE","SHAVE2clear_stack"); + SHAVE2clear_stack(); // uncommented joe - oct 10 + + //init_threads(); // uncommented joe - oct 10 + + _needyzswap() = needYZswap; + _draname() = NULL; + if(bdata && size > 0) + { + Init(bdata,size); + } +} + +HAIRAPI HairStack::~HairStack() +{ + Clear(); + + if(draname()) + free(draname()); + + LOGMSG("SHAVE","SHAVE2clear_stack"); + SHAVE2clear_stack(); //added + + //called in shaveVrayPlugin::renderEnd + //SHAVE2cleanup(); // uncommented joe - oct 10 + +#ifdef WIN32 + DeleteCriticalSection(&csect); +#else + pthread_mutex_destroy( &mutex ); +#endif +} + + +/* +| from IHairStack +*/ +HAIRAPI bool HairStack::Init(char* filename) +{ + LOGMSG("SHAVE", "HairStack::Init"); + + size_t len = strlen(filename) + 5; + _draname() = (char*)malloc(len); + memset(draname(),0,len); + sprintf(draname(),"%s",filename); + + LOGMSGS("SHAVE", "HairStack: dra file ",draname()); + +#ifdef USE_MEMFILE + init_MEMFILE2(&_mem(),0); + FILE* draFile = fopen(draname(), "r+b"); + if(!draFile) + { + LOGMSGS("SHAVE","HairStack: can not open dra file ",draname()); + return false; + } + + //Get the size of the DRA file. + + StatType fileInfo; + fstat(fileno(draFile), &fileInfo); + if(fileInfo.st_size == 0) + { + LOGMSGS("SHAVE", "HairStack: can not read dra file ",draname()); + return false; + } + _mem().size = fileInfo.st_size; + _mem().data = (char*)malloc(mem().size); + + + //size_t nread = fread(&_mem().data,1,mem().size,draFile); + int sum = 0; + int c; + int p = 0; + while ((c = fgetc(draFile)) != EOF) + { + _mem().data[p] = c; + p++; + sum+=c; + } + fclose(draFile); + if(p != mem().size) + { + char buf[100]; sprintf(buf,"(bytes read: %i expected: %li)",p,mem().size); + LOGMSGS("SHAVE", "HairStack: error reading DRA file ",buf); + free_MEMFILE2(&_mem()); + return false; + } + + LOGMSGI("SHAVE", "HairStack: bytes read ",p); + //printf("SHAVE> MEMFILE ID:%i data:%p, pos:%i size:%i\n",mem().ID, mem().data, mem().pos, mem().size ); + LOGMSGI("SHAVE", "shaveVrayInstance: (debug) checksum ", (int)sum); + + Lock(); + try + { + LOGMSG("SHAVE", "SHAVE2init_hairstack_from_mem_archive"); + _voxres() = SHAVE2init_hairstack_from_mem_archive(&_mem()); +// SHAVEprint_engine2(); + } + catch (...) + { + LOGMSG("SHAVE", "exception occured in SHAVE2init_hairstack_from_mem_archive"); + _voxres() = -1; + } + UnLock(); +#else + Lock(); + try + { + LOGMSG("SHAVE", "SHAVE2init_hairstack_from_archive"); + _voxres() = SHAVE2init_hairstack_from_archive(draname()); + } + catch (...) + { + LOGMSG("SHAVE", "exception occured in SHAVE2init_hairstack_from_archive"); + _voxres() = -1; + } + UnLock(); +#endif + + + if(voxres() == -1) + { + return false; + } + if(voxres() != 0) + { + _voxels().resize(voxres()*voxres()*voxres()); + for(unsigned int i = 0; i < (unsigned int)voxels().size(); i++) + { + _voxel(i) = NULL; + } + } + LOGMSG("SHAVE", "HairStack::Init - OK"); + return true; +} + +/* +| from IHairStack +*/ +HAIRAPI bool HairStack::Init(void* bdata, long size) +{ + LOGMSG("SHAVE", "HairStack::Init"); + LOGMSGI("SHAVE", "HairStack: data size ",(int)size); + + init_MEMFILE2(&_mem(),0); + _mem().size = size; + _mem().data = (char*)bdata; + + Lock(); + try + { + LOGMSG("SHAVE", "SHAVE2init_hairstack_from_mem_archive"); + _voxres() = SHAVE2init_hairstack_from_mem_archive(&_mem()); + } + catch (...) + { + LOGMSG("SHAVE", "exception occured in SHAVE2init_hairstack_from_mem_archive"); + _voxres() = -1; + } + UnLock(); + + + if(voxres() == -1) + { + return false; + } + if(voxres() != 0) + { + _voxels().resize(voxres()*voxres()*voxres()); + for(unsigned int i = 0; i < (unsigned int)voxels().size(); i++) + { + _voxel(i) = NULL; + } + } + LOGMSG("SHAVE", "HairStack::Init - OK"); + return true; +} +/* +| from IHairStack +*/ +HAIRAPI void HairStack::Clear() +{ + LOGMSG("SHAVE", "HairStack::Clear"); + + for(unsigned int i = 0; i < (unsigned int)voxels().size(); i++) + { + if(voxel(i)) + { + delete voxel(i); + _voxel(i) = NULL; + } + } + _voxels().clear(); + _voxres() = 0; + + for(unsigned int i = 0; i < (unsigned int)nodes().size(); i++) + { + if(node(i)) + { + delete node(i); + _node(i) = NULL; + } + } + _nodes().clear(); + + LOGMSG("SHAVE", "SHAVE2clear_stack"); + + Lock(); + SHAVE2clear_stack(); + UnLock(); + + LOGMSG("SHAVE", "HairStack::Clear - OK"); +} +/* +| from IHairStack +*/ +HAIRAPI char* HairStack::GetDRAname() const +{ + return draname(); +} +/* +| from IHairStack +*/ +HAIRAPI int HairStack::GetNumVoxels() const +{ + return (int)voxels().size(); +} +/* +| from IHairStack +*/ +HAIRAPI int HairStack::GetVoxelRes() const +{ + return voxres(); +} +/* +| from IHairStack +*/ +HAIRAPI IHairVoxel* HairStack::GetHairVoxel(int x, int y, int z) +{ + int idx = 0; + int nvoxels = (int)voxels().size(); + if(nvoxels == 0) + return NULL; + + if(voxelIDXformXYZ(idx,x,y,z) && idx < nvoxels) + { + if(!voxel(idx)) + { + VERT ppMax; + VERT ppMin; + + VERT pMax; + VERT pMin; + + Lock(); + +#ifdef USE_MEMFILE + LOGMSG("SHAVE", "SHAVE2import_mem_archive_voxel_bbox"); + if(SHAVE2import_mem_archive_voxel_bbox( &_mem(), x, y, z, &ppMin, &ppMax )) +#else + LOGMSG("SHAVE", "SHAVE2import_archive_voxel_bbox"); + if(SHAVE2import_archive_voxel_bbox( draname(), x, y, z, &ppMin, &ppMax )) +#endif + { + if(needyzswap()) + { + pMin.x = ppMin.x; + pMin.y = -ppMax.z; + pMin.z = ppMin.y; + + pMax.x = ppMax.x; + pMax.y = -ppMin.z; + pMax.z = ppMax.y; + } + else + { + pMin = ppMin; + pMax = ppMax; + } + _voxel(idx) = new HairVoxel(this, pMin, pMax, x, y, z, false); + } + else + { + //no hair in voxel + _voxel(idx) = new HairVoxel(); + } + UnLock(); + } + return voxel(idx); + } + return NULL; +} +/* +| from IHairStack +*/ +HAIRAPI IHairVoxel* HairStack::GetHairVoxel(int idx) +{ + int nvoxels = (int)voxels().size(); + if(nvoxels == 0) + return NULL; + + if(idx < nvoxels) + { + if(!voxel(idx) ) + { + VERT ppMax; + VERT ppMin; + + VERT pMax; + VERT pMin; + + int x, y, z; + if(voxelXYZformIDX(idx,x,y,z)) + { + Lock(); + +#ifdef USE_MEMFILE + LOGMSG("SHAVE", "SHAVE2import_mem_archive_voxel_bbox"); + if(SHAVE2import_mem_archive_voxel_bbox( &_mem(), x, y, z, &ppMin, &ppMax)) +#else + LOGMSG("SHAVE", "SHAVE2import_archive_voxel_bbox"); + if(SHAVE2import_archive_voxel_bbox( draname(), x, y, z, &ppMin, &ppMax)) +#endif + { + if(needyzswap()) + { + pMin.x = ppMin.x; + pMin.y = -ppMax.z; + pMin.z = ppMin.y; + + pMax.x = ppMax.x; + pMax.y = -ppMin.z; + pMax.z = ppMax.y; + } + else + { + pMin = ppMin; + pMax = ppMax; + } + + _voxel(idx) = new HairVoxel(this, pMin, pMax, x, y, z, false); + } + else + { + //no hair in voxel + _voxel(idx) = new HairVoxel(); + } + UnLock(); + } + } + return voxel(idx); + } + return NULL; +} +/* +| from IHairStack +*/ +HAIRAPI IHairNode* HairStack::GetHairNodeByID (int node_index, bool squirrel) +{ + for(unsigned int i = 0; i < nodes().size(); i++) + if(node(i) && node(i)->GetStackID() == node_index) + return node(i); + + HairNode* hnode = new HairNode(this, node_index,squirrel); + if(hnode->GetNumVoxels() == 0) + { + delete hnode; + return NULL; + } + _nodes().push_back(hnode); + return hnode; +} +/* +| from IHairStack +*/ +void HairStack::Lock() +{ +#ifdef WIN32 + EnterCriticalSection(&csect); +#else + pthread_mutex_lock( &mutex ); +#endif +} +/* +| from IHairStack +*/ +void HairStack::UnLock() +{ +#ifdef WIN32 + LeaveCriticalSection(&csect); +#else + pthread_mutex_unlock( &mutex ); +#endif +} + +bool HairStack::voxelXYZformIDX(int index, int& x, int& y, int& z) +{ + if(voxres() == 0) + { + x = y = z = 0; + return false; + } + int voxresSq = voxres()*voxres(); + + z = index / (voxresSq); + y = (index - z*voxresSq)/voxres(); + x = index - z*voxresSq - y*voxres(); + return true; +} + +bool HairStack::voxelIDXformXYZ(int& index, int x, int y, int z) +{ + if(voxres() == 0) + { + index = -1; + return false; + } + index = z*(voxres()*voxres()) + y*voxres() + x; + return true; +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +| HairHode wrapper | +/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + +char* IHairNode::GetVersion() +{ + return SHAVE2query_version(); +} + +HAIRAPI HairNode::HairNode(HairStack* hstack, int stack_id, bool sqrl) +{ + LOGMSG("SHAVE", "HairNode ctor"); + + assert(hstack); + _stack() = hstack; + _stackid() = stack_id; + _squirrel()= sqrl; + + _bboxMin().x = FLT_MAX; + _bboxMin().y = FLT_MAX; + _bboxMin().z = FLT_MAX; + + _bboxMax().x = -FLT_MAX; + _bboxMax().y = -FLT_MAX; + _bboxMax().z = -FLT_MAX; + + float x1 = FLT_MAX; + float y1 = FLT_MAX; + float z1 = FLT_MAX; + + float x2 = -FLT_MAX; + float y2 = -FLT_MAX; + float z2 = -FLT_MAX; + + if(!stack()) + return; + + int voxres = hstack->GetVoxelRes(); + + LOGMSGI("SHAVE", "voxres",voxres); + + for(int ix = 0; ix < voxres; ix++) + { + for(int iy = 0; iy < voxres; iy++) + { + for(int iz = 0; iz < voxres; iz++) + { + VERT pMin; + VERT pMax; + + VERT ppMin; + VERT ppMax; + + bool hasHair; + + _stack()->Lock(); + try + { +#ifdef USE_MEMFILE + LOGMSG("SHAVE", "SHAVE2import_mem_archive_voxel_bbox"); + hasHair = SHAVE2import_mem_archive_voxel_bbox( + stack()->GetMemFile(), + ix, + iy, + iz, + &ppMin, + &ppMax + ) != 0; +#else + LOGMSG("SHAVE", "SHAVE2import_archive_voxel_bbox"); + hasHair = SHAVE2import_archive_voxel_bbox( + stack()->GetDRAname(), + ix, + iy, + iz, + &ppMin, + &ppMax + ) != 0; +#endif + } + catch (...) + { + LOGMSG("SHAVE", "an exception occured in SHAVE2import(_mem_)archive_voxel_bbox"); + hasHair = false; + } + + _stack()->UnLock(); + + if(!hasHair) + { + continue; + } + if(hstack->GetNeedYZswap()) + { + pMin.x = ppMin.x; + pMin.y = -ppMax.z; + pMin.z = ppMin.y; + + pMax.x = ppMax.x; + pMax.y = -ppMin.z; + pMax.z = ppMax.y; + } + else + { + pMin = ppMin; + pMax = ppMax; + } + + HairVoxel* vox = new HairVoxel(stack(),pMin,pMax, stackid(),ix,iy,iz,squirrel()); + if(!vox->HasHair()) + { + delete vox; + continue; + } + //init lookup tables + int vox_idx = (int)voxels().size(); + int num_vox_verts = vox->GetNumVerts(); + for(int i = 0; i < num_vox_verts; i++) + { + _vtovoxs().push_back(vox_idx); + _vtovoxVs().push_back(i); + } + + int num_vox_strands = vox->GetNumStrands(); + for(int i = 0; i < num_vox_strands; i++) + { + _stovoxs().push_back(vox_idx); + _stovoxSs().push_back(i); + } + + //add voxel to list + _voxels().push_back(vox); + + + //expand bounding box + _bboxMin().x = bboxMin().x > pMin.x ? pMin.x : bboxMin().x; + _bboxMin().y = bboxMin().y > pMin.y ? pMin.y : bboxMin().y; + _bboxMin().z = bboxMin().z > pMin.z ? pMin.z : bboxMin().z; + + _bboxMax().x = bboxMax().x < pMax.x ? pMax.x : bboxMax().x; + _bboxMax().y = bboxMax().y < pMax.y ? pMax.y : bboxMax().y; + _bboxMax().z = bboxMax().z < pMax.z ? pMax.z : bboxMax().z; + } + } + } + LOGMSG("SHAVE", "HairNode ctor - OK"); +} + +HAIRAPI HairNode::~HairNode() +{ + LOGMSG("SHAVE", "HairNode dtor"); + + for(unsigned int i = 0; i < (unsigned int)voxels().size(); i++) + { + if(voxel(i)) + { + delete voxel(i); + _voxel(i) = NULL; + } + } + _voxels().clear(); + + _vtovoxs().clear(); + _vtovoxVs().clear(); + + _stovoxs().clear(); + _stovoxSs().clear(); + + LOGMSG("SHAVE", "HairNode dtor - OK"); +} + +/* +| from IHairNode +*/ +HAIRAPI bool HairNode::GetBbox(VERT& pmin, VERT& pmax) const +{ + pmin = bboxMin(); + pmax = bboxMax(); + return (voxels().size() > 0); +} +/* +| from IHairNode +*/ +HAIRAPI int HairNode::GetStackID() const +{ + return stackid(); +} +/* +| from IHairNode +*/ +HAIRAPI int HairNode::GetNumVoxels()const +{ + return (int)voxels().size(); +} +/* +| from IHairNode +*/ +HAIRAPI IHairVoxel* HairNode::GetVoxel(int i) const +{ + if(i < (int)voxels().size()) + return voxel(i); + + return NULL; +} +/* +| from IHairNode +*/ +int HairNode::GetNumVerts () const +{ + return (int)vtovoxs().size(); +} +/* +| from IHairNode +*/ +int HairNode::GetNumStrands() const +{ + return (int)stovoxs().size(); +} +/* +| from IHairNode +*/ +int HairNode::GetNumFaces() const +{ + return (int)stovoxs().size(); +} +/* +| from IHairNode +*/ +void HairNode::GetVert(int i, float& x, float& y, float& z) const +{ + int vox_idx; + int vert_idx; + vertIndexToVoxVertIndex(i,vox_idx,vert_idx); + + voxel(vox_idx)->GetVert(vert_idx,x,y,z); +} +/* +| from IHairNode +*/ +void HairNode::GetVelocity(int i, float& x, float& y, float& z) const +{ + int vox_idx; + int vert_idx; + vertIndexToVoxVertIndex(i,vox_idx,vert_idx); + + voxel(vox_idx)->GetVelocity(vert_idx,x,y,z); +} +/* +| from IHairNode +*/ +void HairNode::GetStrand(int i, int& v_start, int& v_end) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + voxel(vox_idx)->GetStrand(str_idx,v_start,v_end); +} +/* +| from IHairNode +*/ +void HairNode::GetFace(int i, int& v_start, int& v_end) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + voxel(vox_idx)->GetFace(str_idx,v_start,v_end); +} +/* +| from IHairNode +*/ +bool HairNode::IsColorConst (int i) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + return voxel(vox_idx)->IsColorConst(str_idx); +} +/* +| from IHairNode +*/ +void HairNode::GetRootColor (int i, float& r, float& g, float& b) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + voxel(vox_idx)->GetRootColor(str_idx,r,g,b); +} +/* +| from IHairNode +*/ +void HairNode::GetTipColor(int i, float& r, float& g, float& b) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + voxel(vox_idx)->GetTipColor(str_idx,r,g,b); +} +/* +| from IHairNode +*/ +void HairNode::GetVertColor(int i, int knot_idx, float& r, float& g, float& b) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + voxel(vox_idx)->GetVertColor(str_idx,knot_idx,r,g,b); +} +/* +| from IHairNode +*/ +void HairNode::GetColor(int i, float t, float& r, float& g, float& b) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + voxel(vox_idx)->GetColor(str_idx,t,r,g,b); +} +/* +| from IHairNode +*/ +void HairNode::GetSurfNormal(int i, float& x, float& y, float& z) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + voxel(vox_idx)->GetSurfNormal(str_idx,x,y,z); +} +/* +| from IHairNode +*/ +float HairNode::GetStrandGlossiness(int i) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + return voxel(vox_idx)->GetStrandGlossiness(str_idx); +} +/* +| from IHairNode +*/ +float HairNode::GetStrandSpecLevel(int i) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + return voxel(vox_idx)->GetStrandSpecLevel(str_idx); +} + +/* +| from IHairNode +*/ +float HairNode::GetStrandOpacity(int i) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + return voxel(vox_idx)->GetStrandOpacity(str_idx); +} +/* +| from IHairNode +*/ +float HairNode::GetStrandAmbDiff(int i) const +{ + int vox_idx; + int str_idx; + strandIndexToVoxStrandIndex(i,vox_idx,str_idx); + + return voxel(vox_idx)->GetStrandAmbDiff(str_idx); +} + + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +| HairVoxel wrapper | +/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + +HAIRAPI HairVoxel::HairVoxel() +{ + _stack() = NULL; + _hashair() = false; + _nodevoxel()= false; + _nodeindex()= -1; + _squirrel() = false; + + _bboxMin().x = FLT_MAX; + _bboxMin().y = FLT_MAX; + _bboxMin().z = FLT_MAX; + + _bboxMax().x = -FLT_MAX; + _bboxMax().y = -FLT_MAX; + _bboxMax().z = -FLT_MAX; + + _hairtype().owner = NULL; +} + +HAIRAPI HairVoxel::HairVoxel(HairStack* hstack, + const VERT& pmin, const VERT& pmax, + int ix, int iy, int iz, + bool squirr) +{ + LOGMSGI3("SHAVE","HairVoxel ctor",ix, iy, iz); + + _stack() = hstack; + _hashair() = false; + _nodevoxel()= false; + _nodeindex()= -1; + _squirrel() = squirr; + + _bboxMin() = pmin; + _bboxMax() = pmax; + + assert(hstack); + if(!hstack) + return; + + _stack()->Lock(); +#ifdef USE_MEMFILE + LOGMSG("SHAVE","SHAVE2import_mem_archive_voxel"); + SHAVE2import_mem_archive_voxel( stack()->GetMemFile(), ix, iy, iz, &_hairtype(), 0); +#else + LOGMSG("SHAVE","SHAVE2import_archive_voxel"); + SHAVE2import_archive_voxel( hstack->GetDRAname(), ix, iy, iz, &_hairtype(), 0); +#endif + _stack()->UnLock(); + + LOGMSGI("SHAVE","numfaces",hairtype().totalfaces); + + _hashair() = hairtype().totalfaces != 0; + _hairtype().owner = hstack; + _hairtype().squirrel = squirrel(); + + LOGMSG("SHAVE","HairVoxel ctor - OK"); +} + +HAIRAPI HairVoxel::HairVoxel(HairStack* hstack, + const VERT& pmin, const VERT& pmax, + int stack_id, int ix, int iy, int iz, + bool squirr) +{ + LOGMSGI3("SHAVE","HairVoxel ctor2",ix, iy, iz); + + _stack() = hstack; + _hashair() = false; + _nodevoxel()= true; + _nodeindex()= stack_id; + + _squirrel() = squirr; + + _bboxMin() = pmin; + _bboxMax() = pmax; + + assert(hstack); + if(!hstack) + return; + + _stack()->Lock(); + +#ifdef USE_MEMFILE + LOGMSG("SHAVE","SHAVE2import_mem_archive_voxel_by_node"); + SHAVE2import_mem_archive_voxel_by_node(stack()->GetMemFile(),ix,iy,iz, + &_hairtype(), &_hairuvs(), + 0, stack_id); +#else + LOGMSG("SHAVE","SHAVE2import_archive_voxel_by_node"); + SHAVE2import_archive_voxel_by_node(hstack->GetDRAname(),ix,iy,iz, + &_hairtype(), &_hairuvs(), + 0, stack_id); +#endif + LOGMSGI("SHAVE","numfaces",hairtype().totalfaces); + + _stack()->UnLock(); + + _hashair() = hairtype().totalfaces != 0; + _hairtype().owner = hstack; + _hairtype().squirrel = squirrel(); + + ////////////// debug //////////// + //int nv = hairtype().GetNumVerts(); + //for(int i = 0; i < nv; i++) + //{ + // float u,v,w; + // hairtype().GetUV(i,u,v,w); + // printf("uvw %f %f %f\n", u,v,w); + //} + //fflush(stdout); + ///////////////////////////////// + + LOGMSG("SHAVE","HairVoxel ctor2 - OK"); +} + +HAIRAPI HairVoxel::~HairVoxel() +{ + LOGMSG("SHAVE","HairVoxel dtor"); + LOGMSG("SHAVE","HairVoxel dtor - OK"); +} +/* +| from IHairVoxel +*/ +HAIRAPI bool HairVoxel::HasHair() const +{ + return hashair(); +} +/* +| from IHairVoxel +*/ +HAIRAPI bool HairVoxel::IsNodeVoxel() const +{ + return nodevoxel(); +} +/* +| from IHairVoxel +*/ +HAIRAPI int HairVoxel::GetNodeID(void) const +{ + return nodeindex(); +} +/* +| from IHairVoxel +*/ +HAIRAPI bool HairVoxel::GetBbox(VERT& pmin, VERT& pmax) const +{ + pmin = bboxMin(); + pmax = bboxMax(); + + return hashair(); +} +/* +| from IHairVoxel +*/ +HAIRAPI const HairType& HairVoxel::GetHair(/*bool isShadow*/) +{ + return hairtype(); +} +/* +| from IHairVoxel +*/ +HAIRAPI const HairUVs& HairVoxel::GetUVs (/*bool isShadow*/) +{ + return hairuvs(); +} +/* +| from IHairVoxel +*/ +int HairVoxel::GetNumVerts () const +{ + return hairtype().GetNumVerts(); +} +/* +| from IHairVoxel +*/ +int HairVoxel::GetNumStrands() const +{ + return hairtype().GetNumStrands(); +} +/* +| from IHairVoxel +*/ +int HairVoxel::GetNumFaces() const +{ + return hairtype().GetNumFaces(); +} +/* +| from IHairVoxel +*/ +void HairVoxel::GetVert(int vertidx, float& x, float& y, float& z) const +{ + hairtype().GetVert(vertidx,x,y,z); +} +/* +| from IHairVoxel +*/ +void HairVoxel::GetVelocity(int vertidx, float& x, float& y, float& z) const +{ + hairtype().GetVelocity(vertidx,x,y,z); +} +/* +| from IHairVoxel +*/ +void HairVoxel::GetStrand(int strandidx, int& v_start, int& v_end) const +{ + hairtype().GetStrand(strandidx,v_start,v_end); +} +/* +| from IHairVoxel +*/ +void HairVoxel::GetFace(int faceidx, int& v_start, int& v_end) const +{ + hairtype().GetFace(faceidx,v_start,v_end); +} +/* +| from IHairVoxel +*/ +bool HairVoxel::IsColorConst(int strandidx) const +{ + return hairtype().IsColorConst(strandidx); +} +/* +| from IHairVoxel +*/ +void HairVoxel::GetRootColor(int strandidx, float& r, float& g, float& b) const +{ + hairtype().GetRootColor(strandidx,r,g,b); +} +/* +| from IHairVoxel +*/ +void HairVoxel::GetTipColor(int strandidx, float& r, float& g, float& b) const +{ + hairtype().GetTipColor(strandidx,r,g,b); +} +/* +| from IHairVoxel +*/ +void HairVoxel::GetVertColor(int strandidx, int knot_idx, float& r, float& g, float& b) const +{ + hairtype().GetVertColor(strandidx,knot_idx,r,g,b); +} +/* +| from IHairVoxel +*/ +void HairVoxel::GetColor(int strandidx, float t, float& r, float& g, float& b) const +{ + hairtype().GetColor(strandidx,t,r,g,b); +} +/* +| from IHairVoxel +*/ +void HairVoxel::GetSurfNormal(int strandidx, float& x, float& y, float& z) const +{ + hairtype().GetSurfNormal(strandidx,x,y,z); +} +/* +| from IHairVoxel +*/ +float HairVoxel::GetStrandGlossiness(int i) const +{ + return hairtype().gloss[i]; +} +/* +| from IHairVoxel +*/ +float HairVoxel::GetStrandSpecLevel(int i) const +{ + return hairtype().spec[i]; +} +/* +| from IHairVoxel +*/ +float HairVoxel::GetStrandOpacity(int i) const +{ + return hairtype().opacity[i]; +} +/* +| from IHairVoxel +*/ +float HairVoxel::GetStrandAmbDiff(int i) const +{ + return hairtype().ambdiff[i]; +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +| HairType wrapper | +/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + +HAIRAPI HairType::HairType(bool init) +{ + if(init) + { + LOGMSG("SHAVE","SHAVE2init_hairtype"); + SHAVE2init_hairtype(this); + } + squirrel = false; +} + +HAIRAPI HairType::~HairType() +{ + LOGMSG("SHAVE","SHAVE2free_hairtype"); + SHAVE2free_hairtype(this); +} + +int HairType::GetNumStrands() const +{ + return totalfaces; +} + +int HairType::GetNumFaces() const +{ + return totalfaces; +} + +int HairType::GetNumVerts() const +{ + return totalverts; +} + +int HairType::GetFaceVert(int face_list_idx ) const +{ + return facelist[face_list_idx]; +} + +void HairType::GetVert(int i, float &x, float &y, float &z) const +{ + bool doswap = owner ? ((HairStack*)owner)->GetNeedYZswap() : false; + if(doswap) + { + x = v[i].x; + y = -v[i].z; + z = v[i].y; + } + else + { + x = v[i].x; + y = v[i].y; + z = v[i].z; + } +} + +void HairType::GetUV (int i, float& u, float& v, float& w) const +{ + u = uvw[i].x; + v = uvw[i].y; + w = uvw[i].z; +} + +void HairType::GetVelocity(int i, float& x, float& y, float& z) const +{ + bool doswap = owner ? ((HairStack*)owner)->GetNeedYZswap() : false; + if(doswap) + { + x = velocity[i].x; + y = -velocity[i].z; + z = velocity[i].y; + } + else + { + x = velocity[i].x; + y = velocity[i].y; + z = velocity[i].z; + } + //x = 0.0f; + //y = 0.0f; + //z = 0.0f; +} + + +void HairType::GetStrand(int i, int& v_start, int& v_end) const +{ + v_start = face_start[i]; + v_end = face_end[i]; +} + +void HairType::GetFace(int i, int& v_start, int& v_end) const +{ + v_start = face_start[i]; + v_end = face_end[i]; +} + +bool HairType::IsColorConst(int i) const +{ + return (colorroot[i].x == colortip[i].x) && + (colorroot[i].y == colortip[i].y) && + (colorroot[i].z == colortip[i].z); +} + +void HairType::GetRootColor(int i, float& r, float& g, float& b) const +{ + r = colorroot[i].x; + g = colorroot[i].y; + b = colorroot[i].z; +} + +void HairType::GetTipColor (int i, float& r, float& g, float& b) const +{ + r = colortip[i].x; + g = colortip[i].y; + b = colortip[i].z; +} + +void HairType::GetVertColor(int i, int v, float& r, float& g, float& b) const +{ + if((colorroot[i].x == colortip[i].x) && + (colorroot[i].y == colortip[i].y) && + (colorroot[i].z == colortip[i].z)) + { + r = colorroot[i].x; + g = colorroot[i].y; + b = colorroot[i].z; + + return; + } + + int nknots = face_end[i] - face_start[i]; + float t = (float)v/(float)nknots; + float T = 1.0f - t; + + if (!squirrel) + { + r = colorroot[i].x*T + colortip[i].x*t; + g = colorroot[i].y*T + colortip[i].y*t; + b = colorroot[i].z*T + colortip[i].z*t; + } + else + { + if (t<.7) + { + r=colorroot[i].x; + g=colorroot[i].y; + b=colorroot[i].z; + } + else + { + r=colortip[i].x; + g=colortip[i].y; + b=colortip[i].z; + } + } +} + +void HairType::GetColor (int i, float t, float& r, float& g, float& b) const +{ + if((colorroot[i].x == colortip[i].x) && + (colorroot[i].y == colortip[i].y) && + (colorroot[i].z == colortip[i].z)) + { + r = colorroot[i].x; + g = colorroot[i].y; + b = colorroot[i].z; + + return; + } + if (!squirrel) + { + float T = 1.0f - t; + r = colorroot[i].x*T + colortip[i].x*t; + g = colorroot[i].y*T + colortip[i].y*t; + b = colorroot[i].z*T + colortip[i].z*t; + } + else + { + if (t<.7) + { + r=colorroot[i].x; + g=colorroot[i].y; + b=colorroot[i].z; + } + else + { + r=colortip[i].x; + g=colortip[i].y; + b=colortip[i].z; + } + } +} + +void HairType::GetSurfNormal(int i, float& x, float& y, float& z) const +{ + bool doswap = owner ? ((HairStack*)owner)->GetNeedYZswap() : false; + if(doswap) + { + x = surfNorm[i].x; + y = -surfNorm[i].z; + z = surfNorm[i].y; + } + else + { + x = surfNorm[i].x; + y = surfNorm[i].y; + z = surfNorm[i].z; + } + +} + +float HairType::GetStrandGlossiness(int i) const +{ + return gloss[i]; +} + +float HairType::GetStrandSpecLevel(int i) const +{ + return spec[i]; +} + +float HairType::GetStrandOpacity(int i) const +{ + return opacity[i]; +} + +float HairType::GetStrandAmbDiff(int i) const +{ + return ambdiff[i]; +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +| HairUVs wrapper | +/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +HAIRAPI HairUVs::HairUVs(bool init) +{ + if(init) + { + LOGMSG("SHAVE", "SHAVE2init_UV"); + SHAVE2init_UV(this); + } +} + +HAIRAPI HairUVs::~HairUVs() +{ + LOGMSG("SHAVE", "SHAVE2free_UV"); + //comment for text + SHAVE2free_UV(this); +} + + -- cgit v1.2.3