#include #include #include #include #include #include #include #include //for Nearest Neighbor Searching #include #include #include typedef reviver::dpoint Point; // #define NUM_OF_POINTS_PER_SLICE 300 // #define TMP_WIDTH 0.1 using namespace::std; float floatRand(){ return (float)rand() / (float)RAND_MAX; } float distance(float p1[3], float p2[3]){ return sqrt(pow(p1[0] - p2[0],2) + pow(p1[1] - p2[1],2) + pow(p1[2] - p2[2],2)); } void invertMat(float *m, float *outMat) { outMat[0] = m[6]*m[11]*m[13] - m[7]*m[10]*m[13] + m[7]*m[9]*m[14] - m[5]*m[11]*m[14] - m[6]*m[9]*m[15] + m[5]*m[10]*m[15]; outMat[1] = m[3]*m[10]*m[13] - m[2]*m[11]*m[13] - m[3]*m[9]*m[14] + m[1]*m[11]*m[14] + m[2]*m[9]*m[15] - m[1]*m[10]*m[15]; outMat[2] = m[2]*m[7]*m[13] - m[3]*m[6]*m[13] + m[3]*m[5]*m[14] - m[1]*m[7]*m[14] - m[2]*m[5]*m[15] + m[1]*m[6]*m[15]; outMat[3] = m[3]*m[6]*m[9] - m[2]*m[7]*m[9] - m[3]*m[5]*m[10] + m[1]*m[7]*m[10] + m[2]*m[5]*m[11] - m[1]*m[6]*m[11]; outMat[4] = m[7]*m[10]*m[12] - m[6]*m[11]*m[12] - m[7]*m[8]*m[14] + m[4]*m[11]*m[14] + m[6]*m[8]*m[15] - m[4]*m[10]*m[15]; outMat[5] = m[2]*m[11]*m[12] - m[3]*m[10]*m[12] + m[3]*m[8]*m[14] - m[0]*m[11]*m[14] - m[2]*m[8]*m[15] + m[0]*m[10]*m[15]; outMat[6] = m[3]*m[6]*m[12] - m[2]*m[7]*m[12] - m[3]*m[4]*m[14] + m[0]*m[7]*m[14] + m[2]*m[4]*m[15] - m[0]*m[6]*m[15]; outMat[7] = m[2]*m[7]*m[8] - m[3]*m[6]*m[8] + m[3]*m[4]*m[10] - m[0]*m[7]*m[10] - m[2]*m[4]*m[11] + m[0]*m[6]*m[11]; outMat[8] = m[5]*m[11]*m[12] - m[7]*m[9]*m[12] + m[7]*m[8]*m[13] - m[4]*m[11]*m[13] - m[5]*m[8]*m[15] + m[4]*m[9]*m[15]; outMat[9] = m[3]*m[9]*m[12] - m[1]*m[11]*m[12] - m[3]*m[8]*m[13] + m[0]*m[11]*m[13] + m[1]*m[8]*m[15] - m[0]*m[9]*m[15]; outMat[10] = m[1]*m[7]*m[12] - m[3]*m[5]*m[12] + m[3]*m[4]*m[13] - m[0]*m[7]*m[13] - m[1]*m[4]*m[15] + m[0]*m[5]*m[15]; outMat[11] = m[3]*m[5]*m[8] - m[1]*m[7]*m[8] - m[3]*m[4]*m[9] + m[0]*m[7]*m[9] + m[1]*m[4]*m[11] - m[0]*m[5]*m[11]; outMat[12] = m[6]*m[9]*m[12] - m[5]*m[10]*m[12] - m[6]*m[8]*m[13] + m[4]*m[10]*m[13] + m[5]*m[8]*m[14] - m[4]*m[9]*m[14]; outMat[13] = m[1]*m[10]*m[12] - m[2]*m[9]*m[12] + m[2]*m[8]*m[13] - m[0]*m[10]*m[13] - m[1]*m[8]*m[14] + m[0]*m[9]*m[14]; outMat[14] = m[2]*m[5]*m[12] - m[1]*m[6]*m[12] - m[2]*m[4]*m[13] + m[0]*m[6]*m[13] + m[1]*m[4]*m[14] - m[0]*m[5]*m[14]; outMat[15] = m[1]*m[6]*m[8] - m[2]*m[5]*m[8] + m[2]*m[4]*m[9] - m[0]*m[6]*m[9] - m[1]*m[4]*m[10] + m[0]*m[5]*m[10]; } class particle { public: particle(RtPoint p_P){ id = count++; P[0] = p_P[0]; P[1] = p_P[1]; P[2] = p_P[2]; constantwidth = 0.1; Cs[0] = 1; Cs[1] = 0.5; Cs[2] = 0.25; multiPointRadius =1; velocity[0] = 0; velocity[1] = 0; velocity[2] = 0; distanceFromCamera = 0; resourceHandleId = -1; }; ~particle(); static int count; //static bool isSorted; int getId(){ return id; } float getP(int index){ return P[index]; } void setConstantwidth(float p_constantwidth){ constantwidth = p_constantwidth; } float getConstantwidth(){ return constantwidth; } void setCs(float p_Cs[3]){ Cs[0] = p_Cs[0]; Cs[1] = p_Cs[1]; Cs[2] = p_Cs[2]; } float getCs(int index){ return Cs[index]; } void setMultiPointRadius(float p_multiPointRadius){ multiPointRadius = p_multiPointRadius; } float getMultiPointRadius(){ return multiPointRadius; } void setVelocity(float p_velocity[3]){ velocity[0] = p_velocity[0]; velocity[1] = p_velocity[1]; velocity[2] = p_velocity[2]; } float getVelocity(int index){ return velocity[index]; } void setDistanceFromCamera(RtPoint p_camPosition){ distanceFromCamera = distance(P,p_camPosition); } float getDistanceFromCamera(){ return distanceFromCamera; } void setResourceHandleId(int p_resourceHandleId){ resourceHandleId = p_resourceHandleId; } int getResourceHandleId(){ return resourceHandleId; } private: int id; float Cs[3]; float P[3]; float constantwidth; float multiPointRadius; float velocity[3]; float distanceFromCamera; int resourceHandleId; }; int particle::count = 0; bool compareDistanceOfParticleFromCamera(particle* first, particle* second){ bool result = false; if(first->getDistanceFromCamera() < second->getDistanceFromCamera()){ result = true; } return result; } class f : public RifPlugin { public: f(); virtual ~f(); virtual RifFilter & GetFilter(); float* getCurrentCameraPosition(){ return current_cameraPosition; } char* getProceduralPrimitiveDsoPath(){ return proceduralPrimitiveDsoPath; } int NUM_OF_POINTS_PER_SLICE; float pointWidth; private: RifFilter filter; static RtVoid nuPatchV(RtInt nu, RtInt uorder, RtFloat uknot[], RtFloat umin, RtFloat umax, RtInt nv, RtInt vorder, RtFloat vknot[], RtFloat vmin, RtFloat vmax, RtInt, RtToken[], RtPointer[]); static RtVoid pointsGeneralPolygonsV(RtInt npolys, RtInt nloops[], RtInt nverts[], RtInt verts[], RtInt, RtToken[], RtPointer[]); static RtVoid pointsV(RtInt nverts, RtInt, RtToken[], RtPointer[]); static RtVoid optionV(RtToken name, RtInt, RtToken[], RtPointer[]); static RtVoid readArchiveV(RtToken name, RtArchiveCallback callback,RtInt, RtToken[], RtPointer[]); static RtVoid frameBegin(RtInt); static RtVoid frameEnd(); static RtVoid displayV(char *name, RtToken type, RtToken mode,RtInt, RtToken[], RtPointer[]); static RtVoid concatTransform(RtMatrix transform); static RtVoid worldBegin(); static RtVoid worldEnd(); void comp(char* originalPath, int currentSliceNum); static void addParticle(f *obj,RtInt nverts, RtInt n, RtToken* keys, RtPointer* vals,int resourceHandleId); static void insertSlicedFinalParticle(); static void insertMergedParticle(); char proceduralPrimitiveDsoPath[512]; int numOfDots; enum {none, final, deepShadow, shadow} current_passClass; enum {inside,outside} isInFrameBlock; enum {insideWorld,outsideWorld} isInWorldBlock; float current_cameraPosition[3]; list particle_list; list particleNames; bool isSorted; bool isNNS_done; int finalPass_numOfSlice; int sliceNumber; char* originalImgPath; int tmpInt; time_t renderStartTime,renderEndTime; double timeDiff; //NN vector ans; nnBase *NN; }; RifPlugin * RifPluginManufacture(int args, char **argv) { f *f_obj = new f(); return f_obj; } f::f() { time (&renderStartTime); cout << "\n"; cout << "Start Slice Point Rendering..." < (RifGetCurrentPlugin()); if(obj->current_passClass == final){ RiMatte(RI_TRUE); } RiNuPatchV(nu,uorder,uknot,umin,umax,nv,vorder,vknot,vmin,vmax,n,keys,vals); } RtVoid f::pointsGeneralPolygonsV(RtInt npolys, RtInt nloops[], RtInt nverts[], RtInt verts[], RtInt n, RtToken* keys, RtPointer* vals){ f *obj = static_cast (RifGetCurrentPlugin()); if(obj->current_passClass == final){ RiMatte(RI_TRUE); } RiPointsGeneralPolygonsV(npolys,nloops,nverts,verts,n,keys,vals); } RtVoid f::pointsV(RtInt nverts, RtInt n, RtToken* keys, RtPointer* vals) { //check if RiPoints from DSO or shadow bool skip = false; for(int q = 0; q < n ;q++){ if(strcmp(keys[q],"fromDso")==0){ //cout << "keys[q] : " << keys[q] << "------------" << endl; skip = true; break; } } if(!skip){ f *obj = static_cast (RifGetCurrentPlugin()); //get identity - name char **name = (char **)alloca(1); RxInfoType_t type; RtInt resultcnt, size; size = RxAttribute("identifier:name",name,(sizeof(char*)),&type,&resultcnt); int resourceHandleId = 0; //check if already added particle bool isThereMyName = false; list::iterator it; for(it = obj->particleNames.begin(); it != obj->particleNames.end(); it++){ resourceHandleId ++; //cout << "+name : " << *it <particleNames.push_back(*name); resourceHandleId ++; //cout << "*name : " << *name <finalPass_numOfSlice = ((int)obj->particle_list.size()/(int)obj->NUM_OF_POINTS_PER_SLICE) +1; // cout << "numOfSlices : " << obj->finalPass_numOfSlice << endl; }else{ //save resource char resourceHandle[128]; sprintf(resourceHandle,"resourceHandle_%d",resourceHandleId); //cout << "saving resourceHandle : " << resourceHandle <current_passClass == final){ }else if(obj->current_passClass == deepShadow){ //do nothing for now //RiPointsV(nverts,n,keys,vals); } }else{ RiPointsV(nverts,n,keys,vals); } } RtVoid f::optionV(RtToken name, RtInt n, RtToken * keys, RtPointer * vals){ f *obj = static_cast (RifGetCurrentPlugin()); //extremedisplacement fix bool doSomething = true; static char* types[] = { "float", "point", "color", "integer", "string", "vector", "normal", "hpoint", "matrix", "mpoint" }; static char* details[] = { "constant", "uniform", "varying", "vertex", "varying"}; for(int i=0;icurrent_passClass = final; }else if(strcmp(pass_class,"DeepShadow")==0){ obj->current_passClass = deepShadow; } //cout << "current_passClass : " << obj->current_passClass < (RifGetCurrentPlugin()); RiReadArchive(name,(RtArchiveCallback)RI_NULL); // cout << "S : "<< name << endl; // cout << "current_passClass : " << obj->current_passClass <isInFrameBlock == outside){ // cout << "M : "<< name <<"@@@@@@@@@@@@@@@@@@@@@@@@@"<< endl; if(obj->current_passClass == final){ cout << "Number of Points in Each Slice : " << obj->NUM_OF_POINTS_PER_SLICE <sliceNumber = 0; for(int n = 0; n < obj->finalPass_numOfSlice ; n++){ // cout << "slice number$$$ : "<< obj->sliceNumber <sliceNumber++; } obj->sliceNumber = -1; }else if(obj->current_passClass == deepShadow){ } obj->isSorted = false; } } RtVoid f::frameBegin(RtInt frameNumber){ f *obj = static_cast (RifGetCurrentPlugin()); obj->isInFrameBlock = inside; RiFrameBegin(frameNumber); } RtVoid f::frameEnd(){ RiFrameEnd(); f *obj = static_cast (RifGetCurrentPlugin()); obj->isInFrameBlock = outside; } void slicePathMake(const char* original, int sliceNum, char* result){ char tmpSliceName[512]; char newSliceName[512]; strcpy(tmpSliceName,original); strcat(tmpSliceName,".%d.tif"); sprintf(newSliceName,tmpSliceName,sliceNum); strcpy(result,newSliceName); //cout << "========== " << result < (RifGetCurrentPlugin()); if(obj->current_passClass == final && obj->sliceNumber != -1){ char newSliceName[512]; slicePathMake(name,obj->sliceNumber,newSliceName); RiDisplayV(newSliceName,type,mode,n,keys,vals); }else if(obj->current_passClass == deepShadow){ RiDisplayV(name,type,mode,n,keys,vals); } obj->originalImgPath = name; } //get and set camera position RtVoid f::concatTransform(RtMatrix transform){ f *obj = static_cast (RifGetCurrentPlugin()); if(obj->isInWorldBlock == outsideWorld){ float inMat[16]; int tmpN = 0; for(int a = 0 ; a< 4 ; a++){ for(int b = 0 ; b< 4 ; b++){ inMat[tmpN] = transform[a][b]; //cout << "Tr mat : "<< tmpN << " _ " << transform[a][b] << endl; //cout << "inMat : "<< tmpN << " _ " << inMat[tmpN] << endl; tmpN++; } } float outMat[16]; invertMat(inMat, outMat); obj->current_cameraPosition[0] = -outMat[12]; obj->current_cameraPosition[1] = -outMat[13]; obj->current_cameraPosition[2] = -outMat[14]; // cout << "+cam x : "<< obj->current_cameraPosition[0] << endl; // cout << "+cam y : "<< obj->current_cameraPosition[1] << endl; // cout << "+cam z : "<< obj->current_cameraPosition[2] << endl; } RiConcatTransform(transform); } void doNN(int nverts,const RtPoint *P_Rib,double *nearestDistances){ //int detail = INT_MAX/100; double detail = 1000000; double offset = 1000; Point *P = (Point*)malloc(nverts*sizeof(Point)); for(int n = 0 ; n < nverts ; n++){ unsigned int P_treeX = (unsigned int)((P_Rib[n][0]+offset)*detail); unsigned int P_treeY = (unsigned int)((P_Rib[n][1]+offset)*detail); unsigned int P_treeZ = (unsigned int)((P_Rib[n][2]+offset)*detail); Point treeP(P_treeX,P_treeY,P_treeZ); P[n][0] = treeP[0]; P[n][1] = treeP[1]; P[n][2] = treeP[2]; //cout << P[n][0] <<" "<< P[n][1] <<" "<< P[n][2] < ans ; nnBase *NN; int size = nverts; ans.resize(1); //cout << NN << endl; NN = new sfcnn_ip(P,size); //cout << "whatbbb\n"; for(int n = 0 ; n < nverts ; n++){ Point queryP(P[n][0],P[n][1],P[n][2]); NN->ksearch(&queryP,3,ans); Point tmp1 = *(ans[1]); Point tmp2 = *(ans[2]); double nX1 = double(tmp1[0]); double nY1 = double(tmp1[1]); double nZ1 = double(tmp1[2]); double nX2 = double(tmp2[0]); double nY2 = double(tmp2[1]); double nZ2 = double(tmp2[2]); double dist1 = sqrt(pow(double(P[n][0])-nX1,2)+pow(double(P[n][1])-nY1,2)+pow(double(P[n][2])-nZ1,2)); double dist2 = sqrt(pow(double(P[n][0])-nX2,2)+pow(double(P[n][1])-nY2,2)+pow(double(P[n][2])-nZ2,2)); nearestDistances[n] = ((dist1 + dist2)/2) / detail; } delete NN; free(P); } void NNS(list particle_list){ int nverts = particle_list.size(); RtPoint* Ps = (RtPoint*)malloc(sizeof(RtPoint)*nverts); double* nearestDistances = (double*)malloc(sizeof(double)*nverts); list::iterator it; int n = 0; for(it = particle_list.begin(); it != particle_list.end(); it++){ particle* tmpParticle = *it; Ps[n][0] = tmpParticle->getP(0); Ps[n][1] = tmpParticle->getP(1); Ps[n][2] = tmpParticle->getP(2); nearestDistances[n] = 0; n++; } //cout << "nverts : "<< nverts <setMultiPointRadius(nearestDistances[n]); n++; } free(Ps); free(nearestDistances); } RtVoid f::worldBegin(){ f *obj = static_cast (RifGetCurrentPlugin()); obj->isInWorldBlock = insideWorld; list::iterator it;; if(!obj->isSorted && obj->particle_list.size() != 0){ for(it = obj->particle_list.begin();it != obj->particle_list.end();it++){ particle *tmpParticle = *it; tmpParticle->setDistanceFromCamera(obj->current_cameraPosition); } cout << "Number of Particles : " << obj->particle_list.size()<current_passClass<particle_list.sort(compareDistanceOfParticleFromCamera); time (&end); dif = difftime (end,start); cout << "Sorted in " << dif << " seconds"<< endl; obj->isSorted = true; if(!obj->isNNS_done){ NNS(obj->particle_list); obj->isNNS_done = true; } } RiWorldBegin(); } void f::comp(char* originalPath, int currentSliceNum){ f *obj = static_cast (RifGetCurrentPlugin()); //cout << "o_path : " << originalPath << " sn : " << currentSliceNum <finalPass_numOfSlice<finalPass_numOfSlice-1){ //cout << "last slice!\n"; sprintf(command,"mv %s %s ",currentSliceName,originalPath); RiSystem(command); } } RtVoid f::worldEnd(){ f *obj = static_cast (RifGetCurrentPlugin()); if(obj->sliceNumber != -1){ insertSlicedFinalParticle(); } if(obj->current_passClass == deepShadow){ insertMergedParticle(); } RiWorldEnd(); obj->isInWorldBlock = outsideWorld; //comp if(obj->originalImgPath,obj->sliceNumber > 0 && obj->current_passClass == final){ obj->comp(obj->originalImgPath,obj->sliceNumber); } } void f::addParticle(f *obj,RtInt nverts, RtInt n, RtToken* keys, RtPointer* vals,int resourceHandleId){ RtPoint *particlePositions; float *constantwidth; RtColor *Cs; RtVector *velocity; for(int q = 0; q < n ;q++){ if(strcmp(keys[q],"P")==0){ particlePositions = (RtPoint*)vals[q]; //cout << "found P! " << *particlePositions[0] << "," << *particlePositions[1]<<"," << *particlePositions[2]<setConstantwidth(*constantwidth); tmpParticle->setCs(Cs[m]); tmpParticle->setVelocity(velocity[m]); tmpParticle->setResourceHandleId(resourceHandleId); obj->particle_list.push_back(tmpParticle); } // cout << "particle added in passClass " << obj->current_passClass << endl; } RtVoid freestrings(RtString *twostrings) { free((void *)twostrings[0]); free((void *)twostrings[1]); free((void *)twostrings); } void dynamicLoad(float* P,float constantwidth,float multiPointRadius,int numOfDots,int id,float* Cs){ f *obj = static_cast (RifGetCurrentPlugin()); constantwidth = obj->pointWidth; char buffer[256]; sprintf(buffer,"%f %d %d %f %f %f %f %f %f %f", multiPointRadius,numOfDots,id,constantwidth,P[0],P[1],P[2],Cs[0],Cs[1],Cs[2]); RtBound myBound = {-100,100, -100,100 ,-100, 100}; RtString *twostrings = (RtString *)malloc(2 * sizeof(RtString)); twostrings[0] = strdup(obj->getProceduralPrimitiveDsoPath()); twostrings[1] = strdup(buffer); RiProcedural (twostrings,myBound,RiProcDynamicLoad,(RtProcFreeFunc)freestrings); } //for deepShadow rendering - put all particle at once (for naw) void f::insertMergedParticle(){ f *obj = static_cast (RifGetCurrentPlugin()); list::iterator it; for(it = obj->particle_list.begin(); it != obj->particle_list.end();it++){ particle* tmpParticle = *it; char resourceHandle[128]; sprintf(resourceHandle,"resourceHandle_%d",tmpParticle->getResourceHandleId()); RtToken restore[1] = {"restore"}; RtToken shading[1] = {"shading"}; //RiResource(resourceHandle,"attributes","string operation",restore,"string subset",shading,NULL); //dso parameter setting RtPoint P = {tmpParticle->getP(0),tmpParticle->getP(1),tmpParticle->getP(2)}; float constantwidth = tmpParticle->getConstantwidth(); float multiPointRadius = tmpParticle->getMultiPointRadius(); int numOfDots = obj->numOfDots; int id = tmpParticle->getId(); RtColor Cs = {tmpParticle->getCs(0),tmpParticle->getCs(1),tmpParticle->getCs(2)}; //cout << "dynamic call for Final" < (RifGetCurrentPlugin()); int particleStartId = (obj->sliceNumber)* obj->NUM_OF_POINTS_PER_SLICE; list::iterator it = obj->particle_list.begin(); int n = 0; //go to start point while(it!=obj->particle_list.end() && n < particleStartId){ it++; n++; } while(it!=obj->particle_list.end() && n< particleStartId+obj->NUM_OF_POINTS_PER_SLICE){ //cout << " sliceNum_" << obj->sliceNumber<<" : "<< n <getResourceHandleId()); RtToken restore[1] = {"restore"}; RtToken shading[1] = {"shading"}; RiResource(resourceHandle,"attributes","string operation",restore,"string subset",shading,NULL); //dso parameter setting RtPoint P = {tmpParticle->getP(0),tmpParticle->getP(1),tmpParticle->getP(2)}; float constantwidth = tmpParticle->getConstantwidth(); float multiPointRadius = tmpParticle->getMultiPointRadius(); int numOfDots = obj->numOfDots; int id = tmpParticle->getId(); RtColor Cs = {tmpParticle->getCs(0),tmpParticle->getCs(1),tmpParticle->getCs(2)}; //cout << "dynamic call for Final" <