Beispiel #1
0
        /// <summary>
        /// Inserts a node into the tree and returns "true" for success or "false" for failure.
        /// </summary>
        /// <param name="obj">the object to insert</param>
        /// <returns>"true" for success, "false" for failure</returns>
        public bool Insert(I3DObject obj)
        {
            var location = GetLocation(obj);

            switch (location)
            {
            case ObjectLocation.None:
                return(false);

            case ObjectLocation.Child:
                if (_children == null)
                {
                    _children = CreateChildren();
                }
                return(_children.Select(x => x.Insert(obj)).Aggregate((a, b) => a || b));

            case ObjectLocation.Self:
                var tmpList = new List <I3DObject>(_objects)
                {
                    obj
                };
                _objects = tmpList.ToArray();
                return(true);
            }
            throw new Exception("Unknown ObjectLocation");
        }
Beispiel #2
0
 public void Add(I3DObject o)
 {
     if (!Root.Insert(o, o.GetBoundingSphere()))
     {
         throw new Exception("Could not insert: " + o);
     }
 }
Beispiel #3
0
        public int Add(BoxSpecs box, int level = 0, int location = 0)
        {
            I3DObject shape = CreateBox(box);

            if (level > 0 && location > 0)
            {
                bool succesfullAdd = facility[level, location].TryAdd(shape);
                if (succesfullAdd)
                {
                    return(shape.Id);
                }
                return(-1);
            }

            for (int levels = 1; level < facility.GetLength(0); level++)
            {
                for (int locations = 1; locations < facility.GetLength(1); locations++)
                {
                    if (facility[levels, locations].TryAdd(shape))
                    {
                        return(shape.Id);
                    }
                }
            }
            return(-1);
        }
Beispiel #4
0
        public void Render()
        {
            Canvas.ClearObjects();

            DrawGrid();

            foreach (I3DObject o in Scene.DrawList)
            {
                I3DObject or = o;
                if (YRotation != 0)
                {
                    or = or.RotateXZ(YRotation);
                }
                if (XRotation != 0)
                {
                    or = or.RotateXY(XRotation);
                }
                if (ZRotation != 0)
                {
                    or = or.RotateYZ(ZRotation);
                }

                or.Render(this);
            }
        }
Beispiel #5
0
        protected override void RenderVertices(I3DObject obj)
        {
            BE.Alpha   = obj.Alpha;
            BE.Texture = obj.Texture;

            base.RenderVertices(obj);
        }
Beispiel #6
0
        protected virtual void RenderVertices(I3DObject obj)
        {
            ApplyPass(obj);

            GameInstanceProvider.Instance.GraphicsDevice.Indices = obj.IndexBuffer;
            GameInstanceProvider.Instance.GraphicsDevice.SetVertexBuffer(obj.VertexBuffer);
            GameInstanceProvider.Instance.GraphicsDevice.DrawIndexedPrimitives(_primitiveType, 0, 0, obj.IndexBuffer.IndexCount / 3);
        }
Beispiel #7
0
        public new double GetReflectivityAt(Vect3 hitPoint)
        {
            I3DObject ret = GetObjectAt(hitPoint);

            if (ret != null)
            {
                return(ret.GetReflectivityAt(hitPoint));
            }
            throw new Exception("internal error!");
        }
Beispiel #8
0
        public new Color GetColorAt(Vect3 hitPoint)
        {
            I3DObject ret = GetObjectAt(hitPoint);

            if (ret != null)
            {
                return(ret.GetColorAt(hitPoint));
            }
            throw new Exception("internal error!");
        }
Beispiel #9
0
        public override Vect3 GetNormalAt(Vect3 hitPoint)
        {
            I3DObject ret = GetObjectAt(hitPoint);

            if (ret != null)
            {
                return(ret.GetNormalAt(hitPoint));
            }
            throw new Exception("internal error!");
        }
Beispiel #10
0
 public void CheckCollisionSet(List <I3DObject> objects, Shapes.Ray ray)
 {
     foreach (I3DObject candidate in objects)
     {
         double distanceCandidate = candidate.GetHitPointDistance(ray);
         if (distanceCandidate > Constants.EPS && distanceCandidate < Distance)
         {
             Obj      = candidate;
             Distance = distanceCandidate;
         }
     }
 }
 public static ObjectCategory Create(I3DObject obj)
 {
     return(new ObjectCategory
     {
         IsVisible = obj.IsVisible,
         BlendStateId = GetBlendStateId(obj.BlendState),
         IsVisualObject = obj.IsVisualObject,
         Alpha = obj.Alpha,
         IsOpaque = obj.IsOpaque,
         TextureName = obj.Texture.Name,
     });
 }
Beispiel #12
0
        /// <summary>
        /// for a given object return the location where it should be inserted.
        /// where the object is inserted is determined by its bounding sphere.
        ///  * if the sphere is bigger than the object or does not intersect -> dont insert
        ///  * if it is bigger than half the size -> insert into own list
        ///  * if it is smaller than that -> insert into a child node
        /// </summary>
        private ObjectLocation GetLocation(I3DObject obj)
        {
            var boundingSphere = obj.GetBoundingSphere();

            if (boundingSphere.Radius > _halfWidth || !CubeSphere.IsSphereIntersectingCube(_center, _halfWidth, boundingSphere))
            {
                return(ObjectLocation.None);
            }

            if (boundingSphere.Radius < _halfWidth / 2)
            {
                return(ObjectLocation.Child);
            }

            return(ObjectLocation.Self);
        }
Beispiel #13
0
        public override void ApplyPass(I3DObject obj)
        {
            if (_encounterAnimationStarted)
            {
                if (obj is PlayerCharacter)
                {
                    BE.DiffuseColor = Vector3.One;
                }
                else
                {
                    BE.DiffuseColor = new Vector3(_encounterAnimationState * ENCOUNTER_WHITE_MULTIPLIER);
                }
            }
            else
            {
                BE.DiffuseColor = Vector3.One;
            }

            base.ApplyPass(obj);
        }
Beispiel #14
0
        public virtual void Render(I3DObject obj)
        {
            if (obj.IsVisible && obj.IsVisualObject)
            {
                if (obj.BlendState != null)
                {
                    if (obj.BlendState.Name != GameInstanceProvider.Instance.GraphicsDevice.BlendState.Name)
                    {
                        GameInstanceProvider.Instance.GraphicsDevice.BlendState = obj.BlendState;
                    }
                }
                else
                {
                    if (GameInstanceProvider.Instance.GraphicsDevice.BlendState.Name != BlendState.AlphaBlend.Name)
                    {
                        GameInstanceProvider.Instance.GraphicsDevice.BlendState = BlendState.AlphaBlend;
                    }
                }

                World = obj.World;
                RenderVertices(obj);
            }
        }
Beispiel #15
0
 public virtual void ApplyPass(I3DObject obj)
 {
     Effect.CurrentTechnique.Passes[0].Apply();
 }
Beispiel #16
0
        /**
         * Inserts an object into the subtree. The actual algorithms for building the tree are specified by TreeInsertStrategy.
         *
         * @param o the object to be added.
         * @param s the bounding sphere of the object - precomputed for memory and performance reasons
         * @return false if the object does not intersect/or is not enclosed by this subtree, true otherwise.
         */

        public bool Insert(I3DObject o, Sphere s)
        {
            if (s == null)
            {
                //objects without bounding sphere will potentially intersect every ray
                Content.Add(o);
                return(true);
            }

            switch (Strategy)
            {
            case TreeInsertStrategy.LeafOnly:
                if (!CubeSphere.IsSphereIntersectingCube(Center, Width / 2, s))
                {
                    return(false);
                }

                if (_child != null)
                {
                    _child[0].Insert(o, s);
                    _child[1].Insert(o, s);
                    _child[2].Insert(o, s);
                    _child[3].Insert(o, s);
                    _child[4].Insert(o, s);
                    _child[5].Insert(o, s);
                    _child[6].Insert(o, s);
                    _child[7].Insert(o, s);
                }
                else
                {
                    Content.Add(o);
                }

                if (_child == null &&
                    Content.Count > TreeInsertStrategyConstants.MaxElements &&
                    Width > TreeInsertStrategyConstants.MinWidth)
                {
                    Split();
                }

                return(true);

            case TreeInsertStrategy.FitIntoBox:
                if (!o.IsEnclosedByCube(Center, Width / 2))
                {
                    return(false);
                }

                if (_child != null)
                {
                    if (_child[0].Insert(o, s) ||
                        _child[1].Insert(o, s) ||
                        _child[2].Insert(o, s) ||
                        _child[3].Insert(o, s) ||
                        _child[4].Insert(o, s) ||
                        _child[5].Insert(o, s) ||
                        _child[6].Insert(o, s) ||
                        _child[7].Insert(o, s))
                    {
                        return(true);
                    }
                }

                Content.Add(o);

                if (_child == null &&
                    Content.Count > TreeInsertStrategyConstants.MaxElements &&
                    Width > TreeInsertStrategyConstants.MinWidth)
                {
                    Split();
                }

                return(true);

            case TreeInsertStrategy.Dynamic:
                //if sphere is not touching cube -> error
                if (!CubeSphere.IsSphereIntersectingCube(Center, Width / 2, s))
                {
                    return(false);
                }

                //if object is enclosed by any child, add it there
                if (_child != null)
                {
                    foreach (Node n in _child)
                    {
                        if (o.IsEnclosedByCube(n.Center, n.Width / 2))
                        {
                            return(n.Insert(o, s));
                        }
                    }
                }

                //if object is very small (in relation to the box) - duplicate it to child nodes
                //add it to this node otherwise
                if (_child != null && s.Radius / Width < TreeInsertStrategyConstants.DynamicDuplicateMaxSizeRatio)
                {
                    _child[0].Insert(o, s);
                    _child[1].Insert(o, s);
                    _child[2].Insert(o, s);
                    _child[3].Insert(o, s);
                    _child[4].Insert(o, s);
                    _child[5].Insert(o, s);
                    _child[6].Insert(o, s);
                    _child[7].Insert(o, s);
                }
                else
                {
                    Content.Add(o);
                }

                //if node too full split it
                if (_child == null && Content.Count > 2 /*&&width>TreeInsertStrategy.DYNAMIC_MIN_WIDTH*/)
                {
                    Split();
                }

                return(true);

            case TreeInsertStrategy.DynamicTest:
                //if sphere is not touching cube -> error
                if (!CubeSphere.IsSphereIntersectingCube(Center, Width / 2, s))
                {
                    return(false);
                }

                //if object is enclosed by any child, add it there
                if (_child != null)
                {
                    foreach (Node n in _child)
                    {
                        if (o.IsEnclosedByCube(n.Center, n.Width / 2))
                        {
                            return(n.Insert(o, s));
                        }
                    }

                    bool i0 = CubeSphere.IsSphereIntersectingCube(_child[0].Center, _child[0].Width / 2, s),
                         i1 = CubeSphere.IsSphereIntersectingCube(_child[1].Center, _child[1].Width / 2, s),
                         i2 = CubeSphere.IsSphereIntersectingCube(_child[2].Center, _child[2].Width / 2, s),
                         i3 = CubeSphere.IsSphereIntersectingCube(_child[3].Center, _child[3].Width / 2, s),
                         i4 = CubeSphere.IsSphereIntersectingCube(_child[4].Center, _child[4].Width / 2, s),
                         i5 = CubeSphere.IsSphereIntersectingCube(_child[5].Center, _child[5].Width / 2, s),
                         i6 = CubeSphere.IsSphereIntersectingCube(_child[6].Center, _child[6].Width / 2, s),
                         i7 = CubeSphere.IsSphereIntersectingCube(_child[7].Center, _child[7].Width / 2, s);

                    int intersectionCount = 0;

                    if (i0)
                    {
                        intersectionCount++;
                    }
                    if (i1)
                    {
                        intersectionCount++;
                    }
                    if (i2)
                    {
                        intersectionCount++;
                    }
                    if (i3)
                    {
                        intersectionCount++;
                    }
                    if (i4)
                    {
                        intersectionCount++;
                    }
                    if (i5)
                    {
                        intersectionCount++;
                    }
                    if (i6)
                    {
                        intersectionCount++;
                    }
                    if (i7)
                    {
                        intersectionCount++;
                    }

                    if (intersectionCount == 1 || intersectionCount * s.Radius / Width < 0.35)
                    {
                        if (i0)
                        {
                            _child[0].Insert(o, s);
                        }
                        if (i1)
                        {
                            _child[1].Insert(o, s);
                        }
                        if (i2)
                        {
                            _child[2].Insert(o, s);
                        }
                        if (i3)
                        {
                            _child[3].Insert(o, s);
                        }
                        if (i4)
                        {
                            _child[4].Insert(o, s);
                        }
                        if (i5)
                        {
                            _child[5].Insert(o, s);
                        }
                        if (i6)
                        {
                            _child[6].Insert(o, s);
                        }
                        if (i7)
                        {
                            _child[7].Insert(o, s);
                        }

                        return(true);
                    }
                }

                Content.Add(o);

                //if node too full split it
                if (_child == null && Content.Count > 2)
                {
                    Split();
                }

                return(true);

            case TreeInsertStrategy.FastBuildTest:
                //if sphere is not touching cube -> error
                if (!CubeSphere.IsSphereIntersectingCube(Center, Width / 2, s))
                {
                    return(false);
                }

                //if object is enclosed by any child, add it there
                if (_child != null)
                {
                    bool i0 = CubeSphere.IsSphereIntersectingCube(_child[0].Center, _child[0].Width / 2, s),
                         i1 = CubeSphere.IsSphereIntersectingCube(_child[1].Center, _child[1].Width / 2, s),
                         i2 = CubeSphere.IsSphereIntersectingCube(_child[2].Center, _child[2].Width / 2, s),
                         i3 = CubeSphere.IsSphereIntersectingCube(_child[3].Center, _child[3].Width / 2, s),
                         i4 = CubeSphere.IsSphereIntersectingCube(_child[4].Center, _child[4].Width / 2, s),
                         i5 = CubeSphere.IsSphereIntersectingCube(_child[5].Center, _child[5].Width / 2, s),
                         i6 = CubeSphere.IsSphereIntersectingCube(_child[6].Center, _child[6].Width / 2, s),
                         i7 = CubeSphere.IsSphereIntersectingCube(_child[7].Center, _child[7].Width / 2, s);

                    int intersectionCount = 0;

                    if (i0)
                    {
                        intersectionCount++;
                    }
                    if (i1)
                    {
                        intersectionCount++;
                    }
                    if (i2)
                    {
                        intersectionCount++;
                    }
                    if (i3)
                    {
                        intersectionCount++;
                    }
                    if (i4)
                    {
                        intersectionCount++;
                    }
                    if (i5)
                    {
                        intersectionCount++;
                    }
                    if (i6)
                    {
                        intersectionCount++;
                    }
                    if (i7)
                    {
                        intersectionCount++;
                    }

                    if (intersectionCount == 1 || intersectionCount * s.Radius / Width < 0.5)
                    {
                        if (i0)
                        {
                            _child[0].Insert(o, s);
                        }
                        if (i1)
                        {
                            _child[1].Insert(o, s);
                        }
                        if (i2)
                        {
                            _child[2].Insert(o, s);
                        }
                        if (i3)
                        {
                            _child[3].Insert(o, s);
                        }
                        if (i4)
                        {
                            _child[4].Insert(o, s);
                        }
                        if (i5)
                        {
                            _child[5].Insert(o, s);
                        }
                        if (i6)
                        {
                            _child[6].Insert(o, s);
                        }
                        if (i7)
                        {
                            _child[7].Insert(o, s);
                        }

                        return(true);
                    }
                }

                Content.Add(o);

                //if node too full split it
                if (_child == null && Content.Count > TreeInsertStrategyConstants.MaxElements &&
                    Width > TreeInsertStrategyConstants.DynamicMinWidth)
                {
                    Split();
                }

                return(true);

            default:
                throw new Exception("Mode not implemented: " + Strategy);
            }
        }
Beispiel #17
0
        public static void Assignment7()
        {
            Random random = new Random();
            int n = 100;
            I3DObject[] objects = new I3DObject[n];
            for (int i = 0; i < n; i++)
            {
                switch(random.Next(3))
                {
                    case 0:
                        objects[i] = new Box(random.NextDouble(), random.NextDouble(), random.NextDouble());
                        break;
                    case 1:
                        objects[i] = new Cylinder(random.NextDouble(), random.NextDouble());
                        break;
                    case 2:
                        objects[i] = new Sphere(random.NextDouble());
                        break;
                }
            }

            I3DObject largest = objects.OrderByDescending(o => o.Volume).FirstOrDefault();
            Console.WriteLine("Largest shape: {0} ({1}m^3)", largest.GetType(), largest.Volume);
            Console.WriteLine("Total volume of all shapes: {0}", objects.Sum(o => o.Volume));
        }