示例#1
0
        public bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweepnorm, double slen, MaterialSolidity solidness, out RayHit hit)
        {
            BoundingBox    bb;
            RigidTransform rot = new RigidTransform(Vector3.Zero, startingTransform.Orientation);

            castShape.GetBoundingBox(ref rot, out bb);
            double  adv    = 0.1f;
            double  max    = slen + adv;
            bool    gotOne = false;
            RayHit  BestRH = default(RayHit);
            Vector3 sweep  = sweepnorm * slen;

            for (double f = 0; f < max; f += adv)
            {
                Vector3 c  = startingTransform.Position + sweepnorm * f;
                int     mx = (int)Math.Ceiling(c.X + bb.Max.X);
                for (int x = (int)Math.Floor(c.X + bb.Min.X); x <= mx; x++)
                {
                    if (x < 0 || x >= ChunkSize.X)
                    {
                        continue;
                    }
                    int my = (int)Math.Ceiling(c.Y + bb.Max.Y);
                    for (int y = (int)Math.Floor(c.Y + bb.Min.Y); y <= my; y++)
                    {
                        if (y < 0 || y >= ChunkSize.Y)
                        {
                            continue;
                        }
                        int mz = (int)Math.Ceiling(c.Z + bb.Max.Z);
                        for (int z = (int)Math.Floor(c.Z + bb.Min.Z); z <= mz; z++)
                        {
                            if (z < 0 || z >= ChunkSize.Z)
                            {
                                continue;
                            }
                            BlockInternal bi = Blocks[BlockIndex(x, y, z)];
                            if (solidness.HasFlag(((Material)bi.BlockMaterial).GetSolidity()))
                            {
                                Location    offs;
                                EntityShape es = BlockShapeRegistry.BSD[bi.BlockData].GetShape(bi.Damage, out offs, false);
                                if (es == null)
                                {
                                    continue;
                                }
                                Vector3          adj  = new Vector3(x + (double)offs.X, y + (double)offs.Y, z + (double)offs.Z);
                                EntityCollidable coll = es.GetCollidableInstance();
                                //coll.LocalPosition = adj;
                                RigidTransform rt = new RigidTransform(Vector3.Zero, Quaternion.Identity);
                                coll.LocalPosition  = Vector3.Zero;
                                coll.WorldTransform = rt;
                                coll.UpdateBoundingBoxForTransform(ref rt);
                                RayHit         rhit;
                                RigidTransform adjusted = new RigidTransform(startingTransform.Position - adj, startingTransform.Orientation);
                                bool           b        = coll.ConvexCast(castShape, ref adjusted, ref sweep, out rhit);
                                if (b && (!gotOne || rhit.T * slen < BestRH.T) && rhit.T >= 0)
                                {
                                    gotOne           = true;
                                    BestRH           = rhit;
                                    BestRH.Location += adj;
                                    BestRH.T        *= slen;           // TODO: ???
                                    BestRH.Normal    = -BestRH.Normal; // TODO: WHY?!
                                }
                            }
                        }
                    }
                }
                if (gotOne)
                {
                    hit = BestRH;
                    return(true);
                }
            }
            hit = new RayHit()
            {
                Location = startingTransform.Position + sweep, Normal = new Vector3(0, 0, 0), T = slen
            };
            return(false);
        }