public ApplyImpulse ( Vector3 location, Vector3 impulse ) : void | ||
location | Vector3 | Location to apply the impulse. |
impulse | Vector3 | Impulse to apply. |
Résultat | void |
/// <summary> /// Maintains the position of the character's body above the ground. /// </summary> /// <param name="supportLocationVelocity">Velocity of the support point connected to the supportEntity.</param> /// <param name="supportNormal">The normal at the surface where the ray hit the entity.</param> /// <param name="supportDistance">Distance from the character to the support location.</param> private void support(Vector3 supportLocationVelocity, Vector3 supportNormal, float supportDistance, float dt) { //Put the character at the right distance from the ground. float supportVerticalVelocity = Math.Max(supportLocationVelocity.Y, -0.1f); float heightDifference = this.SupportHeight - supportDistance; this.Body.Position += (new Vector3(0, MathHelper.Clamp(heightDifference, (supportVerticalVelocity - 10.0f) * dt, (supportVerticalVelocity + 10.0f) * dt), 0)); //Remove from the character velocity which would push it toward or away from the surface. //This is a relative velocity, so the velocity of the body and the velocity of a point on the support entity must be found. float bodyNormalVelocity = Vector3.Dot(this.Body.LinearVelocity, supportNormal); float supportEntityNormalVelocity = Vector3.Dot(supportLocationVelocity, supportNormal); Vector3 diff = (bodyNormalVelocity - supportEntityNormalVelocity) * -supportNormal; diff.Y = Math.Max(diff.Y, 0); this.Body.LinearVelocity += diff; BEPUphysics.Entities.Entity supportEntity = this.SupportEntity; if (supportEntity != null && supportEntity.IsAffectedByGravity) { Vector3 supportLocation = this.SupportLocation; Vector3 impulse = (this.Body.Mass * 1.5f) * ((Space)this.Space).ForceUpdater.Gravity * dt; supportEntity.ApplyImpulse(ref supportLocation, ref impulse); supportEntity.ActivityInformation.Activate(); } }
void ApplyLiquidForcesTo(Entity e, double dt) { if (e.Mass <= 0) { return; } Location min = new Location(e.CollisionInformation.BoundingBox.Min); Location max = new Location(e.CollisionInformation.BoundingBox.Max); min = min.GetBlockLocation(); max = max.GetUpperBlockBorder(); for (int x = (int)min.X; x < max.X; x++) { for (int y = (int)min.Y; y < max.Y; y++) { for (int z = (int)min.Z; z < max.Z; z++) { Location c = new Location(x, y, z); Material mat = (Material)TheRegion.GetBlockInternal(c).BlockMaterial; if (mat.GetSolidity() != MaterialSolidity.LIQUID) { continue; } // TODO: Account for block shape? double vol = e.CollisionInformation.Shape.Volume; double dens = (e.Mass / vol); double WaterDens = 5; // TODO: Read from material. // TODO: Sanity of values. float modifier = (float)(WaterDens / dens); float submod = 0.125f; // TODO: Tracing accuracy! Vector3 impulse = -(TheRegion.PhysicsWorld.ForceUpdater.Gravity + TheRegion.GravityNormal.ToBVector() * 0.4f) * e.Mass * dt * modifier * submod; // TODO: Don't apply smaller logic this if scale is big! for (float x2 = 0.25f; x2 < 1; x2 += 0.5f) { for (float y2 = 0.25f; y2 < 1; y2 += 0.5f) { for (float z2 = 0.25f; z2 < 1; z2 += 0.5f) { Location lc = c + new Location(x2, y2, z2); RayHit rh; if (e.CollisionInformation.RayCast(new Ray(lc.ToBVector(), new Vector3(0, 0, 1)), 0.01f, out rh)) // TODO: Efficiency! { Vector3 center = lc.ToBVector(); e.ApplyImpulse(ref center, ref impulse); e.ModifyLinearDamping(mat.GetSpeedMod()); e.ModifyAngularDamping(mat.GetSpeedMod()); } } } } } } } }
public override void ApplyImpulse(Vector3 position, Vector3 force) { entity.ApplyImpulse(position, force); }