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); }