AtNode *createCurvesNode(nodeData &nodata, userData * ud, std::vector<float> &samples, int i) { Alembic::AbcGeom::ICurves typedObject(nodata.object, Alembic::Abc::kWrapExisting); size_t minNumSamples = typedObject.getSchema().getNumSamples() == 1 ? typedObject.getSchema().getNumSamples() : samples.size(); shiftedProcessing(nodata, ud); AtNode *shapeNode = AiNode("curves"); nodata.createdShifted = false; // create arrays to hold the data AtArray *pos = NULL; // loop over all samples AtULong posOffset = 0; size_t totalNumPoints = 0; size_t totalNumPositions = 0; for(size_t sampleIndex = 0; sampleIndex < minNumSamples; ++sampleIndex) { SampleInfo sampleInfo = getSampleInfo( samples[sampleIndex], typedObject.getSchema().getTimeSampling(), typedObject.getSchema().getNumSamples() ); // get the floor sample Alembic::AbcGeom::ICurvesSchema::Sample sample; typedObject.getSchema().get(sample,sampleInfo.floorIndex); // access the num points Alembic::Abc::Int32ArraySamplePtr abcNumPoints = sample.getCurvesNumVertices(); // take care of the topology if(sampleIndex == 0) { // hard coded pixel width, basis and mode AiNodeSetFlt(shapeNode, "min_pixel_width", 0.25f); AiNodeSetStr(shapeNode, "basis", "catmull-rom"); AiNodeSetStr(shapeNode, "mode", ud->gCurvesMode.c_str()); // setup the num_points AtArray * numPoints = AiArrayAllocate((AtInt)abcNumPoints->size(),1,AI_TYPE_UINT); for(size_t i=0;i<abcNumPoints->size();i++) { totalNumPoints += abcNumPoints->get()[i]; totalNumPositions += abcNumPoints->get()[i] + 2; AiArraySetUInt(numPoints,(AtULong)i,(AtUInt)(abcNumPoints->get()[i]+2)); } AiNodeSetArray(shapeNode,"num_points",numPoints); // check if we have a radius Alembic::Abc::IFloatArrayProperty propRadius; if( getArbGeomParamPropertyAlembic( typedObject, "radius", propRadius ) ) { Alembic::Abc::FloatArraySamplePtr abcRadius = propRadius.getValue(sampleInfo.floorIndex); AtArray * radius = AiArrayAllocate((AtInt)abcRadius->size(),1,AI_TYPE_FLOAT); for(size_t i=0; i < abcRadius->size(); ++i) AiArraySetFlt(radius,(AtULong)i,abcRadius->get()[i]); AiNodeSetArray(shapeNode,"radius",radius); } // check if we have uvs Alembic::AbcGeom::IV2fGeomParam uvsParam = typedObject.getSchema().getUVsParam(); if(uvsParam.valid()) { Alembic::Abc::V2fArraySamplePtr abcUvs = uvsParam.getExpandedValue(sampleInfo.floorIndex).getVals(); if(AiNodeDeclare(shapeNode, "Texture_Projection", "uniform POINT2")) { AtArray* uvs = AiArrayAllocate((AtInt)abcUvs->size(), 1, AI_TYPE_POINT2); AtPoint2 uv; for(size_t i=0; i<abcUvs->size(); i++) { uv.x = abcUvs->get()[i].x; uv.y = abcUvs->get()[i].y; AiArraySetPnt2(uvs, (AtULong)i, uv); } AiNodeSetArray(shapeNode, "Texture_Projection", uvs); } } // check if we have colors Alembic::Abc::IC4fArrayProperty propColor; if( getArbGeomParamPropertyAlembic( typedObject, "color", propColor ) ) { Alembic::Abc::C4fArraySamplePtr abcColors = propColor.getValue(sampleInfo.floorIndex); AtBoolean result = false; if(abcColors->size() == 1) result = AiNodeDeclare(shapeNode, "Color", "constant RGBA"); else if(abcColors->size() == abcNumPoints->size()) result = AiNodeDeclare(shapeNode, "Color", "uniform RGBA"); else result = AiNodeDeclare(shapeNode, "Color", "varying RGBA"); if(result) { AtArray * colors = AiArrayAllocate((AtInt)abcColors->size(), 1, AI_TYPE_RGBA); AtRGBA color; for(size_t i=0; i<abcColors->size(); ++i) { color.r = abcColors->get()[i].r; color.g = abcColors->get()[i].g; color.b = abcColors->get()[i].b; color.a = abcColors->get()[i].a; AiArraySetRGBA(colors, (AtULong)i, color); } AiNodeSetArray(shapeNode, "Color", colors); } } } // access the positions Alembic::Abc::P3fArraySamplePtr abcPos = sample.getPositions(); if(pos == NULL) pos = AiArrayAllocate((AtInt)(totalNumPositions * 3),(AtInt)minNumSamples,AI_TYPE_FLOAT); // if we have to interpolate bool done = false; if(sampleInfo.alpha > sampleTolerance) { Alembic::AbcGeom::ICurvesSchema::Sample sample2; typedObject.getSchema().get(sample2,sampleInfo.ceilIndex); Alembic::Abc::P3fArraySamplePtr abcPos2 = sample2.getPositions(); float alpha = (float)sampleInfo.alpha; float ialpha = 1.0f - alpha; size_t offset = 0; if(abcPos2->size() == abcPos->size()) { for(size_t i=0; i<abcNumPoints->size(); ++i) { // add the first and last point manually (catmull clark) for(size_t j=0; j<abcNumPoints->get()[i]; ++j) { AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x * ialpha + abcPos2->get()[offset].x * alpha); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y * ialpha + abcPos2->get()[offset].y * alpha); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z * ialpha + abcPos2->get()[offset].z * alpha); if(j==0 || j == abcNumPoints->get()[i]-1) { AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x * ialpha + abcPos2->get()[offset].x * alpha); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y * ialpha + abcPos2->get()[offset].y * alpha); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z * ialpha + abcPos2->get()[offset].z * alpha); } ++offset; } } done = true; } else { Alembic::Abc::P3fArraySamplePtr abcVel = sample.getPositions(); if(abcVel) { if(abcVel->size() == abcPos->size()) { for(size_t i=0; i<abcNumPoints->size(); ++i) { // add the first and last point manually (catmull clark) for(size_t j=0; j<abcNumPoints->get()[i]; ++j) { AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x + abcVel->get()[offset].x * alpha); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y + abcVel->get()[offset].y * alpha); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z + abcVel->get()[offset].z * alpha); if(j==0 || j == abcNumPoints->get()[i]-1) { AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x + abcVel->get()[offset].x * alpha); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y + abcVel->get()[offset].y * alpha); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z + abcVel->get()[offset].z * alpha); } ++offset; } } done = true; } } } } if(!done) { size_t offset = 0; for(size_t i=0; i<abcNumPoints->size(); ++i) { // add the first and last point manually (catmull clark) for(size_t j=0; j<abcNumPoints->get()[i]; ++j) { AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z); if(j==0 || j == abcNumPoints->get()[i]-1) { AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y); AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z); } ++offset; } } } } AiNodeSetArray(shapeNode, "points", pos); return shapeNode; }
static AtNode *MyGetNode(void *user_ptr, int i){ cout << "BEGIN GET NODE" << endl; const McdMiddleData* params = static_cast<McdMiddleData*>(user_ptr); const char* g_assetsPath = params->m_assetsPath; int g_agentID = params->m_agentID; int g_ppID = params->m_ppID; int g_geoID = params->m_geoID; int g_poly0_subd1 = params->m_poly0_subd1; int g_motionBlur = params->m_motionBlur; float g_motionShutter = params->m_motionShutter; const char* g_poseData = params->m_poseData; string agentFolder; string agentPath2,geoPath2,weightPath2; string currentLine; //long counter1; //long counter2; #ifdef WIN32 EnterCriticalSection(&g_cs1); #else pthread_mutex_lock( &cs_mutex ); #endif if (!have_Data) initAssets(params); #ifdef WIN32 LeaveCriticalSection(&g_cs1); #else pthread_mutex_unlock( &cs_mutex ); #endif #ifdef MiarmyDebug ofstream logFile("e:/logFile.txt"); #endif // agent file: // ///////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////// bool motionBlurDef = false; float motionShutter = 0.0f; if (g_motionBlur == 1) { motionBlurDef = true; motionShutter = g_motionShutter; } vector<float> poseDataRaw; vector<float> poseDataRawNext; McdUtils utils; utils.getPoseRawData(poseDataRaw,poseDataRawNext, motionBlurDef, g_poseData); #ifdef MiarmyDebug logFile<<"pose data raw"<<endl; for (uint i = 0; i < poseDataRaw.size(); i++){ logFile<<poseDataRaw[i]<<" "; } #endif char tempBuf[10]; string ppIdStr, agentTypeIdStr, geoTypeIdStr; string assetsFolder(g_assetsPath); sprintf(tempBuf, "%d", g_ppID); ppIdStr = tempBuf; sprintf(tempBuf, "%d", g_agentID); agentTypeIdStr = tempBuf; sprintf(tempBuf, "%d", g_geoID); geoTypeIdStr = tempBuf; string geomStr = "geom"; geomStr = geomStr + ppIdStr; agentFolder = agentFolderPre + agentTypeIdStr; // d:/pp / McdAgentType0 / McdAgentMain.txt agentPath2= assetsFolder + slash + agentFolder + slash + agentFile2; // d:/pp / McdAgentType0 / McdGeoFiles / McdGeo 0 geoPath2= assetsFolder + slash + agentFolder + slash + geoFolder + slash + geoFilePre + geoTypeIdStr; // d:/pp / McdAgentType0 / McdGeoFiles / McdWeight 0 weightPath2= assetsFolder + slash + agentFolder + slash + geoFolder + slash + weightFilePre + geoTypeIdStr; // we already have agentPath2, geoPath2, and weightPath2, let's extract data: // get bone number and org pose vector<McdMatrix> orgPoseMatrixList; vector<McdMatrix> currentPoseMatrixList; vector<McdMatrix> nextPoseMatrixList; int nbBone = (int)(agentFiles_Data[g_agentID][0] + .1f); utils.getPoseMatrices( orgPoseMatrixList, currentPoseMatrixList, nextPoseMatrixList, agentFiles_Data, poseDataRaw, poseDataRawNext, nbBone, g_agentID, motionBlurDef); // now get the weights McdPointWeight weightList; int nbPoints = utils.getWeightsFromFile( weightList, weightPath2, weightFiles_Data, g_agentID, g_geoID ); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // session 3: get the data from geo file ////////////////////////////////////////////////////////////////////// //bool startCollect = false; McdGeo geo; vector<float> currentPoints, nextPoints; // modified from points; vector<float> currentNormals, nextNormals; // modified from normals; utils.getGeoFromFile( geo, geoFiles_Data, currentNormals, nextNormals, g_geoID, g_agentID, motionBlurDef); // statistic final information: int nbNormalFromRib = geo.nidxs.size(); if (geo.points.size() / 3 != nbPoints) return 0; #ifdef MiarmyDebug logFile << "-----------> points number from pp exportor: >>>>" <<nbPoints<<endl; logFile << "-----------> normals number from rib: >>>>" <<nbNormalFromRib<<endl; #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // session 4: modify the data in vector /////////////////////////////////////////////////////////////////////// // modify points by skinning info #ifdef MiarmyDebug logFile << "*************start to deal with points********************************************"<<endl; #endif McdPoint currentPoint; McdPoint nextPoint; int nbWeights; int boneID; float weight; for (int i = 0; i < nbPoints; i++) { currentPoint.x = geo.points[i*3]; currentPoint.y = geo.points[i*3 + 1]; currentPoint.z = geo.points[i*3 + 2]; if (motionBlurDef) { nextPoint = currentPoint; } nbWeights = weightList.nbWeights[i]; #ifdef MiarmyDebug logFile<<"-------------------------------"<<endl; logFile << "point pre info: "<<currentPoint.x<<" "<<currentPoint.y<<" "<<currentPoint.z<<" "<<endl; #endif McdMatrix deformMat; deformMat = deformMat * 0.0f; // zero out McdMatrix deformMatNext; deformMatNext = deformMatNext * 0.0f; // zero out for (int j = 0; j < nbWeights; j++) { boneID = weightList.pointIdList[i][j]; weight = weightList.pointWeights[i][j]; #ifdef MiarmyDebug logFile <<"pointid: "<<i<<" boneId: "<<boneID<<" weight: "<<weight<<endl; #endif deformMat = deformMat + (orgPoseMatrixList[boneID] * currentPoseMatrixList[boneID]) * weight; if (motionBlurDef) { deformMatNext = deformMatNext + (orgPoseMatrixList[boneID] * nextPoseMatrixList[boneID]) * weight; } } currentPoint = currentPoint * deformMat; if (motionBlurDef) { nextPoint = nextPoint * deformMatNext; } // put result to points: currentPoints.push_back(currentPoint.x); currentPoints.push_back(currentPoint.y); currentPoints.push_back(currentPoint.z); if (motionBlurDef) { nextPoints.push_back(nextPoint.x); nextPoints.push_back(nextPoint.y); nextPoints.push_back(nextPoint.z); } #ifdef MiarmyDebug logFile << "result point info: "<<currentPoints[i*3]<<" "<<currentPoints[i*3+1]<<" "<<currentPoints[i*3+2]<<" "<<endl; if (motionBlurDef) logFile << "next point info: "<<nextPoints[i*3]<<" "<<nextPoints[i*3+1]<<" "<<nextPoints[i*3+2]<<" "<<endl; #endif } // modify normal by skinning info McdVector currentNormal, nextNormal; int normalPointID, normalID; for (int i = 0; i < nbNormalFromRib; i++){ normalID = geo.nidxs[i]; currentNormal.x = geo.normals[normalID*3]; currentNormal.y = geo.normals[normalID*3+1]; currentNormal.z = geo.normals[normalID*3+2]; if (motionBlurDef){ nextNormal.x = geo.normals[normalID*3]; nextNormal.y = geo.normals[normalID*3+1]; nextNormal.z = geo.normals[normalID*3+2]; } normalPointID = geo.vidxs[i]; nbWeights = weightList.nbWeights[normalPointID]; #ifdef MiarmyDebug logFile << "point normal info: "<<currentNormal.x<<" "<<currentNormal.y<<" "<<currentNormal.z<<" "<<endl; if (motionBlurDef){ logFile << "next point normal info: "<<nextNormal.x<<" "<<nextNormal.y<<" "<<nextNormal.z<<" "<<endl; } #endif McdMatrix deformMat; deformMat = deformMat * 0.0f; // zero out McdMatrix deformMatNext; deformMatNext = deformMatNext * 0.0f; // zero out for (int j = 0; j < nbWeights; j++){ boneID = weightList.pointIdList[normalPointID][j]; weight = weightList.pointWeights[normalPointID][j]; deformMat = deformMat + (orgPoseMatrixList[boneID] * currentPoseMatrixList[boneID]) * weight; if (motionBlurDef){ deformMat = deformMat + (orgPoseMatrixList[boneID] * nextPoseMatrixList[boneID]) * weight; } } currentNormal = currentNormal * deformMat; currentNormal.normalize(); if (motionBlurDef){ nextNormal = nextNormal * deformMatNext; nextNormal.normalize(); } // put result to normals: currentNormals[normalID*3] = currentNormal.x; currentNormals[normalID*3+1] = currentNormal.y; currentNormals[normalID*3+2] = currentNormal.z; if (motionBlurDef){ nextNormals[normalID*3] = nextNormal.x; nextNormals[normalID*3+1] = nextNormal.y; nextNormals[normalID*3+2] = nextNormal.z; } #ifdef MiarmyDebug logFile << "result normal info: "<<currentNormals[normalID*3]<<" "<<currentNormals[normalID*3+1]<<" "<<currentNormals[normalID*3+2]<<" "<<endl; if (motionBlurDef) logFile << "result next normal info: "<<nextNormals[normalID*3]<<" "<<nextNormals[normalID*3+1]<<" "<<nextNormals[normalID*3+2]<<" "<<endl; #endif } #ifdef MiarmyDebug logFile <<endl<< "----------------------- END -----------------------: "; logFile.close(); #endif AtArray *nsidesArray; AtArray *vidxsArray; AtArray *nidxsArray; AtArray *uvidxsArray; AtArray *vlistArray; AtArray *nlistArray; AtArray *uvlistArray; // proc geo: if (!motionBlurDef){ nsidesArray = AiArrayAllocate(geo.nsides.size(), 1, AI_TYPE_UINT); vidxsArray = AiArrayAllocate(geo.vidxs.size(), 1, AI_TYPE_UINT); nidxsArray = AiArrayAllocate(geo.nidxs.size(), 1, AI_TYPE_UINT); uvidxsArray = AiArrayAllocate(geo.uvidxs.size(), 1, AI_TYPE_UINT); vlistArray = AiArrayAllocate(geo.points.size() / 3, 1, AI_TYPE_POINT); nlistArray = AiArrayAllocate(geo.normals.size() / 3, 1, AI_TYPE_VECTOR); uvlistArray = AiArrayAllocate(geo.uvlist.size() / 2, 1, AI_TYPE_POINT2); uint i; AtPoint tempPoint; AtVector tempNormal; AtPoint2 tempPoint2; uint nbPnts = currentPoints.size() / 3; uint nbNormals = currentNormals.size() / 3; uint nbUVs = geo.uvlist.size() / 2; for (i = 0; i < geo.nsides.size(); i++) AiArraySetUInt(nsidesArray, i, geo.nsides[i]); for (i = 0; i < geo.vidxs.size(); i++) AiArraySetUInt(vidxsArray, i, geo.vidxs[i]); for (i = 0; i < geo.nidxs.size(); i++) AiArraySetUInt(nidxsArray, i, geo.nidxs[i]); for (i = 0; i < geo.uvidxs.size(); i++) AiArraySetUInt(uvidxsArray, i, geo.uvidxs[i]); for (i = 0; i < nbPnts; i++){ tempPoint.x = currentPoints[i*3]; tempPoint.y = currentPoints[i*3+1]; tempPoint.z = currentPoints[i*3+2]; AiArraySetPnt(vlistArray, i, tempPoint); } for (i = 0; i < nbNormals; i++){ tempNormal.x = currentNormals[i*3]; tempNormal.y = currentNormals[i*3+1]; tempNormal.z = currentNormals[i*3+2]; AiArraySetPnt(nlistArray, i, tempNormal); } for (i = 0; i < nbUVs; i++){ tempPoint2.x = geo.uvlist[i*2]; tempPoint2.y = geo.uvlist[i*2+1]; AiArraySetPnt2(uvlistArray, i, tempPoint2); } } else { nsidesArray = AiArrayAllocate(geo.nsides.size(), 1, AI_TYPE_UINT); vidxsArray = AiArrayAllocate(geo.vidxs.size(), 1, AI_TYPE_UINT); nidxsArray = AiArrayAllocate(geo.nidxs.size(), 1, AI_TYPE_UINT); uvidxsArray = AiArrayAllocate(geo.uvidxs.size(), 1, AI_TYPE_UINT); vlistArray = AiArrayAllocate(geo.points.size() / 3, 2, AI_TYPE_POINT); nlistArray = AiArrayAllocate(geo.normals.size() / 3, 2, AI_TYPE_VECTOR); uvlistArray = AiArrayAllocate(geo.uvlist.size() / 2, 1, AI_TYPE_POINT2); uint i; AtPoint tempPoint; AtVector tempNormal; AtPoint2 tempPoint2; uint nbPnts = currentPoints.size() / 3; uint nbNormals = currentNormals.size() / 3; uint nbUVs = geo.uvlist.size() / 2; for (i = 0; i < geo.nsides.size(); i++) AiArraySetUInt(nsidesArray, i, geo.nsides[i]); for (i = 0; i < geo.vidxs.size(); i++) AiArraySetUInt(vidxsArray, i, geo.vidxs[i]); for (i = 0; i < geo.nidxs.size(); i++) AiArraySetUInt(nidxsArray, i, geo.nidxs[i]); for (i = 0; i < geo.uvidxs.size(); i++) AiArraySetUInt(uvidxsArray, i, geo.uvidxs[i]); for (i = 0; i < nbPnts; i++){ tempPoint.x = currentPoints[i*3]; tempPoint.y = currentPoints[i*3+1]; tempPoint.z = currentPoints[i*3+2]; AiArraySetPnt(vlistArray, i, tempPoint); } for (i = 0; i < nbNormals; i++){ tempNormal.x = currentNormals[i*3]; tempNormal.y = currentNormals[i*3+1]; tempNormal.z = currentNormals[i*3+2]; AiArraySetPnt(nlistArray, i, tempNormal); } for (i = 0; i < nbPnts; i++){ tempPoint.x = nextPoints[i*3]; tempPoint.y = nextPoints[i*3+1]; tempPoint.z = nextPoints[i*3+2]; AiArraySetPnt(vlistArray, i+nbPnts, tempPoint); } for (i = 0; i < nbNormals; i++){ tempNormal.x = nextNormals[i*3]; tempNormal.y = nextNormals[i*3+1]; tempNormal.z = nextNormals[i*3+2]; AiArraySetPnt(nlistArray, i+nbNormals, tempNormal); } for (i = 0; i < nbUVs; i++){ tempPoint2.x = geo.uvlist[i*2]; tempPoint2.y = geo.uvlist[i*2+1]; AiArraySetPnt2(uvlistArray, i, tempPoint2); } } AtNode *meshNode = AiNode("polymesh"); AiNodeSetStr(meshNode, "name", geomStr.c_str()); AiNodeSetArray(meshNode, "nsides", nsidesArray); AiNodeSetArray(meshNode, "vidxs", vidxsArray); if (g_poly0_subd1 != 1) AiNodeSetArray(meshNode, "nidxs", nidxsArray); AiNodeSetArray(meshNode, "uvidxs", uvidxsArray); AiNodeSetArray(meshNode, "vlist", vlistArray); if (g_poly0_subd1 != 1) AiNodeSetArray(meshNode, "nlist", nlistArray); AiNodeSetArray(meshNode, "uvlist", uvlistArray); AiNodeSetBool(meshNode, "smoothing", true); if (g_poly0_subd1 == 1) AiNodeSetStr(meshNode, "subdiv_type", "catclark"); lockup = false; cout << "END GET NODE" << endl; return meshNode; }