예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="object1"></param>
        /// <param name="object2"></param>
        /// <returns></returns>
        public static CollisionImpact Touch(Object3d object1, Object3d object2)
        {
            if (object1 == null)
            {
                throw new ArgumentNullException("object1");
            }
            if (object2 == null)
            {
                throw new ArgumentNullException("object2");
            }

            /* Detect if two objects are touching
             *  object1: The first object to be detected: class or subclass of Object3d
             *  object2: The second object to be detected: class or subclass of Object3d
             *
             *  imp: a collider with the impact time and faces touched on both objects: class collide
             */
            //produce an imaginary collision object based on projecting object 1 in the direction of object 2
            CollisionImpact imp = new CollisionImpact();

            int[]            zero          = { 0, 0, 0 };
            Isotope.Object3d sense_object1 = new Isotope.Object3d(zero, zero, 0, true);
            //Take the 2 centres of the objects
            int[] twos           = { 2, 2, 2 };
            int[] centre_object1 = Vector.AddVector(object1.GetPosition(), Vector.DivideVector(object1.GetSize(), twos));
            int[] centre_object2 = Vector.AddVector(object2.GetPosition(), Vector.DivideVector(object2.GetSize(), twos));
            //Find the projected vector between them
            int[] project_vector = Vector.MultiplyVector(Vector.Direction(centre_object1, centre_object2), twos);
            //Add the projected vector to the first objects position
            sense_object1.SetPosition(Vector.AddVector(object1.GetPosition(), project_vector));
            Vector.CopyVector(object1.GetSize(), sense_object1.GetSize());
            //collision detect the sense object with the object 2
            imp = CollisionDetect(sense_object1, object2);
            return(imp);
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="test_object"></param>
        /// <param name="object_group"></param>
        /// <returns></returns>
        public static bool TestCollisionGroup(Object3d testObject, ArrayList objectGroup)
        {
            if (objectGroup == null)
            {
                throw new ArgumentNullException("objectGroup");
            }

            /* Checks if the test object collides with any object in the object group
             *
             *  test_object: The object to be tested for a collision: class or subclass of Object3d
             *  object_group: A list of objects : list of class or subclass of Object3d
             *  Return true/false: true for a collision : boolean
             */
            CollisionImpact imp = new CollisionImpact();

            for (int obj = 0; obj < objectGroup.Count; obj++)
            {
                //call the collision detector to get the first object collided with
                imp = CollisionDetect(testObject, (Object3d)objectGroup[obj]);
                if (imp.Impact == true)
                {
                    return(true);
                }
            }
            return(false);
        }
예제 #3
0
        //NOTE: we are using an impact structure for touch which may not be appropriate

        /// <summary>
        ///
        /// </summary>
        /// <param name="obj_group"></param>
        public static void TouchProcessor(Object3d[] objectGroup)
        {
            if (objectGroup == null)
            {
                throw new ArgumentNullException("objectGroup");
            }

            /*Discover if any of the objects in the group are touching and call their touch response routines
             *
             * obj_group: A list of objects within the scene: list of class or subclass of Object3d
             */
            CollisionImpact imp = new CollisionImpact();

            for (int object1 = 0; object1 < objectGroup.Length; object1++)
            {
                for (int object2 = object1 + 1; object2 < objectGroup.Length; object2++)
                {
                    //Detect a touch between object 1 and object 2
                    imp = Touch(objectGroup[object1], objectGroup[object2]);
                    if (imp.Impact == true)
                    {
                        //Touch response, call the objects touch event handler
                        objectGroup[object1].EventTouch(imp.Impact, objectGroup[object2], imp.ImpactFaceObject1);
                        objectGroup[object2].EventTouch(imp.Impact, objectGroup[object1], imp.ImpactFaceObject2);
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj_group"></param>
        public static void CollisionProcessor(Object3d[] objectGroup)
        {
            if (objectGroup == null)
            {
                throw new ArgumentNullException("objectGroup");
            }

            /* collision_processor: Detects collisions amongst all object pairs and moves them back
             *  until just before the collision and runs the object collision responses
             *
             *  obj_group: A list of objects within the scene: list of class or subclass of Object3d
             */
            CollisionImpact imp = new CollisionImpact();

            //runs the collision routines until no impacts occur
            while (true)
            {
                bool noimpact = true;
                for (int object1 = 0; object1 < objectGroup.Length; object1++)
                {
                    for (int object2 = object1 + 1; object2 < objectGroup.Length; object2++)
                    {
                        //If both objects are not fixedob call the collision detector to get the first object collided with
                        //and time of collision, faces collided with
                        if (objectGroup[object1].FixedObject == false || objectGroup[object2].FixedObject == false)
                        {
                            imp = CollisionDetect(objectGroup[object1], objectGroup[object2]);
                            if (imp.Impact == true)
                            {
                                //Collision response, currently just moving the two objects apart to just touching
                                CollisionResponse(objectGroup[object1], objectGroup[object2], imp);
                                objectGroup[object1].EventCollision(objectGroup[object2], imp.ImpactFaceObject1);
                                objectGroup[object2].EventCollision(objectGroup[object1], imp.ImpactFaceObject2);
                                noimpact = false;
                                //Console.WriteLine("End collider loop");
                            }
                        }
                    }
                }
                if (noimpact == true)
                {
                    break;
                }
            }
        }
예제 #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="object1"></param>
        /// <param name="object2"></param>
        /// <returns></returns>
        public static CollisionImpact CollisionDetect(Object3d object1, Object3d object2)
        {
            if (object1 == null)
            {
                throw new ArgumentNullException("object1");
            }
            if (object2 == null)
            {
                throw new ArgumentNullException("object2");
            }

            /* Discovers if there is a collision between two objects
             *
             *  object1: The first object to be detected: class or subclass of Object3d
             *  object2: The second object to be detected: class or subclass of Object3d
             *  Returns imp: a collider with the impact time and faces hit on both objects: class collider
             *
             *  Notes: Simple collision detection, does not handle if objects pass completely
             *  through each other if they have high velocity and the objects are small
             */
            CollisionImpact imp = new CollisionImpact();
            int             impactTimeFace1;
            int             impactTimeFace2;
            int             impactFaceObject1 = 0;
            int             impactFaceObject2 = 0;
            int             impactTimeCoord   = 0;

            for (int i = 0; i <= 2; i++)
            {
                //check if intersecting
                if (object1.GetPosition()[i] + object1.GetSize()[i] <= object2.GetPosition()[i])
                {
                    return(imp);
                }
                if (object1.GetPosition()[i] >= object2.GetPosition()[i] + object2.GetSize()[i])
                {
                    return(imp);
                }
            }
            //if intersecting calculate the first face impacted
            imp.Impact = true;
            //***OSCALL
            imp.ImpactTime = 1600000;

            for (int i = 0; i <= 2; i++)
            {
                impactTimeFace1 = object1.GetPosition()[i] + object1.GetSize()[i] - object2.GetPosition()[i];
                impactTimeFace2 = object2.GetPosition()[i] + object2.GetSize()[i] - object1.GetPosition()[i];
                if (impactTimeFace1 < impactTimeFace2)
                {
                    impactFaceObject1 = i << 1;
                    impactFaceObject2 = (i << 1) + 1;
                    impactTimeCoord   = impactTimeFace1;
                }
                else if (impactTimeFace1 >= impactTimeFace2)
                {
                    impactFaceObject1 = (i << 1) + 1;
                    impactFaceObject2 = i << 1;
                    impactTimeCoord   = impactTimeFace2;
                }
                if (impactTimeCoord < imp.ImpactTime)
                {
                    imp.ImpactTime        = impactTimeCoord;
                    imp.ImpactFaceObject1 = impactFaceObject1;
                    imp.ImpactFaceObject2 = impactFaceObject2;
                }
            }
            return(imp);
        }
예제 #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="object1"></param>
        /// <param name="object2"></param>
        /// <param name="imp"></param>
        public static void CollisionResponse(Object3d object1, Object3d object2, CollisionImpact imp)
        {
            if (object1 == null)
            {
                throw new ArgumentNullException("object1");
            }
            if (object2 == null)
            {
                throw new ArgumentNullException("object2");
            }
            if (imp == null)
            {
                throw new ArgumentNullException("imp");
            }

            /* Moves back the objects until they are adjacent on their colliding sides
             *
             *  object1: The first object to be moved: class or subclass of Object3d
             *  object2: The second object to be moved: class or subclass of Object3d
             *  imp: a collider with the impact time and faces hit on both objects: class collider */
            // calculate the collision coordinate from the face
            int coord = imp.ImpactFaceObject1 >> 1;
            int delta = 0;

            //four cases based on if the object has its fixedob flag to stop pushing.
            if (object1.FixedObject == true && object2.FixedObject == true)
            {
                // Do nothing as both objects are fixedob
                return;
            }
            if (object1.FixedObject == false && object2.FixedObject == true)
            {
                if (imp.ImpactFaceObject1 % 2 == 0)
                {
                    object1.GetPosition()[coord] = object2.GetPosition()[coord] - object1.GetSize()[coord] - 1;
                }
                else
                {
                    object1.GetPosition()[coord] = object2.GetPosition()[coord] + object2.GetSize()[coord];
                }
            }
            if (object1.FixedObject == true && object2.FixedObject == false)
            {
                if (imp.ImpactFaceObject2 % 2 == 0)
                {
                    object2.GetPosition()[coord] = object1.GetPosition()[coord] - object2.GetSize()[coord] - 1;
                }
                else
                {
                    object2.GetPosition()[coord] = object1.GetPosition()[coord] + object1.GetSize()[coord];
                }
            }
            if (object1.FixedObject == false && object2.FixedObject == false)
            {
                if (imp.ImpactFaceObject1 % 2 == 0)
                {
                    delta = (object1.GetPosition()[coord] + object1.GetSize()[coord] - object2.GetPosition()[coord]);
                    object1.GetPosition()[coord] = (int)object1.GetPosition()[coord] - (int)((float)delta / 2.0);
                    object2.GetPosition()[coord] = (int)object2.GetPosition()[coord] + (int)((float)delta / 2.0) + 1;
                }
                else
                {
                    delta = (object2.GetPosition()[coord] + object2.GetSize()[coord] - object1.GetPosition()[coord]);
                    object2.GetPosition()[coord] = (int)object2.GetPosition()[coord] - (int)((float)delta / 2.0);
                    object1.GetPosition()[coord] = (int)object1.GetPosition()[coord] + (int)((float)delta / 2.0) + 1;
                }
            }
        }
예제 #7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="object1"></param>
        /// <param name="object2"></param>
        /// <returns></returns>
        public static CollisionImpact CollisionDetect(Object3d object1, Object3d object2)
        {
            if (object1 == null)
            {
                throw new ArgumentNullException("object1");
            }
            if (object2 == null)
            {
                throw new ArgumentNullException("object2");
            }
            /* Discovers if there is a collision between two objects

                object1: The first object to be detected: class or subclass of Object3d
                object2: The second object to be detected: class or subclass of Object3d
                Returns imp: a collider with the impact time and faces hit on both objects: class collider
		 
                Notes: Simple collision detection, does not handle if objects pass completely
                through each other if they have high velocity and the objects are small
            */
            CollisionImpact imp = new CollisionImpact();
            int impactTimeFace1;
            int impactTimeFace2;
            int impactFaceObject1 = 0;
            int impactFaceObject2 = 0;
            int impactTimeCoord = 0;

            for (int i = 0; i <= 2; i++)
            {
                //check if intersecting
                if (object1.GetPosition()[i] + object1.GetSize()[i] <= object2.GetPosition()[i])
                {
                    return (imp);
                }
                if (object1.GetPosition()[i] >= object2.GetPosition()[i] + object2.GetSize()[i])
                {
                    return (imp);
                }
            }
            //if intersecting calculate the first face impacted
            imp.Impact = true;
            //***OSCALL
            imp.ImpactTime = 1600000;

            for (int i = 0; i <= 2; i++)
            {
                impactTimeFace1 = object1.GetPosition()[i] + object1.GetSize()[i] - object2.GetPosition()[i];
                impactTimeFace2 = object2.GetPosition()[i] + object2.GetSize()[i] - object1.GetPosition()[i];
                if (impactTimeFace1 < impactTimeFace2)
                {
                    impactFaceObject1 = i << 1;
                    impactFaceObject2 = (i << 1) + 1;
                    impactTimeCoord = impactTimeFace1;
                }
                else if (impactTimeFace1 >= impactTimeFace2)
                {
                    impactFaceObject1 = (i << 1) + 1;
                    impactFaceObject2 = i << 1;
                    impactTimeCoord = impactTimeFace2;
                }
                if (impactTimeCoord < imp.ImpactTime)
                {
                    imp.ImpactTime = impactTimeCoord;
                    imp.ImpactFaceObject1 = impactFaceObject1;
                    imp.ImpactFaceObject2 = impactFaceObject2;
                }
            }
            return (imp);
        }
예제 #8
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="test_object"></param>
        /// <param name="object_group"></param>
        /// <returns></returns>
        public static bool TestCollisionGroup(Object3d testObject, ArrayList objectGroup)
        {
            if (objectGroup == null)
            {
                throw new ArgumentNullException("objectGroup");
            }
            /* Checks if the test object collides with any object in the object group

                test_object: The object to be tested for a collision: class or subclass of Object3d
                object_group: A list of objects : list of class or subclass of Object3d
                Return true/false: true for a collision : boolean
            */
            CollisionImpact imp = new CollisionImpact();
            for (int obj = 0; obj < objectGroup.Count; obj++)
            {
                //call the collision detector to get the first object collided with
                imp = CollisionDetect(testObject, (Object3d)objectGroup[obj]);
                if (imp.Impact == true)
                {
                    return (true);
                }
            }
            return (false);
        }
예제 #9
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="object1"></param>
        /// <param name="object2"></param>
        /// <returns></returns>
        public static CollisionImpact Touch(Object3d object1, Object3d object2)
        {
            if (object1 == null)
            {
                throw new ArgumentNullException("object1");
            }
            if (object2 == null)
            {
                throw new ArgumentNullException("object2");
            }
            /* Detect if two objects are touching
                object1: The first object to be detected: class or subclass of Object3d
                object2: The second object to be detected: class or subclass of Object3d

                imp: a collider with the impact time and faces touched on both objects: class collide
            */
            //produce an imaginary collision object based on projecting object 1 in the direction of object 2
            CollisionImpact imp = new CollisionImpact();
            int[] zero ={ 0, 0, 0 };
            Isotope.Object3d sense_object1 = new Isotope.Object3d(zero, zero, 0, true);
            //Take the 2 centres of the objects
            int[] twos ={ 2, 2, 2 };
            int[] centre_object1 = Vector.AddVector(object1.GetPosition(), Vector.DivideVector(object1.GetSize(), twos));
            int[] centre_object2 = Vector.AddVector(object2.GetPosition(), Vector.DivideVector(object2.GetSize(), twos));
            //Find the projected vector between them
            int[] project_vector = Vector.MultiplyVector(Vector.Direction(centre_object1, centre_object2), twos);
            //Add the projected vector to the first objects position
            sense_object1.SetPosition(Vector.AddVector(object1.GetPosition(), project_vector));
            Vector.CopyVector(object1.GetSize(), sense_object1.GetSize());
            //collision detect the sense object with the object 2
            imp = CollisionDetect(sense_object1, object2);
            return (imp);
        }
예제 #10
0
        //NOTE: we are using an impact structure for touch which may not be appropriate

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj_group"></param>
        public static void TouchProcessor(Object3d[] objectGroup)
        {
            if (objectGroup == null)
            {
                throw new ArgumentNullException("objectGroup");
            }

            /*Discover if any of the objects in the group are touching and call their touch response routines

               obj_group: A list of objects within the scene: list of class or subclass of Object3d
            */
            CollisionImpact imp = new CollisionImpact();
            for (int object1 = 0; object1 < objectGroup.Length; object1++)
            {
                for (int object2 = object1 + 1; object2 < objectGroup.Length; object2++)
                {
                    //Detect a touch between object 1 and object 2
                    imp = Touch(objectGroup[object1], objectGroup[object2]);
                    if (imp.Impact == true)
                    {
                        //Touch response, call the objects touch event handler
                        objectGroup[object1].EventTouch(imp.Impact, objectGroup[object2], imp.ImpactFaceObject1);
                        objectGroup[object2].EventTouch(imp.Impact, objectGroup[object1], imp.ImpactFaceObject2);
                    }
                }
            }
        }
예제 #11
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="object1"></param>
        /// <param name="object2"></param>
        /// <param name="imp"></param>
        public static void CollisionResponse(Object3d object1, Object3d object2, CollisionImpact imp)
        {
            if (object1 == null)
            {
                throw new ArgumentNullException("object1");
            }
            if (object2 == null)
            {
                throw new ArgumentNullException("object2");
            }
            if (imp == null)
            {
                throw new ArgumentNullException("imp");
            }

            /* Moves back the objects until they are adjacent on their colliding sides

                object1: The first object to be moved: class or subclass of Object3d
                object2: The second object to be moved: class or subclass of Object3d
                imp: a collider with the impact time and faces hit on both objects: class collider */
            // calculate the collision coordinate from the face
            int coord = imp.ImpactFaceObject1 >> 1;
            int delta = 0;
            //four cases based on if the object has its fixedob flag to stop pushing.
            if (object1.FixedObject == true && object2.FixedObject == true)
                // Do nothing as both objects are fixedob
                return;
            if (object1.FixedObject == false && object2.FixedObject == true)
            {
                if (imp.ImpactFaceObject1 % 2 == 0)
                {
                    object1.GetPosition()[coord] = object2.GetPosition()[coord] - object1.GetSize()[coord] - 1;
                }
                else
                {
                    object1.GetPosition()[coord] = object2.GetPosition()[coord] + object2.GetSize()[coord];
                }
            }
            if (object1.FixedObject == true && object2.FixedObject == false)
            {
                if (imp.ImpactFaceObject2 % 2 == 0)
                {
                    object2.GetPosition()[coord] = object1.GetPosition()[coord] - object2.GetSize()[coord] - 1;
                }
                else
                {
                    object2.GetPosition()[coord] = object1.GetPosition()[coord] + object1.GetSize()[coord];
                }
            }
            if (object1.FixedObject == false && object2.FixedObject == false)
            {
                if (imp.ImpactFaceObject1 % 2 == 0)
                {
                    delta = (object1.GetPosition()[coord] + object1.GetSize()[coord] - object2.GetPosition()[coord]);
                    object1.GetPosition()[coord] = (int)object1.GetPosition()[coord] - (int)((float)delta / 2.0);
                    object2.GetPosition()[coord] = (int)object2.GetPosition()[coord] + (int)((float)delta / 2.0) + 1;
                }
                else
                {
                    delta = (object2.GetPosition()[coord] + object2.GetSize()[coord] - object1.GetPosition()[coord]);
                    object2.GetPosition()[coord] = (int)object2.GetPosition()[coord] - (int)((float)delta / 2.0);
                    object1.GetPosition()[coord] = (int)object1.GetPosition()[coord] + (int)((float)delta / 2.0) + 1;
                }
            }
        }
예제 #12
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj_group"></param>
        public static void CollisionProcessor(Object3d[] objectGroup)
        {
            if (objectGroup == null)
            {
                throw new ArgumentNullException("objectGroup");
            }
            /* collision_processor: Detects collisions amongst all object pairs and moves them back
                until just before the collision and runs the object collision responses

                obj_group: A list of objects within the scene: list of class or subclass of Object3d
            */
            CollisionImpact imp = new CollisionImpact();
            //runs the collision routines until no impacts occur
            while (true)
            {
                bool noimpact = true;
                for (int object1 = 0; object1 < objectGroup.Length; object1++)
                {
                    for (int object2 = object1 + 1; object2 < objectGroup.Length; object2++)
                    {
                        //If both objects are not fixedob call the collision detector to get the first object collided with
                        //and time of collision, faces collided with
                        if (objectGroup[object1].FixedObject == false || objectGroup[object2].FixedObject == false)
                        {
                            imp = CollisionDetect(objectGroup[object1], objectGroup[object2]);
                            if (imp.Impact == true)
                            {
                                //Collision response, currently just moving the two objects apart to just touching
                                CollisionResponse(objectGroup[object1], objectGroup[object2], imp);
                                objectGroup[object1].EventCollision(objectGroup[object2], imp.ImpactFaceObject1);
                                objectGroup[object2].EventCollision(objectGroup[object1], imp.ImpactFaceObject2);
                                noimpact = false;
                                //Console.WriteLine("End collider loop");
                            }
                        }
                    }
                }
                if (noimpact == true)
                {
                    break;
                }
            }
        }