Exemple #1
0
//================================================================
//================================================================
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;
	}