Material Based Effects - Detection - Polysoup 1.03 rescource

From TDN

disclaimer: based on the Torque Shader Engine/PolySoupAddon implementation at the moment, not 1.7.1. That's still pending. Will also note that multimaterials, wich is half the point to this, end up fairly non-performant with heavily dense, highish polycount concave meshes when acid-tested.

tscollision.cpp:

replace the whole of

bool TSShapeInstance::castRayOpcode( S32 dl, const Point3F & startPos, const Point3F & endPos, RayInfo *info)
{
}

with:

bool TSShapeInstance::castRayOpcode( S32 dl, const Point3F & startPos, const Point3F & endPos, RayInfo *info)
{
   // if dl==-1, nothing to do
   if (dl==-1)
      return false;

   AssertFatal(dl>=0 && dl<mShape->details.size(),"TSShapeInstance::castRayOpcode");

   info->t = 100.f;

   // get subshape and object detail
   const TSDetail * detail = &mShape->details[dl];
   S32 ss = detail->subShapeNum;
   S32 od = detail->objectDetailNum;

   // set up static data
   setStatics(dl);

   // nothing emitted yet...
   bool emitted = false;

   MeshObjectInstance * mesh;

   MatrixF* saveMat = NULL;
   S32 start = mShape->subShapeFirstObject[ss];
   S32 end   = mShape->subShapeNumObjects[ss] + start;
   if (start<end)
   {
      MatrixF mat;
      MatrixF * previousMat = mMeshObjects[start].getTransform();
      mat = *previousMat;
      mat.inverse();
      Point3F localStart, localEnd;
      mat.mulP(startPos, &localStart);
      mat.mulP(endPos, &localEnd);

      // run through objects and collide
      for (S32 i=start; i<end; i++)
      {
         mesh = &mMeshObjects[i];

         if (od >= mesh->object->numMeshes)
            continue;

         if (mesh->getTransform() != previousMat)
         {
            // different node from before, set up for this node
            previousMat = mesh->getTransform();

            if (previousMat != NULL)
            {
               mat = *previousMat;
               mat.inverse();
               mat.mulP(startPos, &localStart);
               mat.mulP(endPos, &localEnd);
            }
         }

         // collide...
         if ( mesh->castRayOpcode(od,localStart, localEnd, info) )
         {
            saveMat = previousMat;
            emitted = true;
         }
      }
   }

   if ( emitted )
   {
		saveMat->mulV(info->normal);
		info->point  = endPos - startPos;
		info->point *= info->t;
		info->point += startPos;
		
		TriRayInfo triInfo;
		if (mesh->meshList[0]->castRayTri(od,startPos, endPos, &triInfo))
			info->material = triInfo.material;

		if ( mMaterialList )
		{
			MatInstance* matInst = mMaterialList->getMaterialInst( info->material );
			if ( matInst && matInst->getMaterial() ) 
				info->material = matInst->getMaterial()->getId();
		}
   }

   clearStatics();

   return emitted;
}