Exemplo n.º 1
0
        void ApplyLiquidForcesTo(Entity e, double dt)
        {
            if (e.Mass <= 0)
            {
                return;
            }
            RigidTransform ert = new RigidTransform(e.Position, e.Orientation);
            BoundingBox    entbb;

            e.CollisionInformation.Shape.GetBoundingBox(ref ert, out entbb);
            Location min = new Location(entbb.Min);
            Location max = new Location(entbb.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_NoLoad(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.
                        double modifier  = (double)(WaterDens / dens);
                        double 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 (double x2 = 0.25f; x2 < 1; x2 += 0.5f)
                        {
                            for (double y2 = 0.25f; y2 < 1; y2 += 0.5f)
                            {
                                for (double 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());
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }