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 } }
//------------------------------------------------------------------------------ //! 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; }