Beispiel #1
0
        private void PrepareQueryObject(EntityCollidable queryObject, ref System.Numerics.Vector3 position)
        {
            RigidTransform transform;

            transform.Position    = position;
            transform.Orientation = characterBody.Orientation;
            queryObject.UpdateBoundingBoxForTransform(ref transform, 0);
        }
Beispiel #2
0
        private void QueryContacts(Vector3 position, EntityCollidable queryObject)
        {
            this.ClearContacts();

            //Update the position and orientation of the query object.
            RigidTransform transform;

            transform.Position    = position;
            transform.Orientation = this.character.Body.Orientation;
            queryObject.UpdateBoundingBoxForTransform(ref transform, 0);

            foreach (var collidable in this.character.Body.CollisionInformation.OverlappedCollidables)
            {
                if (collidable.BoundingBox.Intersects(queryObject.BoundingBox))
                {
                    var pair        = new CollidablePair(collidable, queryObject);
                    var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
                    if (pairHandler.CollisionRule == CollisionRule.Normal)
                    {
                        pairHandler.SuppressEvents = true;
                        pairHandler.UpdateCollision(0);
                        pairHandler.SuppressEvents = false;

                        foreach (var contact in pairHandler.Contacts)
                        {
                            //Must check per-contact collision rules, just in case
                            //the pair was actually a 'parent pair.'
                            if (contact.Pair.CollisionRule == CollisionRule.Normal)
                            {
                                ContactData contactData;
                                contactData.Position         = contact.Contact.Position;
                                contactData.Normal           = contact.Contact.Normal;
                                contactData.Id               = contact.Contact.Id;
                                contactData.PenetrationDepth = contact.Contact.PenetrationDepth;
                                this.contacts.Add(contactData);
                            }
                        }
                    }
                    //TODO: It would be nice if this was a bit easier.
                    //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving.
                    //No one would ever just guess this correctly.
                    //At least hide it behind a NarrowPhaseHelper function.
                    pairHandler.CleanUp();
                    pairHandler.Factory.GiveBack(pairHandler);
                }
            }

            this.CategorizeContacts(ref position);
        }
Beispiel #3
0
 public override void SpawnBody()
 {
     PreHandleSpawn();
     base.SpawnBody();
     if (mode == ModelCollisionMode.PRECISE)
     {
         Offset = InternalOffset;
     }
     BEPUutilities.Vector3 offs = Offset.ToBVector();
     transform = Matrix4d.CreateTranslation(ClientUtilities.ConvertD(Offset));
     List<BEPUutilities.Vector3> tvecs = TheClient.Models.Handler.GetVertices(model.Original);
     if (tvecs.Count == 0)
     {
         ModelMin = new BEPUutilities.Vector3(0, 0, 0);
         ModelMax = new BEPUutilities.Vector3(0, 0, 0);
     }
     else
     {
         ModelMin = tvecs[0];
         ModelMax = tvecs[0];
         foreach (BEPUutilities.Vector3 vec in tvecs)
         {
             BEPUutilities.Vector3 tvec = vec + offs;
             if (tvec.X < ModelMin.X) { ModelMin.X = tvec.X; }
             if (tvec.Y < ModelMin.Y) { ModelMin.Y = tvec.Y; }
             if (tvec.Z < ModelMin.Z) { ModelMin.Z = tvec.Z; }
             if (tvec.X > ModelMax.X) { ModelMax.X = tvec.X; }
             if (tvec.Y > ModelMax.Y) { ModelMax.Y = tvec.Y; }
             if (tvec.Z > ModelMax.Z) { ModelMax.Z = tvec.Z; }
         }
     }
     if (GenBlockShadows)
     {
         double tx = ModelMax.X - ModelMin.X;
         double ty = ModelMax.Y - ModelMin.Y;
         BoxShape bs = new BoxShape(tx, ty, ModelMax.Z - ModelMin.Z);
         EntityCollidable tempCast = bs.GetCollidableInstance();
         tempCast.LocalPosition = (ModelMax + ModelMin) * 0.5f + Body.Position;
         RigidTransform def = RigidTransform.Identity;
         tempCast.UpdateBoundingBoxForTransform(ref def);
         ShadowCastShape = tempCast.BoundingBox;
         BEPUutilities.Vector3 size = ShadowCastShape.Max - ShadowCastShape.Min;
         ShadowRadiusSquaredXY = size.X * size.X + size.Y * size.Y;
     }
 }
Beispiel #4
0
        public bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweepnorm, double slen, MaterialSolidity solidness, out RayHit hit)
        {
            RigidTransform rot = new RigidTransform(Vector3.Zero, startingTransform.Orientation);

            castShape.GetBoundingBox(ref rot, out BoundingBox 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()))
                            {
                                EntityShape es = BlockShapeRegistry.BSD[bi.BlockData].GetShape(bi.Damage, out Location 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);
                                RigidTransform adjusted = new RigidTransform(startingTransform.Position - adj, startingTransform.Orientation);
                                bool           b        = coll.ConvexCast(castShape, ref adjusted, ref sweep, out RayHit 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);
        }