MCPcopy Create free account
hub / github.com/OpenStarbound/OpenStarbound / updateForceRegions

Method updateForceRegions

source/game/StarMovementController.cpp:737–802  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

735}
736
737void MovementController::updateForceRegions(float) {
738 auto geometry = world()->geometry();
739 auto pos = position();
740 auto body = collisionBody();
741 RectF boundBox = body.boundBox();
742
743 m_appliedForceRegion = false;
744 auto handleForceRegions = [&](List<PhysicsForceRegion> const& forces) {
745 for (auto const& force : forces) {
746 bool categoryCheck = force.call([myCategories = m_parameters.physicsEffectCategories.value()](auto& fr) {
747 return fr.categoryFilter.check(myCategories);
748 });
749 if (!categoryCheck)
750 continue;
751
752 bool boundsCheck = force.call([geometry, myBounds = collisionBoundBox()](auto& fr) {
753 return geometry.rectIntersectsRect(myBounds, fr.boundBox());
754 });
755 if (!boundsCheck)
756 continue;
757
758 m_appliedForceRegion = true;
759 if (auto directionalForceRegion = force.ptr<DirectionalForceRegion>()) {
760 float forceEffect = geometry.polyOverlapArea(directionalForceRegion->region, body) / body.convexArea();
761 if (directionalForceRegion->xTargetVelocity)
762 approachXVelocity(*directionalForceRegion->xTargetVelocity, directionalForceRegion->controlForce * forceEffect);
763 if (directionalForceRegion->yTargetVelocity)
764 approachYVelocity(*directionalForceRegion->yTargetVelocity, directionalForceRegion->controlForce * forceEffect);
765
766 } else if (auto radialForceRegion = force.ptr<RadialForceRegion>()) {
767 Vec2F direction = geometry.diff(pos, radialForceRegion->center);
768 float distance = vmag(direction);
769 if (distance > 0 && distance < radialForceRegion->outerRadius) {
770 float incidence = min(1.0f - (distance - radialForceRegion->innerRadius) / (radialForceRegion->outerRadius - radialForceRegion->innerRadius), distance / radialForceRegion->innerRadius);
771 if (radialForceRegion->targetRadialVelocity < 0)
772 direction = -direction;
773 approachVelocityAlongAngle(direction.angle(),
774 abs(radialForceRegion->targetRadialVelocity),
775 radialForceRegion->controlForce * incidence,
776 true);
777 }
778 } else if (auto gradientForceRegion = force.ptr<GradientForceRegion>()) {
779 float overlapFactor = geometry.polyOverlapArea(gradientForceRegion->region, body) / body.convexArea();
780
781 Vec2F gNorm = gradientForceRegion->gradient.direction();
782 Vec2F pDiff = geometry.diff(pos, gradientForceRegion->gradient.min());
783 float projected = pDiff[0] * gNorm[0] + pDiff[1] * gNorm[1];
784 float gradientFactor = 1.0 - clamp(projected / gradientForceRegion->gradient.length(), -1.0f, 1.0f);
785
786 approachVelocityAlongAngle(gradientForceRegion->gradient.angle(),
787 gradientForceRegion->baseTargetVelocity * overlapFactor * gradientFactor,
788 gradientForceRegion->baseControlForce * overlapFactor * gradientFactor,
789 true);
790 }
791 }
792 };
793
794 for (auto& physicsEntity : world()->query<PhysicsEntity>(boundBox)) {

Callers

nothing calls this directly

Calls 15

vmagFunction · 0.85
clampFunction · 0.85
callMethod · 0.80
rectIntersectsRectMethod · 0.80
polyOverlapAreaMethod · 0.80
convexAreaMethod · 0.80
entityIdMethod · 0.80
geometryMethod · 0.45
boundBoxMethod · 0.45
valueMethod · 0.45
checkMethod · 0.45
diffMethod · 0.45

Tested by

no test coverage detected