PODVector<OffMeshConnection*> DynamicNavigationMesh::CollectOffMeshConnections(const BoundingBox& bounds) { PODVector<OffMeshConnection*> connections; node_->GetComponents<OffMeshConnection>(connections, true); for (unsigned i = 0; i < connections.Size(); ++i) { OffMeshConnection* connection = connections[i]; if (!(connection->IsEnabledEffective() && connection->GetEndPoint())) { // discard this connection connections.Erase(i); --i; } } return connections; }
PODVector<CrowdAgent*> CrowdManager::GetAgents(Node* node, bool inCrowdFilter) const { if (!node) node = GetScene(); PODVector<CrowdAgent*> agents; node->GetComponents<CrowdAgent>(agents, true); if (inCrowdFilter) { PODVector<CrowdAgent*>::Iterator i = agents.Begin(); while (i != agents.End()) { if ((*i)->IsInCrowd()) ++i; else i = agents.Erase(i); } } return agents; }
void PhysicsWorld::GetRigidBodies(PODVector<RigidBody*>& result, const RigidBody* body) { ATOMIC_PROFILE(PhysicsBodyQuery); result.Clear(); if (!body || !body->GetBody()) return; PhysicsQueryCallback callback(result, body->GetCollisionMask()); world_->contactTest(body->GetBody(), callback); // Remove the body itself from the returned list for (unsigned i = 0; i < result.Size(); i++) { if (result[i] == body) { result.Erase(i); break; } } }
void OptimizeIndices(ModelSubGeometryLodLevel* subGeom, ModelVertexBuffer* vb, ModelIndexBuffer* ib) { PODVector<Triangle> oldTriangles; PODVector<Triangle> newTriangles; if (subGeom->indexCount_ % 3) { PrintLine("Index count is not divisible by 3, skipping index optimization"); return; } for (unsigned i = 0; i < vb->vertices_.Size(); ++i) { vb->vertices_[i].useCount_ = 0; vb->vertices_[i].cachePosition_ = -1; } for (unsigned i = subGeom->indexStart_; i < subGeom->indexStart_ + subGeom->indexCount_; i += 3) { Triangle triangle; triangle.v0_ = ib->indices_[i]; triangle.v1_ = ib->indices_[i + 1]; triangle.v2_ = ib->indices_[i + 2]; vb->vertices_[triangle.v0_].useCount_++; vb->vertices_[triangle.v1_].useCount_++; vb->vertices_[triangle.v2_].useCount_++; oldTriangles.Push(triangle); } for (unsigned i = 0; i < vb->vertices_.Size(); ++i) CalculateScore(vb->vertices_[i]); PODVector<unsigned> vertexCache; while (oldTriangles.Size()) { unsigned bestTriangle = M_MAX_UNSIGNED; float bestTriangleScore = -1.0f; // Find the best triangle at this point for (unsigned i = 0; i < oldTriangles.Size(); ++i) { Triangle& triangle = oldTriangles[i]; float triangleScore = vb->vertices_[triangle.v0_].score_ + vb->vertices_[triangle.v1_].score_ + vb->vertices_[triangle.v2_].score_; if (triangleScore > bestTriangleScore) { bestTriangle = i; bestTriangleScore = triangleScore; } } if (bestTriangle == M_MAX_UNSIGNED) { PrintLine("Could not find next triangle, aborting index optimization"); return; } // Add the best triangle Triangle triangleCopy = oldTriangles[bestTriangle]; newTriangles.Push(triangleCopy); oldTriangles.Erase(oldTriangles.Begin() + bestTriangle); // Reduce the use count vb->vertices_[triangleCopy.v0_].useCount_--; vb->vertices_[triangleCopy.v1_].useCount_--; vb->vertices_[triangleCopy.v2_].useCount_--; // Model the LRU cache behaviour // Erase the triangle vertices from the middle of the cache, if they were there for (unsigned i = 0; i < vertexCache.Size(); ++i) { if ((vertexCache[i] == triangleCopy.v0_) || (vertexCache[i] == triangleCopy.v1_) || (vertexCache[i] == triangleCopy.v2_)) { vertexCache.Erase(vertexCache.Begin() + i); --i; } } // Then push them to the front vertexCache.Insert(vertexCache.Begin(), triangleCopy.v0_); vertexCache.Insert(vertexCache.Begin(), triangleCopy.v1_); vertexCache.Insert(vertexCache.Begin(), triangleCopy.v2_); // Update positions & scores of all vertices in the cache // Give position -1 if vertex is going to be erased for (unsigned i = 0; i < vertexCache.Size(); ++i) { ModelVertex& vertex = vb->vertices_[vertexCache[i]]; if (i >= VERTEX_CACHE_SIZE) vertex.cachePosition_ = -1; else vertex.cachePosition_ = i; CalculateScore(vertex); } // Finally erase the extra vertices if (vertexCache.Size() > VERTEX_CACHE_SIZE) vertexCache.Resize(VERTEX_CACHE_SIZE); } // Rewrite the index data now unsigned i = subGeom->indexStart_; for (unsigned j = 0; j < newTriangles.Size(); ++j) { ib->indices_[i++] = newTriangles[j].v0_; ib->indices_[i++] = newTriangles[j].v1_; ib->indices_[i++] = newTriangles[j].v2_; } }