void Component::GetComponents(PODVector<Component*>& dest, StringHash type) const { if (node_) node_->GetComponents(dest, type); else dest.Clear(); }
void PhysicsWorld2D::Raycast(PODVector<PhysicsRaycastResult2D>& results, const Vector2& startPoint, const Vector2& endPoint, unsigned collisionMask) { results.Clear(); RayCastCallback callback(results, startPoint, collisionMask); world_->RayCast(&callback, ToB2Vec2(startPoint), ToB2Vec2(endPoint)); }
template<> void* ToluaToPODVector<Vector2>(lua_State* L, int narg, void* def) { if (!lua_istable(L, narg)) return 0; static PODVector<Vector2> result; result.Clear(); tolua_Error tolua_err; int length = lua_objlen(L, narg); for (int i = 1; i <= length; ++i) { lua_pushinteger(L, i); lua_gettable(L, narg); if (!tolua_isusertype(L, -1, "Vector2", 0, &tolua_err)) { lua_pop(L, 1); return 0; } Vector2* value = (Vector2*)tolua_touserdata(L, -1, 0); result.Push(*value); lua_pop(L, 1); } return &result; }
template<> void* ToluaToPODVector<unsigned>(lua_State* L, int narg, void* def) { if (!lua_istable(L, narg)) return 0; static PODVector<unsigned> result; result.Clear(); int length = lua_objlen(L, narg); for (int i = 1; i <= length; ++i) { lua_pushinteger(L, i); lua_gettable(L, narg); if (!lua_isnumber(L, -1)) { lua_pop(L, 1); return 0; } unsigned value = (unsigned)tolua_tonumber(L, -1, 0); result.Push(value); lua_pop(L, 1); } return &result; }
static void ClipPolygon(PODVector<DecalVertex>& dest, const PODVector<DecalVertex>& src, const Plane& plane, bool skinned) { unsigned last = 0; float lastDistance = 0.0f; dest.Clear(); if (src.Empty()) return; for (unsigned i = 0; i < src.Size(); ++i) { float distance = plane.Distance(src[i].position_); if (distance >= 0.0f) { if (lastDistance < 0.0f) dest.Push(ClipEdge(src[last], src[i], lastDistance, distance, skinned)); dest.Push(src[i]); } else { if (lastDistance >= 0.0f && i != 0) dest.Push(ClipEdge(src[last], src[i], lastDistance, distance, skinned)); } last = i; lastDistance = distance; } // Recheck the distances of the last and first vertices and add the final clipped vertex if applicable float distance = plane.Distance(src[0].position_); if ((lastDistance < 0.0f && distance >= 0.0f) || (lastDistance >= 0.0f && distance < 0.0f)) dest.Push(ClipEdge(src[last], src[0], lastDistance, distance, skinned)); }
void RigidBody::GetCollidingBodies(PODVector<RigidBody*>& result) const { if (physicsWorld_) physicsWorld_->GetRigidBodies(result, this); else result.Clear(); }
void CopyStrippedCode(PODVector<unsigned char>& dest, void* src, unsigned srcSize) { unsigned const D3DSIO_COMMENT = 0xFFFE; unsigned* srcWords = (unsigned*)src; unsigned srcWordSize = srcSize >> 2; dest.Clear(); for (unsigned i = 0; i < srcWordSize; ++i) { unsigned opcode = srcWords[i] & 0xffff; unsigned paramLength = (srcWords[i] & 0x0f000000) >> 24; unsigned commentLength = srcWords[i] >> 16; // For now, skip comment only at fixed position to prevent false positives if (i == 1 && opcode == D3DSIO_COMMENT) { // Skip the comment i += commentLength; } else { // Not a comment, copy the data unsigned char* srcBytes = (unsigned char*)(srcWords + i); dest.Push(*srcBytes++); dest.Push(*srcBytes++); dest.Push(*srcBytes++); dest.Push(*srcBytes++); } } }
void Node::GetComponents(PODVector<Component*>& dest, ShortStringHash type) const { dest.Clear(); for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i) { if ((*i)->GetType() == type) dest.Push(*i); } }
void NavigationMesh::FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, const Vector3& extents, const dtQueryFilter* filter) { PODVector<NavigationPathPoint> navPathPoints; FindPath(navPathPoints, start, end, extents, filter); dest.Clear(); for (unsigned i = 0; i < navPathPoints.Size(); ++i) dest.Push(navPathPoints[i].position_); }
void ResourceCache::GetResources(PODVector<Resource*>& result, ShortStringHash type) const { result.Clear(); HashMap<ShortStringHash, ResourceGroup>::ConstIterator i = resourceGroups_.Find(type); if (i != resourceGroups_.End()) { for (HashMap<StringHash, SharedPtr<Resource> >::ConstIterator j = i->second_.resources_.Begin(); j != i->second_.resources_.End(); ++j) result.Push(j->second_); } }
bool Scene::GetNodesWithTag(PODVector<Node*>& dest, const String& tag) const { dest.Clear(); HashMap<StringHash, PODVector<Node*> >::ConstIterator it = taggedNodes_.Find(tag); if (it != taggedNodes_.End()) { dest = it->second_; return true; } else return false; }
void Node::GetChildren(PODVector<Node*>& dest, bool recursive) const { dest.Clear(); if (!recursive) { for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i) dest.Push(*i); } else GetChildrenRecursive(dest); }
void AssetDatabase::GetDirtyAssets(PODVector<Asset*>& assets) { assets.Clear(); List<SharedPtr<Asset>>::ConstIterator itr = assets_.Begin(); while (itr != assets_.End()) { if ((*itr)->IsDirty()) assets.Push(*itr); itr++; } }
template <> void* ToluaToPODVector<bool>(double /*overload*/, lua_State* L, int narg, void* /*def*/) { if (!lua_istable(L, narg)) return 0; static PODVector<bool> result; result.Clear(); result.Resize((unsigned)lua_objlen(L, narg)); for (unsigned i = 0; i < result.Size(); ++i) { lua_rawgeti(L, narg, i + 1); result[i] = (bool)tolua_toboolean(L, -1, 0); lua_pop(L, 1); } return &result; }
void PhysicsWorld::GetRigidBodies(PODVector<RigidBody*>& result, const RigidBody* body) { PROFILE(GetCollidingBodies); result.Clear(); for (HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, btPersistentManifold*>::Iterator i = currentCollisions_.Begin(); i != currentCollisions_.End(); ++i) { if (i->first_.first_ == body) result.Push(i->first_.second_); else if (i->first_.second_ == body) result.Push(i->first_.first_); } }
void Node::GetChildrenWithComponent(PODVector<Node*>& dest, ShortStringHash type, bool recursive) const { dest.Clear(); if (!recursive) { for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i) { if ((*i)->HasComponent(type)) dest.Push(*i); } } else GetChildrenWithComponentRecursive(dest, type); }
void Node::GetComponents(PODVector<Component*>& dest, StringHash type, bool recursive) const { dest.Clear(); if (!recursive) { for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i) { if ((*i)->GetType() == type) dest.Push(*i); } } else GetComponentsRecursive(dest, type); }
void PhysicsWorld::GetRigidBodies(PODVector<RigidBody*>& result, const BoundingBox& box, unsigned collisionMask) { ATOMIC_PROFILE(PhysicsBoxQuery); result.Clear(); btBoxShape boxShape(ToBtVector3(box.HalfSize())); UniquePtr<btRigidBody> tempRigidBody(new btRigidBody(1.0f, 0, &boxShape)); tempRigidBody->setWorldTransform(btTransform(btQuaternion::getIdentity(), ToBtVector3(box.Center()))); tempRigidBody->activate(); world_->addRigidBody(tempRigidBody.Get()); PhysicsQueryCallback callback(result, collisionMask); world_->contactTest(tempRigidBody.Get(), callback); world_->removeRigidBody(tempRigidBody.Get()); }
void AssetDatabase::GetAssetsByImporterType(StringHash type, PODVector<Asset*>& assets) const { assets.Clear(); List<SharedPtr<Asset>>::ConstIterator itr = assets_.Begin(); while (itr != assets_.End()) { Asset* asset = *itr; if (asset->GetImporterType() == type) assets.Push(asset); itr++; } }
void NavigationMesh::FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, const Vector3& extents) { PROFILE(FindPath); dest.Clear(); if (!InitializeQuery()) return; // Navigation data is in local space. Transform path points from world to local const Matrix3x4& transform = node_->GetWorldTransform(); Matrix3x4 inverse = transform.Inverse(); Vector3 localStart = inverse * start; Vector3 localEnd = inverse * end; dtPolyRef startRef; dtPolyRef endRef; navMeshQuery_->findNearestPoly(&localStart.x_, &extents.x_, queryFilter_, &startRef, 0); navMeshQuery_->findNearestPoly(&localEnd.x_, &extents.x_, queryFilter_, &endRef, 0); if (!startRef || !endRef) return; int numPolys = 0; int numPathPoints = 0; navMeshQuery_->findPath(startRef, endRef, &localStart.x_, &localEnd.x_, queryFilter_, pathData_->polys_, &numPolys, MAX_POLYS); if (!numPolys) return; Vector3 actualLocalEnd = localEnd; // If full path was not found, clamp end point to the end polygon if (pathData_->polys_[numPolys - 1] != endRef) navMeshQuery_->closestPointOnPoly(pathData_->polys_[numPolys - 1], &localEnd.x_, &actualLocalEnd.x_); navMeshQuery_->findStraightPath(&localStart.x_, &actualLocalEnd.x_, pathData_->polys_, numPolys, &pathData_->pathPoints_[0].x_, pathData_->pathFlags_, pathData_->pathPolys_, &numPathPoints, MAX_POLYS); // Transform path result back to world space for (int i = 0; i < numPathPoints; ++i) dest.Push(transform * pathData_->pathPoints_[i]); }
void PhysicsWorld::GetRigidBodies(PODVector<RigidBody*>& result, const Sphere& sphere, unsigned collisionMask) { ATOMIC_PROFILE(PhysicsSphereQuery); result.Clear(); btSphereShape sphereShape(sphere.radius_); UniquePtr<btRigidBody> tempRigidBody(new btRigidBody(1.0f, 0, &sphereShape)); tempRigidBody->setWorldTransform(btTransform(btQuaternion::getIdentity(), ToBtVector3(sphere.center_))); // Need to activate the temporary rigid body to get reliable results from static, sleeping objects tempRigidBody->activate(); world_->addRigidBody(tempRigidBody.Get()); PhysicsQueryCallback callback(result, collisionMask); world_->contactTest(tempRigidBody.Get(), callback); world_->removeRigidBody(tempRigidBody.Get()); }
void StringToBuffer(PODVector<unsigned char>& dest, const char* source) { if (!source) { dest.Clear(); return; } unsigned size = CountElements(source, ' '); dest.Resize(size); bool inSpace = true; unsigned index = 0; unsigned value = 0; // Parse values const char* ptr = source; while (*ptr) { if (inSpace && *ptr != ' ') { inSpace = false; value = (unsigned)(*ptr - '0'); } else if (!inSpace && *ptr != ' ') { value *= 10; value += *ptr - '0'; } else if (!inSpace && *ptr == ' ') { dest[index++] = (unsigned char)value; inSpace = true; } ++ptr; } // Write the final value if (!inSpace && index < size) dest[index] = (unsigned char)value; }
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; } } }
bool GetBlendData(OutModel& model, aiMesh* mesh, PODVector<unsigned>& boneMappings, Vector<PODVector<unsigned char> >& blendIndices, Vector<PODVector<float> >& blendWeights, String& errorMessage, unsigned maxBones) { blendIndices.Resize(mesh->mNumVertices); blendWeights.Resize(mesh->mNumVertices); boneMappings.Clear(); // If model has more bones than can fit vertex shader parameters, write the per-geometry mappings if (model.bones_.Size() > maxBones) { if (mesh->mNumBones > maxBones) { errorMessage = "Geometry (submesh) has over " + String(maxBones) + " bone influences. Try splitting to more submeshes\n" "that each stay at " + String(maxBones) + " bones or below."; return false; } boneMappings.Resize(mesh->mNumBones); for (unsigned i = 0; i < mesh->mNumBones; ++i) { aiBone* bone = mesh->mBones[i]; String boneName = FromAIString(bone->mName); unsigned globalIndex = GetBoneIndex(model, boneName); if (globalIndex == M_MAX_UNSIGNED) { errorMessage = "Bone " + boneName + " not found"; return false; } boneMappings[i] = globalIndex; for (unsigned j = 0; j < bone->mNumWeights; ++j) { unsigned vertex = bone->mWeights[j].mVertexId; blendIndices[vertex].Push(i); blendWeights[vertex].Push(bone->mWeights[j].mWeight); } } } else { for (unsigned i = 0; i < mesh->mNumBones; ++i) { aiBone* bone = mesh->mBones[i]; String boneName = FromAIString(bone->mName); unsigned globalIndex = GetBoneIndex(model, boneName); if (globalIndex == M_MAX_UNSIGNED) { errorMessage = "Bone " + boneName + " not found"; return false; } for (unsigned j = 0; j < bone->mNumWeights; ++j) { unsigned vertex = bone->mWeights[j].mVertexId; blendIndices[vertex].Push(globalIndex); blendWeights[vertex].Push(bone->mWeights[j].mWeight); } } } // Normalize weights now if necessary, also remove too many influences for (unsigned i = 0; i < blendWeights.Size(); ++i) { if (blendWeights[i].Size() > 4) { PrintLine("Warning: more than 4 bone influences in vertex " + String(i)); while (blendWeights[i].Size() > 4) { unsigned lowestIndex = 0; float lowest = M_INFINITY; for (unsigned j = 0; j < blendWeights[i].Size(); ++j) { if (blendWeights[i][j] < lowest) { lowest = blendWeights[i][j]; lowestIndex = j; } } blendWeights[i].Erase(lowestIndex); blendIndices[i].Erase(lowestIndex); } } float sum = 0.0f; for (unsigned j = 0; j < blendWeights[i].Size(); ++j) sum += blendWeights[i][j]; if (sum != 1.0f && sum != 0.0f) { for (unsigned j = 0; j < blendWeights[i].Size(); ++j) blendWeights[i][j] /= sum; } } return true; }
void NavigationMesh::FindPath(PODVector<NavigationPathPoint>& dest, const Vector3& start, const Vector3& end, const Vector3& extents, const dtQueryFilter* filter) { ATOMIC_PROFILE(FindPath); dest.Clear(); if (!InitializeQuery()) return; // Navigation data is in local space. Transform path points from world to local const Matrix3x4& transform = node_->GetWorldTransform(); Matrix3x4 inverse = transform.Inverse(); Vector3 localStart = inverse * start; Vector3 localEnd = inverse * end; const dtQueryFilter* queryFilter = filter ? filter : queryFilter_.Get(); dtPolyRef startRef; dtPolyRef endRef; navMeshQuery_->findNearestPoly(&localStart.x_, &extents.x_, queryFilter, &startRef, 0); navMeshQuery_->findNearestPoly(&localEnd.x_, &extents.x_, queryFilter, &endRef, 0); if (!startRef || !endRef) return; int numPolys = 0; int numPathPoints = 0; navMeshQuery_->findPath(startRef, endRef, &localStart.x_, &localEnd.x_, queryFilter, pathData_->polys_, &numPolys, MAX_POLYS); if (!numPolys) return; Vector3 actualLocalEnd = localEnd; // If full path was not found, clamp end point to the end polygon if (pathData_->polys_[numPolys - 1] != endRef) navMeshQuery_->closestPointOnPoly(pathData_->polys_[numPolys - 1], &localEnd.x_, &actualLocalEnd.x_, 0); navMeshQuery_->findStraightPath(&localStart.x_, &actualLocalEnd.x_, pathData_->polys_, numPolys, &pathData_->pathPoints_[0].x_, pathData_->pathFlags_, pathData_->pathPolys_, &numPathPoints, MAX_POLYS); // Transform path result back to world space for (int i = 0; i < numPathPoints; ++i) { NavigationPathPoint pt; pt.position_ = transform * pathData_->pathPoints_[i]; pt.flag_ = (NavigationPathPointFlag)pathData_->pathFlags_[i]; // Walk through all NavAreas and find nearest unsigned nearestNavAreaID = 0; // 0 is the default nav area ID float nearestDistance = M_LARGE_VALUE; for (unsigned j = 0; j < areas_.Size(); j++) { NavArea* area = areas_[j].Get(); if (area && area->IsEnabledEffective()) { BoundingBox bb = area->GetWorldBoundingBox(); if (bb.IsInside(pt.position_) == INSIDE) { Vector3 areaWorldCenter = area->GetNode()->GetWorldPosition(); float distance = (areaWorldCenter - pt.position_).LengthSquared(); if (distance < nearestDistance) { nearestDistance = distance; nearestNavAreaID = area->GetAreaID(); } } } } pt.areaID_ = (unsigned char)nearestNavAreaID; dest.Push(pt); } }