//================================================================ //================================================================ bool __cdecl RunTask(IAgent* agent, DWORD sessionId, IGenericStream* inStream, IGenericStream* outStream) { EnterCriticalSection(&CS); DWORD dataKey = sessionId; //uncomment to allow each thread from pool to have separate global data //dataKey |= GetCurrentThreadId(); TSessionDataCache::iterator i = sessionDataCache.find(dataKey); if (i==sessionDataCache.end()) { sessionDataCache.insert(std::make_pair(dataKey,TSessionData())); //----------- read global data ------------- IGenericStream* globalDataStream; HRESULT rz = agent->GetData(sessionId, dataDesc, &globalDataStream); if (rz!=S_OK) { LeaveCriticalSection(&CS); return false; } i = sessionDataCache.find(dataKey); assert(i!=sessionDataCache.end()); TSessionData* sd = &i->second; sd->octree = new AtiOctree(globalDataStream); globalDataStream->Read(&sd->highNumTris,sizeof(sd->highNumTris)); sd->highTris = new NmRawTriangle[sd->highNumTris]; globalDataStream->Read(sd->highTris,sd->highNumTris*sizeof(NmRawTriangle)); globalDataStream->Read(&sd->gNumSamples,sizeof(sd->gNumSamples)); sd->gSamples = new NmSample[sd->gNumSamples]; globalDataStream->Read(sd->gSamples,sd->gNumSamples*sizeof(NmSample)); globalDataStream->Read(&sd->hTangentSpace,sizeof(sd->hTangentSpace)); if (sd->hTangentSpace!=NULL) { sd->hTangentSpace = new NmTangentMatrix[sd->highNumTris]; globalDataStream->Read(sd->hTangentSpace,sd->highNumTris*sizeof(NmTangentMatrix)); } globalDataStream->Read(&sd->bumpWidth,sizeof(sd->bumpWidth)); globalDataStream->Read(&sd->bumpHeight,sizeof(sd->bumpHeight)); globalDataStream->Read(&sd->bumpMap,sizeof(sd->bumpMap)); if (sd->bumpMap!=NULL) { sd->bumpMap = new float[sd->bumpWidth*sd->bumpHeight*3]; globalDataStream->Read(sd->bumpMap,sd->bumpWidth*sd->bumpHeight*3*sizeof(float)); } globalDataStream->Read(&sd->numRays,sizeof(sd->numRays)); if (sd->numRays!=0) { sd->rays = new NmRawPointD[sd->numRays]; globalDataStream->Read(sd->rays,sd->numRays*sizeof(NmRawPointD)); sd->rayWeights = new double[sd->numRays]; globalDataStream->Read(sd->rayWeights,sd->numRays*sizeof(double)); } { globalDataStream->AddRef(); DWORD d = globalDataStream->Release(); } globalDataStream->Release(); agent->FreeCachedData(sessionId, dataDesc); } TSessionData* sd = &i->second; LeaveCriticalSection(&CS); //------------------------------------------ float* img; float* img2; int minX; int pad; int maxX; int gWidth; int y; double x1,x2,x3,y1,y2,y3; double b0; bool gInTangentSpace; NmTangentMatrix tangentSpace_l; NmRawTriangle lTri; bool gOcclusion; bool gBentNormal; int numComponents; int gOcclIdx; bool gDisplacements; int gDispIdx; bool gEdgeCopy; int gNormalRules; double gMaxAngle; double gDistance; double gEpsilon; int gMaxCells = 0; AtiOctreeCell** gCell = NULL; DWORD intag; bool bFirstPass=true; int l; inStream->Read(&intag, sizeof(DWORD)); do { inStream->Read(&img, sizeof(float*)); inStream->Read(&img2, sizeof(float*)); if (bFirstPass==true) { outStream->Write(&img, sizeof(float*)); outStream->Write(&img2, sizeof(float*)); } inStream->Read(&minX, sizeof(minX)); inStream->Read(&pad, sizeof(pad)); inStream->Read(&maxX, sizeof(maxX)); inStream->Read(&gWidth, sizeof(gWidth)); inStream->Read(&y, sizeof(y)); inStream->Read(&x1, sizeof(x1)); inStream->Read(&x2, sizeof(x2)); inStream->Read(&x3, sizeof(x3)); inStream->Read(&y1, sizeof(y1)); inStream->Read(&y2, sizeof(y2)); inStream->Read(&y3, sizeof(y3)); inStream->Read(&b0, sizeof(b0)); inStream->Read(&gInTangentSpace, sizeof(gInTangentSpace)); inStream->Read(&tangentSpace_l,sizeof(NmTangentMatrix)); inStream->Read(&lTri, sizeof(NmRawTriangle)); /* if (bFirstPass) { octree = new AtiOctree(inStream); inStream->Read(&highNumTris,sizeof(highNumTris)); highTris = new NmRawTriangle[highNumTris]; inStream->Read(highTris,highNumTris*sizeof(NmRawTriangle)); inStream->Read(&gNumSamples,sizeof(gNumSamples)); gSamples = new NmSample[gNumSamples]; inStream->Read(gSamples,gNumSamples*sizeof(NmSample)); inStream->Read(&hTangentSpace,sizeof(hTangentSpace)); if (hTangentSpace!=NULL) { hTangentSpace = new NmTangentMatrix[highNumTris]; inStream->Read(hTangentSpace,highNumTris*sizeof(NmTangentMatrix)); } inStream->Read(&bumpWidth,sizeof(bumpWidth)); inStream->Read(&bumpHeight,sizeof(bumpHeight)); inStream->Read(&bumpMap,sizeof(bumpMap)); if (bumpMap!=NULL) { bumpMap = new float[bumpWidth*bumpHeight*3]; inStream->Read(bumpMap,bumpWidth*bumpHeight*3*sizeof(float)); } inStream->Read(&numRays,sizeof(numRays)); if (numRays!=0) { rays = new NmRawPointD[numRays]; inStream->Read(rays,numRays*sizeof(NmRawPointD)); rayWeights = new double[numRays]; inStream->Read(rayWeights,numRays*sizeof(double)); } } */ inStream->Read(&gOcclusion,sizeof(gOcclusion)); inStream->Read(&gBentNormal,sizeof(gBentNormal)); inStream->Read(&numComponents,sizeof(numComponents)); inStream->Read(&gOcclIdx,sizeof(gOcclIdx)); inStream->Read(&gDisplacements ,sizeof(gDisplacements)); inStream->Read(&gDispIdx ,sizeof(gDispIdx)); inStream->Read(&gEdgeCopy, sizeof(gEdgeCopy)); inStream->Read(&gNormalRules, sizeof(gNormalRules)); inStream->Read(&gMaxAngle, sizeof(gMaxAngle)); inStream->Read(&gDistance, sizeof(gDistance)); inStream->Read(&gEpsilon, sizeof(gEpsilon)); inStream->Read(&l, sizeof(l)); if (bFirstPass==true) { outStream->Write(&l, sizeof(l)); } bFirstPass=false; //--------------------------------------- // Loop over the Xs filling in each texel of the normal map for (int x = (minX - pad); x <= (maxX + pad); x++) { if (agent->TestConnection(sessionId)!=S_OK) { delete[] gCell; return false; } // Make sure this is a valid texture coordinate if ((x < 0) || (x >= gWidth)) { continue; } // Find Barycentric coordinates. double b1 = ((x2-x) * (y3-y) - (x3-x) * (y2-y)) / b0; double b2 = ((x3-x) * (y1-y) - (x1-x) * (y3-y)) / b0; double b3 = ((x1-x) * (y2-y) - (x2-x) * (y1-y)) / b0; // Interpolate tangent space. double ts[9]; if (gInTangentSpace == true) { for (int t = 0; t < 9; t++) { // ts[t] = (tangentSpace[l].m[0][t] * b1) + // (tangentSpace[l].m[1][t] * b2) + // (tangentSpace[l].m[2][t] * b3); ts[t] = (tangentSpace_l.m[0][t] * b1) + (tangentSpace_l.m[1][t] * b2) + (tangentSpace_l.m[2][t] * b3); } } // For each sample accumulate the normal double sNorm[3] = {0.0, 0.0, 0.0}; double sOcclusion = 0.0; double sDisplacement = 0.0; int sFound = 0; double aNorm[3] = {0.0, 0.0, 0.0}; for (int s = 0; s < sd->gNumSamples; s++) { // Compute new x & y double sX = (double)(x) + sd->gSamples[s].x; double sY = (double)(y) + sd->gSamples[s].y; // Find Barycentric coordinates. double b1 = ((x2-sX) * (y3-sY) - (x3-sX) * (y2-sY)) / b0; double b2 = ((x3-sX) * (y1-sY) - (x1-sX) * (y3-sY)) / b0; double b3 = ((x1-sX) * (y2-sY) - (x2-sX) * (y1-sY)) / b0; // Use Barycentric coordinates to deterimine if we are // are outside of the triangle. if ((b1 > 1.0) || (b1 < 0.0) || (b2 > 1.0) || (b2 < 0.0) || (b3 > 1.0) || (b3 < 0.0)) { continue; } // Compute position and normal NmRawPointD pos; NmRawPointD norm; BaryInterpolate (&lTri, b1, b2, b3, pos.v, norm.v); // First see if we even have an intersection. double newNorm[3]; double newPos[3]; double newDisplacement = 0.0f; if (FindBestIntersection (pos, norm, sd->octree, sd->highTris, sd->hTangentSpace, sd->bumpMap, sd->bumpHeight, sd->bumpWidth, newNorm, newPos, &newDisplacement, gNormalRules, gMaxAngle, gDistance, gEpsilon, gMaxCells, gCell)) { // Normalize the new normal sDisplacement += newDisplacement; Normalize (newNorm); // Do bent normal/occlusion if needed. if (gOcclusion || gBentNormal) { // First do the ray casting. NmRawPointD bentNormal; double occlusion; ComputeOcclusion ((NmRawPointD*)(newPos), (NmRawPointD*)(newNorm), sd->highNumTris, sd->highTris, sd->octree, sd->numRays, sd->rays, sd->rayWeights, &bentNormal, &occlusion, gMaxCells, gCell); // Add it to our sample sum. if (gBentNormal) { sNorm[0] += bentNormal.x; sNorm[1] += bentNormal.y; sNorm[2] += bentNormal.z; } else { sNorm[0] += newNorm[0]; sNorm[1] += newNorm[1]; sNorm[2] += newNorm[2]; } sOcclusion += occlusion; sFound++; } else { // Plain old normal map sNorm[0] += newNorm[0]; sNorm[1] += newNorm[1]; sNorm[2] += newNorm[2]; sFound++; } } // end if we found a normal } // end for samples (s); // If we found a normal put it in the image. if (sFound > 0) { // Convert to tangent space if needed if (gInTangentSpace == true) { ConvertToTangentSpace (ts, sNorm, sNorm); } // Add it to the image. int idx = y*gWidth*numComponents + x*numComponents; //======== write result ============== BYTE ostag; DWORD osindex; float osval; ostag = 3; osindex = idx; osval = (float)sNorm[0]; outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); ostag = 3; osindex = idx+1; osval = (float)sNorm[1]; outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); ostag = 3; osindex = idx+2; osval = (float)sNorm[2]; outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); // img[idx + 0] += (float)sNorm[0]; // img[idx + 1] += (float)sNorm[1]; // img[idx + 2] += (float)sNorm[2]; if (gOcclusion) { ostag = 1; osindex = idx + gOcclIdx; osval = (float)(sOcclusion/sFound); outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); // img[idx + gOcclIdx] = (float)(sOcclusion/sFound); } if (gDisplacements) { ostag = 1; osindex = idx + gDispIdx; osval = (float)(sDisplacement/sFound); outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); // img[idx + gDispIdx] = (float)(sDisplacement/sFound); } //==================================== } // end if we found a normal else if (gEdgeCopy) { // Since we didn't find a normal, "snap" the center // sample's barycentric coordinates to the edge of the // triangle and find the normal there. Store this in // a temporary buffer that we'll use to dilate the image // in a way that doesn't produce texture seams. double sX = (double)x; double sY = (double)y; double b1 = ((x2-sX) * (y3-sY) - (x3-sX) * (y2-sY)) / b0; double b2 = ((x3-sX) * (y1-sY) - (x1-sX) * (y3-sY)) / b0; double b3 = ((x1-sX) * (y2-sY) - (x2-sX) * (y1-sY)) / b0; // "Snap" barycentric coordinates. if (b1 > 1.0) { double diff = b1 - 1.0; b1 = 1.0; b2 += (diff/2.0); b3 += (diff/2.0); } if (b1 < 0.0) { double diff = b1; b1 = 0.0; b2 += (diff/2.0); b3 += (diff/2.0); } if (b2 > 1.0) { double diff = b2 - 1.0; b1 = 1.0; b1 += (diff/2.0); b3 += (diff/2.0); } if (b2 < 0.0) { double diff = b2; b2 = 0.0; b1 += (diff/2.0); b3 += (diff/2.0); } if (b3 > 1.0) { double diff = b3 - 1.0; b3 = 1.0; b2 += (diff/2.0); b1 += (diff/2.0); } if (b3 < 0.0) { double diff = b3; b3 = 0.0; b2 += (diff/2.0); b1 += (diff/2.0); } // Compute position and normal NmRawPointD pos; NmRawPointD norm; BaryInterpolate (&lTri, b1, b2, b3, pos.v, norm.v); // First see if we even have an intersection. double newNorm[3]; double newPos[3]; double newOcclusion = 0.0; double newDisplacement = 0.0; if (FindBestIntersection (pos, norm, sd->octree, sd->highTris, sd->hTangentSpace, sd->bumpMap, sd->bumpHeight, sd->bumpWidth, newNorm, newPos, &newDisplacement, gNormalRules, gMaxAngle, gDistance, gEpsilon, gMaxCells, gCell)) { // Normalize the new normal Normalize (newNorm); // Do bent normal/occlusion if needed. if (gOcclusion || gBentNormal) { // First do the ray casting. NmRawPointD bentNormal; ComputeOcclusion ((NmRawPointD*)(newPos), (NmRawPointD*)(newNorm), sd->highNumTris, sd->highTris, sd->octree, sd->numRays, sd->rays, sd->rayWeights, &bentNormal, &newOcclusion, gMaxCells, gCell); // Replace normal with bent normal if needed if (gBentNormal) { newNorm[0] += bentNormal.x; newNorm[1] += bentNormal.y; newNorm[2] += bentNormal.z; } } // do ambient occlusion if needed // Convert to tangent space if needed if (gInTangentSpace == true) { ConvertToTangentSpace (ts, newNorm, newNorm); } // Add it to the image. int idx = y*gWidth*numComponents + x*numComponents; BYTE ostag; DWORD osindex; float osval; ostag = 4; osindex = idx; osval = (float)newNorm[0]; outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); ostag = 4; osindex = idx+1; osval = (float)newNorm[1]; outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); ostag = 4; osindex = idx+2; osval = (float)newNorm[2]; outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); // img2[idx + 0] += (float)newNorm[0]; // img2[idx + 1] += (float)newNorm[1]; // img2[idx + 2] += (float)newNorm[2]; if (gOcclusion) { ostag = 2; osindex = idx + gOcclIdx; osval = (float)(newOcclusion); outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); // img2[idx + gOcclIdx] = (float)(newOcclusion); } if (gDisplacements) { ostag = 2; osindex = idx + gDispIdx; osval = (float)(newDisplacement); outStream->Write(&ostag,sizeof(ostag)); outStream->Write(&osindex,sizeof(osindex)); outStream->Write(&osval,sizeof(osval)); // img2[idx + gDispIdx] = (float)(newDisplacement); } } // end if we found a normal // else don't add anything to either image. } // end else find a "snapped" normal // Spin! // ShowSpinner (prog); } // end for x inStream->Read(&intag, sizeof(DWORD)); } while (intag==1); delete[] gCell; gMaxCells = 0; gCell=NULL; BYTE ostag; ostag = 0; outStream->Write(&ostag,sizeof(ostag)); DWORD tricount; inStream->Read(&tricount, sizeof(tricount)); outStream->Write(&tricount, sizeof(tricount)); return true; }
ERMsg BeginSession(IAgent* agent, __int32 sessionId, DWORD hxGridSessionId, IGenericStream* globalDataStream = NULL) { ERMsg msg; //EnterCriticalSection(&sessionDataCache.m_CS); CS.Enter(); CSessionDataCache::iterator i = sessionDataCache.find(sessionId); if (i == sessionDataCache.end()) { //----------- read global data ------------- //CStdString tmp; //tmp.Format("Before init\nsessionId = %d\nhxGridSessionId = %d",sessionId, hxGridSessionId); //MessageBox(NULL, (LPCTSTR)tmp, "BeginSession", MB_OK); if (globalDataStream == NULL) { ASSERT(agent); HRESULT rz = agent->GetData(hxGridSessionId, SIMULATED_ANNEALING_DATA_DESCRIPTOR, &globalDataStream); if (rz != S_OK) { CS.Leave(); msg.ajoute(string("ERROR: agent->GetData from ") + SIMULATED_ANNEALING_DATA_DESCRIPTOR + " failed"); return msg; } } //insert a new session sessionDataCache.insert(std::make_pair(sessionId, TSessionData())); i = sessionDataCache.find(sessionId); ASSERT(i != sessionDataCache.end()); TSessionData& sd = i->second; istringstream iStream(string((char*)globalDataStream->GetBasePointer(), globalDataStream->GetLength())); msg = sd.m_modelVector.ReadStream(iStream); if (!msg) return msg; //free global stream. No longer need for this session if (agent) { //release global stream globalDataStream->Release(); agent->FreeCachedData(hxGridSessionId, SIMULATED_ANNEALING_DATA_DESCRIPTOR); //set agent on model for (CSimulatedAnnealingVector::iterator it = sd.m_modelVector.begin(); it != sd.m_modelVector.end(); it++) { (*it)->m_pAgent = agent; (*it)->m_hxGridSessionID = hxGridSessionId; } } } CS.Leave(); return msg; }