Пример #1
0
	void ForwardRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix)
	{
		if (material->IsEnabled(RendererParameter_Blend))
		{
			Layer& currentLayer = GetLayer(renderOrder);
			auto& transparentModels = currentLayer.transparentModels;
			auto& transparentModelData = currentLayer.transparentModelData;

			// Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant)
			unsigned int index = transparentModelData.size();
			transparentModelData.resize(index+1);

			TransparentModelData& data = transparentModelData.back();
			data.material = material;
			data.meshData = meshData;
			data.squaredBoundingSphere = Spheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius());
			data.transformMatrix = transformMatrix;

			transparentModels.push_back(index);
		}
		else
		{
			Layer& currentLayer = GetLayer(renderOrder);
			auto& opaqueModels = currentLayer.opaqueModels;

			auto it = opaqueModels.find(material);
			if (it == opaqueModels.end())
			{
				BatchedModelEntry entry;
				entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);

				it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first;
			}

			BatchedModelEntry& entry = it->second;
			entry.enabled = true;

			auto& meshMap = entry.meshMap;

			auto it2 = meshMap.find(meshData);
			if (it2 == meshMap.end())
			{
				MeshInstanceEntry instanceEntry;
				instanceEntry.squaredBoundingSphere = meshAABB.GetSquaredBoundingSphere();

				if (meshData.indexBuffer)
					instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &ForwardRenderQueue::OnIndexBufferInvalidation);

				instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &ForwardRenderQueue::OnVertexBufferInvalidation);

				it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first;
			}

			std::vector<Matrix4f>& instances = it2->second.instances;
			instances.push_back(transformMatrix);

			// Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ?
			if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT)
				entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau
		}
	}
Пример #2
0
//------------------------------------------------------------------------------
//!
void
adjustRoot( const Vector<Puppeteer::PositionalConstraint>& pc, Vec3f& root, Vec3f& dRoot )
{
   // Test if root is contained into limbs spheres.
   Vec3f newRoot;

   bool in = true;
   for( uint i = 0; i < pc.size(); ++i )
   {
      in &= pc[i].sphere().isInside( root );
   }
   // Are we inside all constraints range?
   if( in ) return;

   // 1 sphere.
   if( pc.size() == 1 )
   {
      newRoot = pc[0].sphere().project( root );
   }
   // 2 spheres not intersecting.
   else if( !pc[0].sphere().isOverlapping( pc[1].sphere() ) )
   {
      // Return the projection on the most important one.
      uint s  = pc[0].weight() > pc[1].weight() ? 0 : 1;
      newRoot = pc[s].sphere().project( root );
   }
   else
   {
      // 2 spheres intersecting.
      // Test nearest point on spheres.
      Vec3f projPt[2];
      projPt[0] = pc[0].sphere().project( root );
      projPt[1] = pc[1].sphere().project( root );

      int minPt  = -1;
      float dist = CGConstf::infinity();
      if( pc[1].sphere().isInside( projPt[0] ) )
      {
         minPt = 0;
         dist  = (projPt[0]-root).sqrLength();
      }

      if( pc[0].sphere().isInside( projPt[1] ) )
      {
         float cdist = (projPt[1]-root).sqrLength();
         if( cdist < dist ) minPt = 1;
      }

      // Test circle.
      if( minPt < 0 )
      {
         const Spheref& s0 = pc[0].sphere();
         const Spheref& s1 = pc[1].sphere();

         // Compute center of intersection circle.
         Vec3f dir = s1.center()-s0.center();
         float d2  = dir.sqrLength();
         float t  = (d2 - s1.radius()*s1.radius() + s0.radius()*s0.radius())/(2.0f*d2);
         Vec3f center = s0.center() + dir*t;

         // Compute radius of intersection circle.
         float r = CGM::sqrt( (s0.radius()*s0.radius())-t*t*d2 );

         // Project root on the circle plane.
         Planef plane( dir, center );
         plane.normalize();
         Vec3f pRoot = plane.closest( root );

         // Nearest point on circle.
         newRoot = Spheref( center, r ).project( pRoot );
      }
      else
      {
         newRoot = projPt[minPt];
      }
   }

   // Compute new root and displacement.
   dRoot  += newRoot - root;
   root    = newRoot;
}