예제 #1
0
        public static void UpdateLightProxy(MyLight light)
        {
            if ((!light.LightOn || light.LightType == MyLight.LightTypeEnum.None) && light.ProxyId != MyDynamicAABBTree.NullNode)
            {
                m_tree.RemoveProxy(light.ProxyId);
                light.ProxyId = MyDynamicAABBTree.NullNode;
            }

            BoundingBox bbox = BoundingBoxHelper.InitialBox;

            if (light.IsTypePoint || light.IsTypeHemisphere)
            {
                bbox = BoundingBox.CreateFromSphere(light.PointBoundingSphere);
            }
            if (light.IsTypeSpot)
            {
                var box = light.SpotBoundingBox;
                BoundingBoxHelper.AddBBox(box, ref bbox);
            }

            if (light.ProxyId == MyDynamicAABBTree.NullNode)
            {
                light.ProxyId = m_tree.AddProxy(ref bbox, light, 0);
            }
            else
            {
                m_tree.MoveProxy(light.ProxyId, ref bbox, Vector3.Zero);
            }
        }
예제 #2
0
        void UpdateMoneyStack()
        {
            //HashSet<GameObject> stacks = new HashSet<GameObject>();
            int totalStacksToShow = TotalMoney / 1000;

            while (_shownMoneyStacks < totalStacksToShow)
            {
                GameObject newBundle = GameObject.Instantiate("cashStack", transform.position + 0.5f * Vector3.Up, MyRandom.YRotation());
                //stacks.Add(newBundle);

                Vector3 size = BoundingBoxHelper.CalculateSize(newBundle.Model, newBundle.transform.scale);

                int     stackId = _shownMoneyStacks / BundlesPerStack;
                int     rowId   = stackId % ColumnsPerRow;
                int     colId   = stackId / ColumnsPerRow;
                Vector3 up      = (0.1f + (_shownMoneyStacks % BundlesPerStack) * size.Y) * Vector3.Up;
                Vector3 right   = (rowId * Margin + size.X * rowId) * Vector3.Right;
                Vector3 back    = (colId * Margin + size.Z * colId) * Vector3.Backward;

                newBundle.transform.position = transform.position + up + right + back;

                lock (lockList) {
                    _moneyGameObjects.Add(newBundle);
                    ++_shownMoneyStacks;
                }
                //await Time.WaitForSeconds(0.1f);
            }
        }
예제 #3
0
        void AddToActive(CollisionSkin cs, SkinTester st)
        {
            int   n      = active_.Count;
            float xMin   = cs.WorldBoundingBox.Min.X;
            bool  active = (cs.Owner != null) && cs.Owner.IsActive;

            for (int i = 0; i != n;)
            {
                CollisionSkin asi = active_[i];
                if (asi.WorldBoundingBox.Max.X < xMin)
                {
                    //  prune no longer interesting boxes from potential overlaps
                    --n;
                    active_.RemoveAt(i);
                }
                else
                {
                    bool active2 = active || (active_[i].Owner != null && asi.Owner.IsActive);
                    if (active2 && BoundingBoxHelper.OverlapTest(ref cs.WorldBoundingBox, ref asi.WorldBoundingBox))
                    {
                        if (active)
                        {
                            st.TestSkin(cs, asi);
                        }
                        else
                        {
                            st.TestSkin(asi, cs);
                        }
                    }
                    ++i;
                }
            }
            active_.Add(cs);
        }
예제 #4
0
        public WorstCouple GetWorstCouple(IEnumerable <ShapeItem <T> > items)
        {
            var worstCouple = new WorstCouple();

            var currentCoverArea = BoundingBoxHelper <T> .GetDiffCoveredArea(
                items.ElementAt(0).BoundingBox
                , items.ElementAt(1).BoundingBox);

            for (int i = 0; i < items.Count(); i++)
            {
                for (int l = 0; l < items.Count(); l++)
                {
                    if (l != i)
                    {
                        var coverArea = BoundingBoxHelper <T> .GetDiffCoveredArea(
                            items.ElementAt(i).BoundingBox
                            , items.ElementAt(l).BoundingBox);

                        if (coverArea.CompareTo(currentCoverArea) > 0)
                        {
                            currentCoverArea   = coverArea;
                            worstCouple.IndexA = i;
                            worstCouple.IndexB = l;
                        }
                    }
                }
            }

            return(worstCouple);
        }
예제 #5
0
        public virtual void Draw(GameTime gameTime)
        {
            foreach (MapTile tile in DrawnMap)
            {
                MapRender.Draw(
                    MapSpriteSheet.Sprite(CharToTile[tile.ModelChar]),
                    tile.Position,
                    0.1f,
                    Color.White,
                    0,
                    1,
                    SpriteEffects.None);
            }

            foreach (MapTile tile in DrawnMap)
            {
                if (tile.IsCollidable)
                {
                    if (DebugConstants.ShowBoundingBoxes)
                    {
                        BoundingBoxHelper.DrawRectangle(tile.BoundingBox, GlobalAssets.BBoxOutline, Color.White, MapBatch, false, 1);
                    }

                    if ((tile.IsBeingCollided || tile.IsBeingStoodOn) && DebugConstants.ShowCollisionOverlays)
                    {
                        BoundingBoxHelper.DrawRectangle(tile.BoundingBox, GlobalAssets.CollisionOverlay, Color.White, MapBatch, true, 1);
                    }
                }
            }
        }
예제 #6
0
        public BoundingBox GetAABB()
        {
            BoundingBox     box     = BoundingBoxHelper.InitialBox;
            BoundingFrustum frustum = ConvertToFrustum();

            BoundingBoxHelper.AddFrustum(ref frustum, ref box);
            return(box);
        }
예제 #7
0
        /// <summary>
        /// CollDetectBoxStaticMeshOverlap
        /// </summary>
        /// <param name="oldBox"></param>
        /// <param name="newBox"></param>
        /// <param name="mesh"></param>
        /// <param name="info"></param>
        /// <param name="collTolerance"></param>
        /// <param name="collisionFunctor"></param>
        /// <returns>bool</returns>
        private static bool CollDetectBoxStaticMeshOverlap(Box oldBox,
                                                           Box newBox,
                                                           TriangleMesh mesh,
                                                           ref CollDetectInfo info,
                                                           float collTolerance,
                                                           CollisionFunctor collisionFunctor)
        {
            float boxRadius = newBox.GetBoundingRadiusAroundCentre();

            #region REFERENCE: Vector3 boxCentre = newBox.GetCentre();
            Vector3 boxCentre;
            newBox.GetCentre(out boxCentre);
            // Deano need to trasnform the box center into mesh space
            Matrix invTransformMatrix = mesh.InverseTransformMatrix;
            Vector3.Transform(ref boxCentre, ref invTransformMatrix, out boxCentre);
            #endregion

            BoundingBox bb = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddBox(newBox, ref bb);

            bool collision = false;

            int[] potTriArray = IntStackAlloc();

            // aabox is done in mesh space and handles the mesh transform correctly
            int numTriangles = mesh.GetTrianglesIntersectingtAABox(potTriArray, MaxLocalStackTris, ref bb);

            for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
            {
                IndexedTriangle meshTriangle = mesh.GetTriangle(potTriArray[iTriangle]);

                // quick early test is done in mesh space
                float dist = meshTriangle.Plane.DotCoordinate(boxCentre);

                // BEN-BUG-FIX: Fixed by chaning 0.0F to -boxRadius.
                if (dist > boxRadius || dist < -boxRadius)
                {
                    continue;
                }

                if (DoOverlapBoxTriangleTest(
                        oldBox, newBox,
                        ref meshTriangle,
                        mesh,
                        ref info,
                        collTolerance,
                        collisionFunctor))
                {
                    collision = true;
                }
            }

            FreeStackAlloc(potTriArray);

            return(collision);
        }
        public void ShouldGet3Diff()
        {
            var rectangle = BoundingBoxHelper <Int32> .GetBoundingBox(3, 3);

            var rectangle2 = BoundingBoxHelper <Int32> .GetBoundingBox(4, 3);

            var diff = BoundingBoxHelper <Int32> .GetDiffCoveredArea(rectangle, rectangle2);

            Assert.AreEqual(3, diff);
        }
예제 #9
0
        // --------------------- CUSTOM METHODS ----------------


        // queries


        // other

        private Vector3 CalculateShadowSize(GameObject shadow)
        {
            Vector3 modelSize  = BoundingBoxHelper.CalculateSize(gameObject.Model, transform.scale);
            Vector3 shadowSize = BoundingBoxHelper.CalculateSize(shadow.Model, shadow.transform.scale);

            float xFactor = shadowSize.X / modelSize.X;
            float zFactor = shadowSize.Z / modelSize.Z;

            return(new Vector3(1.5f / xFactor, 1.0f, 1.5f / zFactor));
        }
예제 #10
0
        private static void CollDetectSweep(ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            var mesh = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as TriangleMesh;

            var oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box;
            var newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box;

            oldBox.GetCentre(out var oldCentre);
            newBox.GetCentre(out var newCentre);

            Vector3.Subtract(ref newCentre, ref oldCentre, out var delta);

            var boxMinLen  = 0.5f * System.Math.Min(newBox.SideLengths.X, System.Math.Min(newBox.SideLengths.Y, newBox.SideLengths.Z));
            var nPositions = 1 + (int)(delta.Length() / boxMinLen);

            if (nPositions > 50)
            {
                System.Diagnostics.Debug.WriteLine("Warning - clamping max positions in swept box test");
                nPositions = 50;
            }

            if (nPositions == 1)
            {
                CollDetectBoxStaticMeshOverlap(oldBox, newBox, mesh, ref info, collTolerance, collisionFunctor);
            }
            else
            {
                var bb = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddBox(oldBox, ref bb);
                BoundingBoxHelper.AddBox(newBox, ref bb);
                unsafe
                {
                    var potentialTriangles = stackalloc int[MaxLocalStackTris];
                    {
                        var numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);
                        if (numTriangles <= 0)
                        {
                            return;
                        }
                        for (var i = 0; i <= nPositions; ++i)
                        {
                            var frac = (float)i / nPositions;
                            Vector3.Multiply(ref delta, frac, out var centre);
                            Vector3.Add(ref centre, ref oldCentre, out centre);

                            var orient = Matrix.Add(Matrix.Multiply(oldBox.Orientation, 1.0f - frac), Matrix.Multiply(newBox.Orientation, frac));
                            var box    = new Box(centre - 0.5f * Vector3.TransformNormal(newBox.SideLengths, orient), orient, newBox.SideLengths);

                            CollDetectBoxStaticMeshOverlap(oldBox, box, mesh, ref info, collTolerance, collisionFunctor);
                        }
                    }
                }
            }
        }
예제 #11
0
        /// <summary>
        /// SegmentIntersect
        /// </summary>
        /// <param name="fracOut"></param>
        /// <param name="skinOut"></param>
        /// <param name="posOut"></param>
        /// <param name="normalOut"></param>
        /// <param name="seg"></param>
        /// <param name="collisionPredicate"></param>
        /// <returns>bool</returns>
        public override bool SegmentIntersect(out float fracOut, out CollisionSkin skinOut, out Microsoft.Xna.Framework.Vector3 posOut, out Microsoft.Xna.Framework.Vector3 normalOut, JigLibX.Geometry.Segment seg, CollisionSkinPredicate1 collisionPredicate)
        {
            fracOut = float.MaxValue;
            skinOut = null;
            posOut  = normalOut = Vector3.Zero;

            float   frac;
            Vector3 pos;
            Vector3 normal;

            Vector3 segmentBeginning = seg.Origin;
            Vector3 segmentEnd       = seg.Origin + seg.Delta;

            Vector3 min = Vector3.Min(segmentBeginning, segmentEnd);
            Vector3 max = Vector3.Max(segmentBeginning, segmentEnd);

            active_.Clear();

            BoundingBox box = new BoundingBox(min, max);

            Extract(min, max, active_);

            float distanceSquared = float.MaxValue;
            int   nActive         = active_.Count;

            for (int i = 0; i != nActive; ++i)
            {
                CollisionSkin skin = active_[i];
                if (collisionPredicate == null || collisionPredicate.ConsiderSkin(skin))
                {
                    if (BoundingBoxHelper.OverlapTest(ref box, ref skin.WorldBoundingBox))
                    {
                        if (skin.SegmentIntersect(out frac, out pos, out normal, seg))
                        {
                            if (frac >= 0)
                            {
                                float newDistanceSquared = Vector3.DistanceSquared(segmentBeginning, pos);
                                if (newDistanceSquared < distanceSquared)
                                {
                                    distanceSquared = newDistanceSquared;

                                    fracOut   = frac;
                                    skinOut   = skin;
                                    posOut    = pos;
                                    normalOut = normal;
                                }
                            }
                        }
                    }
                }
            }

            return(fracOut <= 1);
        }
        public void ShouldGet4x4Bb()
        {
            var rectangle = BoundingBoxHelper <Int32> .GetBoundingBox(3, 4);

            var rectangle2 = BoundingBoxHelper <Int32> .GetBoundingBox(4, 3);

            var coverdArea = (BoundingBox2D <Int32>)rectangle.GetCoveredBoundingbox(rectangle2);

            Assert.AreEqual(4, coverdArea.Width);
            Assert.AreEqual(4, coverdArea.Height);
        }
예제 #13
0
        static void UpdateBoundingFrustum()
        {
            //  Update frustum
            BoundingFrustum.Matrix = ViewProjectionMatrix;

            //  Update bounding box
            BoundingBox = new BoundingBox(new Vector3(float.PositiveInfinity), new Vector3(float.NegativeInfinity));
            BoundingBoxHelper.AddFrustum(ref BoundingFrustum, ref BoundingBox);

            //  Update bounding sphere
            BoundingSphere = MyUtils.GetBoundingSphereFromBoundingBox(ref BoundingBox);
        }
예제 #14
0
        private static void FindObjectsInDetectingArea()
        {
            // find max detector's range
            float range = Math.Max(DefaultRadarRange, MyHudConstants.RADAR_JAMMER_RANGE);

            Debug.Assert(m_objectsInDetectingArea.Count == 0);
            BoundingSphere sphereToDetecting = new BoundingSphere(GetRadarPosition(), range);
            BoundingBox    radarBoundingBox  = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSphere(ref sphereToDetecting, ref radarBoundingBox);
            MyEntities.GetElementsInBox(ref radarBoundingBox, m_objectsInDetectingArea);
        }
예제 #15
0
        protected void CutOutFromVoxel(MyVoxelMap voxelMap, ref BoundingSphere bigSphereForTunnel)
        {
            if (!IsDummy)
            {
                if (MyMultiplayerGameplay.IsRunning)
                {
                    MyMultiplayerGameplay.Static.CutOut(voxelMap, ref bigSphereForTunnel);
                }

                //remove decals
                MyDecals.HideTrianglesAfterExplosion(voxelMap, ref bigSphereForTunnel);

                //cut off
                MyVoxelGenerator.CutOutSphereFast(voxelMap, bigSphereForTunnel);


                if (MySession.Is25DSector)
                {
                    //  Create debris rocks thrown from the explosion
                    MyExplosionDebrisVoxel.CreateExplosionDebris(ref bigSphereForTunnel, 1, CommonLIB.AppCode.Networking.MyMwcVoxelMaterialsEnum.Ice_01, MinerWars.AppCode.Game.Managers.Session.MySession.PlayerShip.GroupMask, voxelMap);

                    BoundingBox boundingBox = BoundingBoxHelper.InitialBox;
                    BoundingBoxHelper.AddSphere(ref bigSphereForTunnel, ref boundingBox);

                    // we need local list because this method can be called from inside of the loop

                    var elements = MyEntities.GetElementsInBox(ref boundingBox);
                    foreach (var el in elements)
                    {
                        MyEntity entity = ((MinerWars.AppCode.Game.Physics.MyPhysicsBody)el.GetRigidBody().m_UserData).Entity;
                        MyExplosionDebrisVoxel debris = entity as MyExplosionDebrisVoxel;

                        if (debris == null)
                        {
                            continue;
                        }

                        Vector3 awayDirection = debris.GetPosition() - bigSphereForTunnel.Center;

                        debris.Physics.AddForce(
                            MinerWars.AppCode.Game.Physics.MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE,
                            awayDirection * MyExplosionsConstants.EXPLOSION_FORCE_RADIUS_MULTIPLIER * 100000,
                            bigSphereForTunnel.Center,
                            MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.GetRandomVector3Normalized() * 10000);
                    }

                    elements.Clear();
                }

                PlayVoxelCutCue();
            }
        }
예제 #16
0
        //  IMPORTANT: This struct must be initialized using this constructor, or by filling all four fields. It's because
        //  some code may need length or distance, and if they aren't calculated, we can have problems.
        public MyLine(Vector3 from, Vector3 to, bool calculateBoundingBox = true)
        {
            From      = from;
            To        = to;
            Direction = MyMwcUtils.Normalize(to - from);
            Vector3.Distance(ref to, ref from, out Length);

            //  Calculate line's bounding box, but only if we know we will need it
            BoundingBox = BoundingBoxHelper.InitialBox;
            if (calculateBoundingBox == true)
            {
                BoundingBoxHelper.AddLine(ref this, ref BoundingBox);
            }
        }
예제 #17
0
        public override bool SegmentIntersect(out float fracOut, out CollisionSkin skinOut, out Vector3 posOut, out Vector3 normalOut, Segment seg, CollisionSkinPredicate1 collisionPredicate)
        {
            fracOut = float.MaxValue;
            skinOut = null;
            posOut  = normalOut = Vector3.Zero;

            var segmentBeginning = seg.Origin;
            var segmentEnd       = seg.Origin + seg.Delta;

            var min = Vector3.Min(segmentBeginning, segmentEnd);
            var max = Vector3.Max(segmentBeginning, segmentEnd);

            active_.Clear();

            var box = new BoundingBox(min, max);

            Extract(min, max, active_);

            var distanceSquared = float.MaxValue;
            var nActive         = active_.Count;

            for (var i = 0; i != nActive; ++i)
            {
                var skin = active_[i];
                if (collisionPredicate == null || collisionPredicate.ConsiderSkin(skin))
                {
                    if (BoundingBoxHelper.OverlapTest(ref box, ref skin.WorldBoundingBox))
                    {
                        if (skin.SegmentIntersect(out var frac, out var pos, out var normal, seg))
                        {
                            if (frac >= 0)
                            {
                                var newDistanceSquared = Vector3.DistanceSquared(segmentBeginning, pos);
                                if (newDistanceSquared < distanceSquared)
                                {
                                    distanceSquared = newDistanceSquared;

                                    fracOut   = frac;
                                    skinOut   = skin;
                                    posOut    = pos;
                                    normalOut = normal;
                                }
                            }
                        }
                    }
                }
            }

            return(fracOut <= 1);
        }
        public bool GetIntersectionWithSphere(MyEntity physObject, ref BoundingSphere sphere)
        {
            //  Transform sphere from world space to object space
            Matrix         worldInv = physObject.GetWorldMatrixInverted();
            Vector3        positionInObjectSpace = MyUtils.GetTransform(sphere.Center, ref worldInv);
            BoundingSphere sphereInObjectSpace   = new BoundingSphere(positionInObjectSpace, sphere.Radius);

            var aabb = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSphere(ref sphereInObjectSpace, ref aabb);
            AABB gi_aabb = new AABB(ref aabb.Min, ref aabb.Max);

            m_overlappedTriangles.Clear();
            if (m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles))
            {
                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

                //  Triangles that are directly in this node
                for (int i = 0; i < m_overlappedTriangles.Count; i++)
                {
                    var triangleIndex = m_overlappedTriangles[i];

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphereInObjectSpace) == true)
                    {
                        //  See that we swaped vertex indices!!
                        MyTriangle_Vertexes     triangle;
                        MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                        triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                        triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                        triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);

                        MyPlane trianglePlane = new MyPlane(ref triangle);

                        if (MyUtils.GetSphereTriangleIntersection(ref sphereInObjectSpace, ref trianglePlane, ref triangle) != null)
                        {
                            //  If we found intersection we can stop and dont need to look further
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
예제 #19
0
        private void LoadWaypointEdges()
        {
            m_edges.Clear();

            BoundingBox bb = BoundingBoxHelper.InitialBox;

            foreach (var part in m_parts)
            {
                if (part != null)
                {
                    BoundingBoxHelper.AddBBox(part.WorldAABB, ref bb);
                }
            }

            m_edges.AddRange(MyWayPointGraph.GetAllEdgesInBox(ref bb));
        }
예제 #20
0
        }             // void

        public override bool SegmentIntersect(out float fracOut, out CollisionSkin skinOut, out Vector3 posOut, out Vector3 normalOut, Segment seg, CollisionSkinPredicate1 collisionPredicate)
        {
            int         numSkins = skins.Count;
            BoundingBox segBox   = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSegment(seg, ref segBox);

            //initialise the outputs
            fracOut = float.MaxValue;
            skinOut = null;
            posOut  = normalOut = Vector3.Zero;

            // working vars
            float   frac;
            Vector3 pos;
            Vector3 normal;

            for (int iskin = 0; iskin < numSkins; ++iskin)
            {
                CollisionSkin skin = skins[iskin];
                if ((collisionPredicate == null) ||
                    collisionPredicate.ConsiderSkin(skin))
                {
                    // basic bbox test
                    if (BoundingBoxHelper.OverlapTest(ref skin.WorldBoundingBox, ref segBox))
                    {
                        if (skin.SegmentIntersect(out frac, out pos, out normal, seg))
                        {
                            if (frac < fracOut)
                            {
                                posOut    = pos;
                                normalOut = normal;
                                skinOut   = skin;
                                fracOut   = frac;
                            }
                        }
                    }
                }
            }

            if (fracOut > 1.0f)
            {
                return(false);
            }
            fracOut = MathHelper.Clamp(fracOut, 0.0f, 1.0f);
            return(true);
        }
예제 #21
0
파일: Picker.cs 프로젝트: bartwe/Gearset
        public override void Draw(GameTime gameTime)
        {
            // Only draw if we're doing a BasicEffectPass pass
            if (GearsetResources.CurrentRenderPass != RenderPass.BasicEffectPass)
            {
                return;
            }

            if (_hoveringObject is IPickable <BoundingBox> )
            {
                BoundingBoxHelper.DrawBoundingBox(((IPickable <BoundingBox>)_hoveringObject).PickableVolume, Color.Gray);
            }
            if (_selectedObject is IPickable <BoundingBox> )
            {
                BoundingBoxHelper.DrawBoundingBox(((IPickable <BoundingBox>)_selectedObject).PickableVolume, Color.White);
            }
        }
        public void Draw(GameTime deltaTime, Entity entity)
        {
            var currentFrame = _currentAnimation.GetCurrentFrame();

            _spriteRender.Draw(currentFrame.SpriteFrame,
                               new Vector2(entity.Position.X, entity.Position.Y),
                               .5f,
                               Color.White,
                               rotation: 0,
                               scale: entity.Scale,
                               spriteEffects: currentFrame.SpriteEffect);

            if (DebugConstants.ShowBoundingBoxes)
            {
                BoundingBoxHelper.DrawRectangle(entity.BoundingBox, GlobalAssets.BBoxOutline, Color.White, _spriteBatch, false, 1);
            }
        }
예제 #23
0
        public override bool SegmentIntersect(out float fracOut, out CollisionSkin skinOut, out Microsoft.Xna.Framework.Vector3 posOut, out Microsoft.Xna.Framework.Vector3 normalOut, JigLibX.Geometry.Segment seg, CollisionSkinPredicate1 collisionPredicate)
        {
            fracOut = float.MaxValue;
            skinOut = null;
            posOut  = normalOut = Vector3.Zero;

            Vector3 min = seg.GetPoint(0);
            Vector3 tmp = seg.GetEnd();
            Vector3 max;

            Vector3.Max(ref min, ref tmp, out max);
            Vector3.Min(ref min, ref tmp, out min);

            BoundingBox box = new BoundingBox(min, max);
            float       frac;
            Vector3     pos;
            Vector3     normal;

            active_.Clear();
            Extract(min, max, active_);

            int nActive = active_.Count;

            for (int i = 0; i != nActive; ++i)
            {
                CollisionSkin skin = active_[i];
                if (collisionPredicate == null || collisionPredicate.ConsiderSkin(skin))
                {
                    if (BoundingBoxHelper.OverlapTest(ref box, ref skin.WorldBoundingBox))
                    {
                        if (skin.SegmentIntersect(out frac, out pos, out normal, seg))
                        {
                            if (frac >= 0 && frac < fracOut)
                            {
                                fracOut   = frac;
                                skinOut   = skin;
                                posOut    = pos;
                                normalOut = normal;
                            }
                        }
                    }
                }
            }
            return(fracOut <= 1);
        }
예제 #24
0
        public static RNode <T> GetLessEnlargementNode(IEnumerable <RNode <T> > nodes, IBoundingBox <T> item)
        {
            var nextNode   = nodes.First();
            var coverdArea = nextNode.BoundingBox.GetCoveredBoundingbox(item);
            var diff       = BoundingBoxHelper <T> .Substract(coverdArea.GetArea(), nextNode.BoundingBox.GetArea());

            //get node by trying to get the less enlargement
            for (int i = 1; i < nodes.Count(); i++)
            {
                var diff2 = BoundingBoxHelper <T> .GetDiffCoveredArea(item, nodes.ElementAt(i).BoundingBox);

                if (diff2.CompareTo(diff) < 0)
                {
                    nextNode = nodes.ElementAt(i);
                }
            }
            return(nextNode);
        }
예제 #25
0
        private static bool CollDetectBoxStaticMeshOverlap(Box oldBox, Box newBox, TriangleMesh mesh, ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            var boxRadius = newBox.GetBoundingRadiusAroundCentre();

            newBox.GetCentre(out var boxCentre);

            var invTransformMatrix = mesh.InverseTransformMatrix;

            Vector3.Transform(ref boxCentre, ref invTransformMatrix, out boxCentre);

            var bb = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddBox(newBox, ref bb);

            unsafe
            {
                var collision          = false;
                var potentialTriangles = stackalloc int[MaxLocalStackTris];
                {
                    var numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                    for (var iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                    {
                        var meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);


                        var dist = meshTriangle.Plane.DotCoordinate(boxCentre);


                        if (dist > boxRadius || dist < -boxRadius)
                        {
                            continue;
                        }

                        if (DoOverlapBoxTriangleTest(oldBox, newBox, ref meshTriangle, mesh, ref info, collTolerance, collisionFunctor))
                        {
                            collision = true;
                        }
                    }
                }
                return(collision);
            }
        }
예제 #26
0
        /// <summary>
        /// Updates bounding volume of this skin
        /// </summary>
        public void UpdateWorldBoundingBox()
        {
            BoundingBox temp = BoundingBoxHelper.InitialBox;

            for (int iold = primitivesOldWorld.Count; iold-- != 0;)
            {
                BoundingBoxHelper.AddPrimitive(primitivesOldWorld[iold], ref temp);
            }

            if (collSystem != null && collSystem.UseSweepTests)
            {
                for (int inew = primitivesNewWorld.Count; inew-- != 0;)
                {
                    BoundingBoxHelper.AddPrimitive(primitivesNewWorld[inew], ref temp);
                }
            }
            WorldBoundingBox = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddBBox(temp, ref WorldBoundingBox);
        }
예제 #27
0
        private static List <UtmSheet> GetIndexSheets(BoundingBox geographicIntersectRegion, double utmWidth, double utmHeight, UtmIndexType type, int utmZone)
        {
            var geoBound = BoundingBoxHelper.UtmMbbToGeodeticWgs84Mbb(_2kUtmBoudingBox, utmZone)
                           .Intersect(geographicIntersectRegion);

            List <UtmSheet> result = new List <UtmSheet>();

            if (geoBound.IsNaN())
            {
                return(result);
            }

            var utmBound = BoundingBoxHelper.GeodeticWgs84MbbToUtmMbb(geoBound, utmZone)
                           .Intersect(_2kUtmBoudingBox);

            if (utmBound.IsNaN())
            {
                return(result);
            }

            int iStart = (int)Math.Floor((utmBound.XMin - _2kUtmXmin) / utmWidth);

            int iEnd = (int)Math.Ceiling((utmBound.XMax - _2kUtmXmin) / utmWidth);

            int jStart = (int)Math.Floor((utmBound.YMin - _2kUtmYmin) / utmHeight);

            int jEnd = (int)Math.Ceiling((utmBound.YMax - _2kUtmYmin) / utmHeight);

            for (int i = iStart; i < iEnd; i++)
            {
                for (int j = jStart; j < jEnd; j++)
                {
                    var startX = _2kUtmXmin + i * utmWidth;

                    var startY = _2kUtmYmin + j * utmHeight;

                    result.Add(UtmSheet.Create(new BoundingBox(startX, startY, startX + utmWidth, startY + utmHeight), type, utmZone));
                }
            }

            return(result);
        }
예제 #28
0
        /// <summary>
        /// Calculate the tightest bounding-shape with the given <paramref name="type"/>
        /// </summary>
        /// <param name="type">Type of the bounding-shape</param>
        protected virtual void CalculateShape(ShapeType type)
        {
            Model       model  = gameObject.Model;
            BoundingBox bb     = BoundingBoxHelper.Calculate(model);
            JVector     bbSize = Conversion.ToJitterVector(bb.Max - bb.Min);

            bbSize = new JVector(
                bbSize.X * Size.X * gameObject.transform.scale.X,
                bbSize.Y * Size.Y * gameObject.transform.scale.Y,
                bbSize.Z * Size.Z * gameObject.transform.scale.Z
                );

            JVector com = 0.5f * Conversion.ToJitterVector(bb.Max + bb.Min);

            CenterOfMass = new JVector(com.X * gameObject.transform.scale.X,
                                       com.Y * gameObject.transform.scale.Y,
                                       com.Z * gameObject.transform.scale.Z);

            float maxDimension = MathHelper.Max(bbSize.X, MathHelper.Max(bbSize.Y, bbSize.Z));

            switch (type)
            {
            case ShapeType.Sphere:
                CollisionShape = new SphereShape(maxDimension);
                break;

            case ShapeType.BoxUniform:
                CollisionShape = new BoxShape(maxDimension, maxDimension, maxDimension);
                break;

            case ShapeType.Box:
            case ShapeType.BoxInvisible:
                CollisionShape = new BoxShape(bbSize);
                break;
            }
        }
예제 #29
0
        private void CollDetectSweep(ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            // todo - proper swept test
            // note - mesh is static and its triangles are in world space
            TriangleMesh mesh = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as TriangleMesh;

            Box oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box;
            Box newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box;

            Vector3 oldCentre;

            oldBox.GetCentre(out oldCentre);
            Vector3 newCentre;

            newBox.GetCentre(out newCentre);

            Vector3 delta;

            Vector3.Subtract(ref newCentre, ref oldCentre, out delta);

            float boxMinLen  = 0.5f * System.Math.Min(newBox.SideLengths.X, System.Math.Min(newBox.SideLengths.Y, newBox.SideLengths.Z));
            int   nPositions = 1 + (int)(delta.Length() / boxMinLen);

            // limit the max positions...
            if (nPositions > 50)
            {
                System.Diagnostics.Debug.WriteLine("Warning - clamping max positions in swept box test");
                nPositions = 50;
            }
            if (nPositions == 1)
            {
                CollDetectBoxStaticMeshOverlap(oldBox, newBox, mesh, ref info, collTolerance, collisionFunctor);
            }
            else
            {
                BoundingBox bb = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddBox(oldBox, ref bb);
                BoundingBoxHelper.AddBox(newBox, ref bb);
                unsafe
                {
#if USE_STACKALLOC
                    int *potentialTriangles = stackalloc int[MaxLocalStackTris];
                    {
#else
                    int[] potTriArray = IntStackAlloc();
                    fixed(int *potentialTriangles = potTriArray)
                    {
#endif
                        int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);
                        if (numTriangles > 0)
                        {
                            for (int i = 0; i <= nPositions; ++i)
                            {
                                float   frac = ((float)i) / nPositions;
                                Vector3 centre;
                                Vector3.Multiply(ref delta, frac, out centre);
                                Vector3.Add(ref centre, ref oldCentre, out centre);

                                Matrix orient = Matrix.Add(Matrix.Multiply(oldBox.Orientation, 1.0f - frac), Matrix.Multiply(newBox.Orientation, frac));

                                Box box = new Box(centre - 0.5f * Vector3.Transform(newBox.SideLengths, orient), orient, newBox.SideLengths);
                                // ideally we'd break if we get one collision... but that stops us getting multiple collisions
                                // when we enter a corner (two walls meeting) - can let us pass through
                                CollDetectBoxStaticMeshOverlap(oldBox, box, mesh, ref info, collTolerance, collisionFunctor);
                            }
                        }
#if USE_STACKALLOC
                    }
#else
                    }
                    FreeStackAlloc(potTriArray);
#endif
                }
            }
        }
예제 #30
0
        public void OverlapAllLineSegment <T>(ref MyLine line, List <MyLineSegmentOverlapResult <T> > elementsList, uint requiredFlags)
        {
            MyPerformanceCounter.PerCameraDraw.StartTimer("DAABB");
            MyPerformanceCounter.PerCameraDraw.Increment("DAABB Queries line");

            elementsList.Clear();

            if (_root == NullNode)
            {
                MyPerformanceCounter.PerCameraDraw.StopTimer("DAABB");
                return;
            }

            using (m_rwLock.AcquireSharedUsing())
            {
                Stack <int> stack = GetStack();
                stack.Push(_root);

                BoundingBox bbox = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddLine(ref line, ref bbox);

                var ray = new Ray(line.From, line.Direction);

                while (stack.Count > 0)
                {
                    int nodeId = stack.Pop();
                    if (nodeId == NullNode)
                    {
                        continue;
                    }

                    DynamicTreeNode node = _nodes[nodeId];

                    if (node.Aabb.Intersects(bbox))
                    {
                        float?distance = node.Aabb.Intersects(ray);
                        if (distance.HasValue && distance.Value <= line.Length && distance.Value >= 0)
                        {
                            if (node.IsLeaf())
                            {
                                uint flags = GetUserFlag(nodeId);
                                if ((flags & requiredFlags) == requiredFlags)
                                {
                                    elementsList.Add(new MyLineSegmentOverlapResult <T>
                                    {
                                        Element  = GetUserData <T>(nodeId),
                                        Distance = distance.Value
                                    });
                                }
                            }
                            else
                            {
                                stack.Push(node.Child1);
                                stack.Push(node.Child2);
                            }
                        }
                    }
                }

                PushStack(stack);
            }
            MyPerformanceCounter.PerCameraDraw.StopTimer("DAABB");
        }