// ---------------------------------------------------------------------------- void IKSolver::HandleNodeAdded(StringHash eventType, VariantMap& eventData) { using namespace NodeAdded; if (solver_->tree == NULL) return; Node* node = static_cast<Node*>(eventData[P_NODE].GetPtr()); PODVector<Node*> nodes; node->GetChildrenWithComponent<IKEffector>(nodes, true); for (PODVector<Node*>::ConstIterator it = nodes.Begin(); it != nodes.End(); ++it) { BuildTreeToEffector(*it); effectorList_.Push((*it)->GetComponent<IKEffector>()); } }
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; }
bool CrowdManager::CreateCrowd() { if (!navigationMesh_ || !navigationMesh_->InitializeQuery()) return false; // Preserve the existing crowd configuration before recreating it VariantVector queryFilterTypeConfiguration, obstacleAvoidanceTypeConfiguration; bool recreate = crowd_ != nullptr; if (recreate) { queryFilterTypeConfiguration = GetQueryFilterTypesAttr(); obstacleAvoidanceTypeConfiguration = GetObstacleAvoidanceTypesAttr(); dtFreeCrowd(crowd_); } crowd_ = dtAllocCrowd(); // Initialize the crowd if (maxAgentRadius_ == 0.f) maxAgentRadius_ = navigationMesh_->GetAgentRadius(); if (!crowd_->init(maxAgents_, maxAgentRadius_, navigationMesh_->navMesh_, CrowdAgentUpdateCallback)) { URHO3D_LOGERROR("Could not initialize DetourCrowd"); return false; } if (recreate) { // Reconfigure the newly initialized crowd SetQueryFilterTypesAttr(queryFilterTypeConfiguration); SetObstacleAvoidanceTypesAttr(obstacleAvoidanceTypeConfiguration); // Re-add the existing crowd agents PODVector<CrowdAgent*> agents = GetAgents(); for (unsigned i = 0; i < agents.Size(); ++i) { // Keep adding until the crowd cannot take it anymore if (agents[i]->AddAgentToCrowd(true) == -1) { URHO3D_LOGWARNINGF("CrowdManager: %d crowd agents orphaned", agents.Size() - i); break; } } } return true; }
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)); }
void AssetDatabase::GetAssetsByImporterType(StringHash type, const String &resourceType, 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++; } }
bool AssetDatabase::ImportDirtyAssets() { PODVector<Asset*> assets; GetDirtyAssets(assets); for (unsigned i = 0; i < assets.Size(); i++) { assets[i]->Import(); assets[i]->Save(); assets[i]->dirty_ = false; assets[i]->UpdateFileTimestamp(); } return assets.Size() != 0; }
bool MasterControl::CursorRayCast(double maxDistance, PODVector<RayQueryResult> &hitResults) { Ray cameraRay = world.camera->camera_->GetScreenRay(0.5f,0.5f); RayOctreeQuery query(hitResults, cameraRay, RAY_TRIANGLE, maxDistance, DRAWABLE_GEOMETRY); world.scene->GetComponent<Octree>()->Raycast(query); if (hitResults.Size()) return true; else return false; }
CSComponentAssembly* CSComponentAssembly::ResolveClassAssembly(const String& fullClassName) { Context* context = ScriptSystem::GetContext(); assert(context); String classname = fullClassName; String csnamespace; // Handle namespaces if (fullClassName.Contains('.')) { StringVector elements = fullClassName.Split('.'); if (elements.Size() <= 1) return 0; classname = elements.Back(); elements.Pop(); csnamespace = String::Joined(elements, "."); } ResourceCache* cache = context->GetSubsystem<ResourceCache>(); PODVector<CSComponentAssembly*> assemblies; cache->GetResources<CSComponentAssembly>(assemblies); for (unsigned i = 0; i < assemblies.Size(); i++) { CSComponentAssembly* assembly = assemblies[i]; // TODO: support namespaces const StringVector& classNames = assembly->GetClassNames(); if (classNames.Contains(classname)) { return assembly; } } return 0; }
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]); }
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 GravityManager::RemoveGravityVectorsRecursively(Node* node) { // Recursively retrieve all nodes that have a gravity probe component PODVector<Node*> gravityVectorNodesToRemove; node->GetChildrenWithComponent<GravityVector>(gravityVectorNodesToRemove, true); // Don't forget to check this node's components as well if(node->GetComponent<GravityVector>()) gravityVectorNodesToRemove.Push(node); // search for found components and remove them from our internal list PODVector<Node*>::ConstIterator it = gravityVectorNodesToRemove.Begin(); for(; it != gravityVectorNodesToRemove.End(); ++it) { PODVector<GravityVector*>::Iterator gravityNode = gravityVectors_.Find((*it)->GetComponent<GravityVector>()); if(gravityNode != gravityVectors_.End()) gravityVectors_.Erase(gravityNode); } }
void CustomGeometry::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results) { RayQueryLevel level = query.level_; switch (level) { case RAY_AABB: Drawable::ProcessRayQuery(query, results); break; case RAY_OBB: case RAY_TRIANGLE: { Matrix3x4 inverse(node_->GetWorldTransform().Inverse()); Ray localRay = query.ray_.Transformed(inverse); float distance = localRay.HitDistance(boundingBox_); Vector3 normal = -query.ray_.direction_; if (level == RAY_TRIANGLE && distance < query.maxDistance_) { distance = M_INFINITY; for (unsigned i = 0; i < batches_.Size(); ++i) { Geometry* geometry = batches_[i].geometry_; if (geometry) { Vector3 geometryNormal; float geometryDistance = geometry->GetHitDistance(localRay, &geometryNormal); if (geometryDistance < query.maxDistance_ && geometryDistance < distance) { distance = geometryDistance; normal = (node_->GetWorldTransform() * Vector4(geometryNormal, 0.0f)).Normalized(); } } } } if (distance < query.maxDistance_) { RayQueryResult result; result.position_ = query.ray_.origin_ + distance * query.ray_.direction_; result.normal_ = normal; result.distance_ = distance; result.drawable_ = this; result.node_ = node_; result.subObject_ = M_MAX_UNSIGNED; results.Push(result); } } break; case RAY_TRIANGLE_UV: ATOMIC_LOGWARNING("RAY_TRIANGLE_UV query level is not supported for CustomGeometry component"); break; } }
void Pickup::HandleTriggerStart(StringHash eventType, VariantMap &eventData) { PODVector<RigidBody*> collidingBodies; triggerBody_->GetCollidingBodies(collidingBodies); for (int i = 0; i < collidingBodies.Size(); i++) { RigidBody* collider = collidingBodies[i]; if (collider->GetNode()->GetNameHash() == N_PLAYER) { masterControl_->player_->Pickup(pickupType_); masterControl_->spawnMaster_->SpawnHitFX(GetPosition(), false); switch (pickupType_){ case PT_MULTIX: case PT_CHAOBALL: Deactivate(); break; case PT_APPLE: case PT_HEART: Respawn(); break; default: break; } } } }
void StaticModel::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results) { RayQueryLevel level = query.level_; switch (level) { case RAY_AABB: Drawable::ProcessRayQuery(query, results); break; case RAY_OBB: case RAY_TRIANGLE: case RAY_TRIANGLE_UV: Matrix3x4 inverse(node_->GetWorldTransform().Inverse()); Ray localRay = query.ray_.Transformed(inverse); float distance = localRay.HitDistance(boundingBox_); Vector3 normal = -query.ray_.direction_; Vector2 geometryUV; unsigned hitBatch = M_MAX_UNSIGNED; if (level >= RAY_TRIANGLE && distance < query.maxDistance_) { distance = M_INFINITY; for (unsigned i = 0; i < batches_.Size(); ++i) { Geometry* geometry = batches_[i].geometry_; if (geometry) { Vector3 geometryNormal; float geometryDistance = level == RAY_TRIANGLE ? geometry->GetHitDistance(localRay, &geometryNormal) : geometry->GetHitDistance(localRay, &geometryNormal, &geometryUV); if (geometryDistance < query.maxDistance_ && geometryDistance < distance) { distance = geometryDistance; normal = (node_->GetWorldTransform() * Vector4(geometryNormal, 0.0f)).Normalized(); hitBatch = i; } } } } if (distance < query.maxDistance_) { RayQueryResult result; result.position_ = query.ray_.origin_ + distance * query.ray_.direction_; result.normal_ = normal; result.textureUV_ = geometryUV; result.distance_ = distance; result.drawable_ = this; result.node_ = node_; result.subObject_ = hitBatch; results.Push(result); } break; } }
unsigned VertexBuffer::GetVertexSize(const PODVector<VertexElement>& elements) { unsigned size = 0; for (unsigned i = 0; i < elements.Size(); ++i) size += ELEMENT_TYPESIZES[elements[i].type_]; return size; }
static int ModelImporter_GetAnimations(duk_context* ctx) { duk_push_this(ctx); ModelImporter* importer = js_to_class_instance<ModelImporter>(ctx, -1, 0); PODVector<Animation*> animations; importer->GetAnimations(animations); duk_push_array(ctx); for(unsigned i = 0; i < animations.Size(); i++) { js_push_class_object_instance(ctx, animations[i], 0); duk_put_prop_index(ctx, -2, i); } return 1; }
void Typography::HandleWhiteBackground(StringHash eventType, VariantMap& eventData) { auto* box = static_cast<CheckBox*>(eventData[Toggled::P_ELEMENT].GetPtr()); bool checked = box->IsChecked(); Color fg = checked ? Color::BLACK : Color::WHITE; Color bg = checked ? Color::WHITE : Color::BLACK; auto* renderer = GetSubsystem<Renderer>(); Zone* zone = renderer->GetDefaultZone(); zone->SetFogColor(bg); PODVector<UIElement*> text = uielement_->GetChildrenWithTag(TEXT_TAG, true); for (int i = 0; i < text.Size(); i++) { text[i]->SetColor(fg); } }
VertexDeclaration::VertexDeclaration(Graphics* graphics, const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>& elementMasks) : declaration_(0) { unsigned usedElementMask = 0; PODVector<VertexDeclarationElement> elements; for (unsigned i = 0; i < buffers.Size(); ++i) { if (buffers[i]) { unsigned elementMask = elementMasks[i]; if (elementMask == MASK_DEFAULT) elementMask = buffers[i]->GetElementMask(); else { if ((buffers[i]->GetElementMask() & elementMask) != elementMask) return; } if (elementMask & MASK_OBJECTINDEX) URHO3D_LOGWARNING("Object index attribute is not supported on Direct3D9 and will be ignored"); for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j) { VertexElement element = (VertexElement)j; if (elementMask & (1 << j) && !(usedElementMask & (1 << j))) { VertexDeclarationElement newElement; newElement.stream_ = i; newElement.element_ = element; newElement.offset_ = buffers[i]->GetElementOffset(element); usedElementMask |= 1 << j; elements.Push(newElement); } } } } Create(graphics, elements); }
void Node::GetComponentsRecursive(PODVector<Component*>& dest, ShortStringHash type) const { for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i) { if ((*i)->GetType() == type) dest.Push(*i); } for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i) (*i)->GetComponentsRecursive(dest, type); }
void Node::GetChildrenRecursive(PODVector<Node*>& dest) const { for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i) { Node* node = *i; dest.Push(node); if (!node->children_.Empty()) node->GetChildrenRecursive(dest); } }
void Menu::ShowPopup(bool enable) { if (!popup_) return; if (enable) { OnShowPopup(); popup_->SetVar(VAR_ORIGIN, this); static_cast<Window*>(popup_.Get())->SetModal(true); popup_->SetPosition(GetScreenPosition() + popupOffset_); popup_->SetVisible(true); // BringToFront() is unreliable in this case as it takes into account only input-enabled elements. // Rather just force priority to max popup_->SetPriority(M_MAX_INT); } else { OnHidePopup(); // If the popup has child menus, hide their popups as well PODVector<UIElement*> children; popup_->GetChildren(children, true); for (PODVector<UIElement*>::ConstIterator i = children.Begin(); i != children.End(); ++i) { Menu* menu = dynamic_cast<Menu*>(*i); if (menu) menu->ShowPopup(false); } static_cast<Window*>(popup_.Get())->SetModal(false); const_cast<VariantMap&>(popup_->GetVars()).Erase(VAR_ORIGIN); popup_->SetVisible(false); popup_->Remove(); } SetVar(VAR_SHOW_POPUP, enable); showPopup_ = enable; selected_ = enable; }
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 Zone::OnMarkedDirty(Node* node) { // Due to the octree query and weak pointer manipulation, is not safe from worker threads Scene* scene = GetScene(); if (scene && scene->IsThreadedUpdate()) { scene->DelayedMarkedDirty(this); return; } Drawable::OnMarkedDirty(node); // When marked dirty, clear the cached zone from all drawables inside the zone bounding box, // and mark gradient dirty in all neighbor zones if (octant_ && lastWorldBoundingBox_.defined_) { PODVector<Drawable*> result; BoxOctreeQuery query(result, lastWorldBoundingBox_, DRAWABLE_GEOMETRY | DRAWABLE_ZONE); octant_->GetRoot()->GetDrawables(query); for (PODVector<Drawable*>::Iterator i = result.Begin(); i != result.End(); ++i) { Drawable* drawable = *i; unsigned drawableFlags = drawable->GetDrawableFlags(); if (drawableFlags & DRAWABLE_GEOMETRY) { if (drawable->GetZone() == this) drawable->SetZone(0); } else if (drawableFlags & DRAWABLE_ZONE) { Zone* zone = static_cast<Zone*>(drawable); zone->lastAmbientStartZone_.Reset(); zone->lastAmbientEndZone_.Reset(); } } } lastWorldBoundingBox_ = GetWorldBoundingBox(); lastAmbientStartZone_.Reset(); lastAmbientEndZone_.Reset(); inverseWorldDirty_ = true; }
bool Serializer::WriteBuffer(const PODVector<unsigned char>& value) { bool success = true; unsigned size = value.Size(); success &= WriteVLE(size); if (size) success &= Write(&value[0], size) == size; return success; }
void StaticModelGroup::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results) { // If no bones or no bone-level testing, use the Drawable test RayQueryLevel level = query.level_; if (level < RAY_AABB) { Drawable::ProcessRayQuery(query, results); return; } // Check ray hit distance to AABB before proceeding with more accurate tests // GetWorldBoundingBox() updates the world transforms if (query.ray_.HitDistance(GetWorldBoundingBox()) >= query.maxDistance_) return; for (unsigned i = 0; i < numWorldTransforms_; ++i) { // Initial test using AABB float distance = query.ray_.HitDistance(boundingBox_.Transformed(worldTransforms_[i])); // Then proceed to OBB and triangle-level tests if necessary if (level >= RAY_OBB && distance < query.maxDistance_) { Matrix3x4 inverse = worldTransforms_[i].Inverse(); Ray localRay = query.ray_.Transformed(inverse); distance = localRay.HitDistance(boundingBox_); if (level == RAY_TRIANGLE && distance < query.maxDistance_) { distance = M_INFINITY; for (unsigned j = 0; j < batches_.Size(); ++j) { Geometry* geometry = batches_[j].geometry_; if (geometry) { float geometryDistance = geometry->GetHitDistance(localRay); if (geometryDistance < query.maxDistance_ && geometryDistance < distance) distance = geometryDistance; } } } } if (distance < query.maxDistance_) { RayQueryResult result; result.drawable_ = this; result.node_ = node_; result.distance_ = distance; result.subObject_ = i; results.Push(result); } } }
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 Node::GetChildrenWithComponentRecursive(PODVector<Node*>& dest, ShortStringHash type) const { for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i) { Node* node = *i; if (node->HasComponent(type)) dest.Push(node); if (!node->children_.Empty()) node->GetChildrenWithComponentRecursive(dest, type); } }
void JSUI::GatherWidgets(tb::TBWidget* widget, PODVector<tb::TBWidget*>& widgets) { if (widget->GetID() != TBID()) widgets.Push(widget); for (TBWidget *n = widget->GetFirstChild(); n; n = n->GetNext()) { GatherWidgets(n, widgets); } }
void ScriptInstance::ReleaseObject() { if (scriptObject_) { if (methods_[METHOD_STOP]) scriptFile_->Execute(scriptObject_, methods_[METHOD_STOP]); PODVector<StringHash> exceptions; exceptions.Push(E_RELOADSTARTED); exceptions.Push(E_RELOADFINISHED); UnsubscribeFromAllEventsExcept(exceptions, false); subscribed_ = false; ClearMethods(); scriptObject_->SetUserData(0); scriptObject_->Release(); scriptObject_ = 0; } }
void Menu::ShowPopup(bool enable) { if (!popup_) return; if (enable) { // Find the UI root element for showing the popup UIElement* root = GetRoot(); if (!root) return; OnShowPopup(); if (popup_->GetParent() != root) root->AddChild(popup_); popup_->SetPosition(GetScreenPosition() + popupOffset_); popup_->SetVisible(true); popup_->SetVar(originHash, (void*)this); popup_->BringToFront(); } else { // If the popup has child menus, hide their popups as well PODVector<UIElement*> children; popup_->GetChildren(children, true); for (PODVector<UIElement*>::ConstIterator i = children.Begin(); i != children.End(); ++i) { Menu* menu = dynamic_cast<Menu*>(*i); if (menu) menu->ShowPopup(false); } popup_->SetVar(originHash, Variant::EMPTY); popup_->SetVisible(false); popup_->Remove(); } showPopup_ = enable; selected_ = enable; }