void TSShapeInstance::MeshObjectInstance::render(  S32 objectDetail, 
                                                   TSMaterialList *materials, 
                                                   const TSRenderState &rdata, 
                                                   F32 alpha )
{
   PROFILE_SCOPE( TSShapeInstance_MeshObjectInstance_render );

   if ( forceHidden || ( ( visible * alpha ) <= 0.01f ) )
      return;

   TSMesh *mesh = getMesh(objectDetail);
   if ( !mesh )
      return;

   const MatrixF &transform = getTransform();

   if ( rdata.getCuller() )
   {
      Box3F box( mesh->getBounds() );
      transform.mul( box );
      if ( rdata.getCuller()->isCulled( box ) )
         return;
   }

   GFX->pushWorldMatrix();
   GFX->multWorld( transform );

   mesh->setFade( visible * alpha );

   // Pass a hint to the mesh that time has advanced and that the
   // skin is dirty and needs to be updated.  This should result
   // in the skin only updating once per frame in most cases.
   const U32 currTime = Sim::getCurrentTime();
   bool isSkinDirty = currTime != mLastTime;

   mesh->render(  materials, 
                  rdata, 
                  isSkinDirty,
                  *mTransforms, 
                  mVertexBuffer,
                  mPrimitiveBuffer );

   // Update the last render time.
   mLastTime = currTime;

   GFX->popWorldMatrix();
}
TSMesh* AppMesh::constructTSMesh()
{
   TSMesh* tsmesh;
   if (isSkin())
   {
      TSSkinMesh* tsskin = new TSSkinMesh();
      tsmesh = tsskin;

      // Copy skin elements
      tsskin->weight = weight;
      tsskin->boneIndex = boneIndex;
      tsskin->vertexIndex = vertexIndex;
      tsskin->batchData.nodeIndex = nodeIndex;
      tsskin->batchData.initialTransforms = initialTransforms;
      tsskin->batchData.initialVerts = initialVerts;
      tsskin->batchData.initialNorms = initialNorms;
   }
   else
   {
      tsmesh = new TSMesh();
   }

   // Copy mesh elements
   tsmesh->verts = points;
   tsmesh->norms = normals;
   tsmesh->tverts = uvs;
   tsmesh->primitives = primitives;
   tsmesh->indices = indices;
   tsmesh->colors = colors;
   tsmesh->tverts2 = uv2s;

   // Finish initializing the shape
   tsmesh->setFlags(flags);
   tsmesh->computeBounds();
   tsmesh->numFrames = numFrames;
   tsmesh->numMatFrames = numMatFrames;
   tsmesh->vertsPerFrame = vertsPerFrame;
   tsmesh->createTangents(tsmesh->verts, tsmesh->norms);
   tsmesh->encodedNorms.set(NULL,0);

   return tsmesh;
}
PhysicsCollision* CollisionComponent::buildColShapes()
{
   PROFILE_SCOPE(CollisionComponent_buildColShapes);

   PhysicsCollision *colShape = NULL;
   U32 surfaceKey = 0;

   TSShape* shape = mOwnerRenderInterface->getShape();

   if (mCollisionType == VisibleMesh)
   {
      // Here we build triangle collision meshes from the
      // visible detail levels.

      // A negative subshape on the detail means we don't have geometry.
      const TSShape::Detail &detail = shape->details[0];
      if (detail.subShapeNum < 0)
         return NULL;

      // We don't try to optimize the triangles we're given
      // and assume the art was created properly for collision.
      ConcretePolyList polyList;
      polyList.setTransform(&MatrixF::Identity, mOwner->getScale());

      // Create the collision meshes.
      S32 start = shape->subShapeFirstObject[detail.subShapeNum];
      S32 end = start + shape->subShapeNumObjects[detail.subShapeNum];
      for (S32 o = start; o < end; o++)
      {
         const TSShape::Object &object = shape->objects[o];
         if (detail.objectDetailNum >= object.numMeshes)
            continue;

         // No mesh or no verts.... nothing to do.
         TSMesh *mesh = shape->meshes[object.startMeshIndex + detail.objectDetailNum];
         if (!mesh || mesh->mNumVerts == 0)
            continue;

         // Gather the mesh triangles.
         polyList.clear();
         mesh->buildPolyList(0, &polyList, surfaceKey, NULL);

         // Create the collision shape if we haven't already.
         if (!colShape)
            colShape = PHYSICSMGR->createCollision();

         // Get the object space mesh transform.
         MatrixF localXfm;
         shape->getNodeWorldTransform(object.nodeIndex, &localXfm);

         colShape->addTriangleMesh(polyList.mVertexList.address(),
            polyList.mVertexList.size(),
            polyList.mIndexList.address(),
            polyList.mIndexList.size() / 3,
            localXfm);
      }

      // Return what we built... if anything.
      return colShape;
   }
   else if (mCollisionType == CollisionMesh)
   {

      // Scan out the collision hulls...
      //
      // TODO: We need to support LOS collision for physics.
      //
      for (U32 i = 0; i < shape->details.size(); i++)
      {
         const TSShape::Detail &detail = shape->details[i];
         const String &name = shape->names[detail.nameIndex];

         // Is this a valid collision detail.
         if (!dStrStartsWith(name, colisionMeshPrefix) || detail.subShapeNum < 0)
            continue;

         // Now go thru the meshes for this detail.
         S32 start = shape->subShapeFirstObject[detail.subShapeNum];
         S32 end = start + shape->subShapeNumObjects[detail.subShapeNum];
         if (start >= end)
            continue;

         for (S32 o = start; o < end; o++)
         {
            const TSShape::Object &object = shape->objects[o];
            const String &meshName = shape->names[object.nameIndex];

            if (object.numMeshes <= detail.objectDetailNum)
               continue;

            // No mesh, a flat bounds, or no verts.... nothing to do.
            TSMesh *mesh = shape->meshes[object.startMeshIndex + detail.objectDetailNum];
            if (!mesh || mesh->getBounds().isEmpty() || mesh->mNumVerts == 0)
               continue;

            // We need the default mesh transform.
            MatrixF localXfm;
            shape->getNodeWorldTransform(object.nodeIndex, &localXfm);

            // We have some sort of collision shape... so allocate it.
            if (!colShape)
               colShape = PHYSICSMGR->createCollision();

            // Any other mesh name we assume as a generic convex hull.
            //
            // Collect the verts using the vertex polylist which will 
            // filter out duplicates.  This is importaint as the convex
            // generators can sometimes fail with duplicate verts.
            //
            VertexPolyList polyList;
            MatrixF meshMat(localXfm);

            Point3F t = meshMat.getPosition();
            t.convolve(mOwner->getScale());
            meshMat.setPosition(t);

            polyList.setTransform(&MatrixF::Identity, mOwner->getScale());
            mesh->buildPolyList(0, &polyList, surfaceKey, NULL);
            colShape->addConvex(polyList.getVertexList().address(),
               polyList.getVertexList().size(),
               meshMat);
         } // objects
      } // details
   }

   return colShape;
}
Beispiel #4
0
void SoftBody::prepBatchRender(SceneRenderState* state, S32 mountedImageIndex )
{
	if (!m_physShapeSoft || m_physShapeSoft->getNodesNum()==0 || gFreezeSim || m_stopSimulation)
	{
		Parent::prepBatchRender(state,mountedImageIndex);
		return;
	}

	TSShapeInstance* shapeInst = getShapeInstance();

	S32 dl = 0;
	const TSShape* shape = getShape();
	const TSDetail * detail = &shape->details[dl];
	S32 ss = detail->subShapeNum;
	S32 od = detail->objectDetailNum;

	U32 vertexStride = shape->getVertexSize();

	S32 start = shape->subShapeFirstObject[ss];
	S32 end   = shape->subShapeNumObjects[ss] + start;
	int physVertexIdx = 0;
	
	for (S32 i=start; i<end; i++)
	{
		TSShapeInstance::MeshObjectInstance* meshOI = &shapeInst->mMeshObjects[i];
		
		if (od >= meshOI->object->numMeshes)
			continue;
		TSMesh* mesh = meshOI->getMesh(od);
		if (mesh)
		{
			mesh->setManualDynamic(true);
			TSVertexBufferHandle& vb = meshOI->mVertexBuffer;
			if (vb == NULL)
				mesh->createVBIB(vb);

			
			U8 *vertData = (U8*)vb.lock();
			
			for(size_t i = 0;i<mesh->mNumVerts;i++)
			{
				Point3F physVertex = m_physShapeSoft->getNodePos(m_vertexBindingVec[physVertexIdx++]);
				//transform into local coordinates
				mRenderWorldToObj.mulP(physVertex);
				physVertex.convolveInverse(mObjScale);
	
				*((Point3F*)vertData) = physVertex;
				vertData += vertexStride;
			}
			
			vb.unlock();
			
		}
	}
	
	Parent::prepBatchRender(state,mountedImageIndex);

	for (S32 i=start; i<end; i++)
	{
		TSShapeInstance::MeshObjectInstance* meshOI = &shapeInst->mMeshObjects[i];
		if (od >= meshOI->object->numMeshes)
			continue;
		TSMesh* mesh = meshOI->getMesh(od);
		if (mesh)
			mesh->setManualDynamic(false);
	}
	
}