예제 #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>
        public void Drop()
        {
            /*/ drop object action /*/
            // Check if we are carrying something to drop
            // Routine does not take into account facing rotation of an object
            if (inventory.Count == 0)
            {
                return;
            }
            // Get the candidate object to be dropped
            ObjectPortable drop_object = (ObjectPortable)inventory[usingObject];

            // Test if there is space for the object to be dropped
            // Create a test object to put in the drop position
            int[]    test_pos    = Physics.DropPosition(this, drop_object, GetFacing(), 4);
            Object3d test_object = new Object3d(test_pos, drop_object.GetSize(), 0, false);

            // Check if the test object collides with any other object in the scene
            if (Physics.TestCollisionGroup(test_object, scene.ObjectGroup) == true)
            {
                return;
            }
            // Put the object into the current scene by adding it to the scenes object list
            // Check if the object wants to be dropped
            if (drop_object.RequestDrop() == false)
            {
                return;
            }
            // Drop the object
            Vector.CopyVector(test_object.GetPosition(), drop_object.GetPosition());
            inventory.Remove(drop_object);
            scene.ObjectGroup.Add(drop_object);
            if (usingObject != 0)
            {
                usingObject = usingObject - 1;
            }
        }
예제 #3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="source_object"></param>
 /// <param name="drop_object"></param>
 /// <param name="facing"></param>
 /// <param name="separation"></param>
 /// <returns></returns>
 public static int[] DropPosition(Object3d sourceObject, Object3d dropObject, int[] facing, int separation)
 {
     /* Calculates a position to drop and object in front of the facing object
      *
      *  source_object: the facing object that is dropping the drop_object: class or subclass of Object3d
      *  drop_object: the object being dropped: class or subclass of Object3d
      *  facing: 3d facing vector : list of integers: [x,y,z]
      *
      *  Notes:
      *  The drop object is in the direction of the facing vector and projected from the centre of
      *  the source object to its edge and then an additional amount to the centre of the drop object.
      *  after that it is offset by half the size of the drop objects size vector.
      */
     if (sourceObject == null)
     {
         throw new ArgumentNullException("sourceObject");
     }
     if (dropObject == null)
     {
         throw new ArgumentNullException("dropObject");
     }
     int[] twos           = { 2, 2, 2 };
     int[] drop_half_size = Vector.DivideVector(dropObject.GetSize(), twos);
     //The centre of the source object
     int[] source_half_size = Vector.DivideVector(sourceObject.GetSize(), twos);
     int[] source_centre    = Vector.AddVector(sourceObject.GetPosition(), source_half_size);
     //offset from the centre of the source object to the centre of the drop object
     int[] displ_vect = Vector.AddVector(Vector.MultiplyVector(facing, drop_half_size), Vector.MultiplyVector(facing, source_half_size));
     //add a small offset to distance it from the source object
     int[] sep         = { separation, separation, separation };
     int[] offset_vect = Vector.AddVector(displ_vect, Vector.MultiplyVector(facing, sep));
     //produce the offset position of the corner of the drop object)
     int[] corner_vect = Vector.SubtractVector(offset_vect, drop_half_size);
     int[] test_pos    = Vector.AddVector(corner_vect, source_centre);
     return(test_pos);
 }
예제 #4
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);
        }
예제 #5
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;
                }
            }
        }
예제 #6
0
 /// <summary>
 /// 
 /// </summary>
 public void Drop()
 {
     /*/ drop object action /*/
     // Check if we are carrying something to drop
     // Routine does not take into account facing rotation of an object
     if (inventory.Count == 0)
     {
         return;
     }
     // Get the candidate object to be dropped
     ObjectPortable drop_object = (ObjectPortable)inventory[usingObject];
     // Test if there is space for the object to be dropped
     // Create a test object to put in the drop position
     int[] test_pos = Physics.DropPosition(this, drop_object, GetFacing(), 4);
     Object3d test_object = new Object3d(test_pos, drop_object.GetSize(), 0, false);
     // Check if the test object collides with any other object in the scene
     if (Physics.TestCollisionGroup(test_object, scene.ObjectGroup) == true)
     {
         return;
     }
     // Put the object into the current scene by adding it to the scenes object list
     // Check if the object wants to be dropped
     if (drop_object.RequestDrop() == false)
     {
         return;
     }
     // Drop the object
     Vector.CopyVector(test_object.GetPosition(), drop_object.GetPosition());
     inventory.Remove(drop_object);
     scene.ObjectGroup.Add(drop_object);
     if (usingObject != 0)
     {
         usingObject = usingObject - 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="source_object"></param>
        /// <param name="drop_object"></param>
        /// <param name="facing"></param>
        /// <param name="separation"></param>
        /// <returns></returns>
        public static int[] DropPosition(Object3d sourceObject, Object3d dropObject, int[] facing, int separation)
        {
            /* Calculates a position to drop and object in front of the facing object

                source_object: the facing object that is dropping the drop_object: class or subclass of Object3d
                drop_object: the object being dropped: class or subclass of Object3d
                facing: 3d facing vector : list of integers: [x,y,z]

                Notes:
                The drop object is in the direction of the facing vector and projected from the centre of
                the source object to its edge and then an additional amount to the centre of the drop object.
                after that it is offset by half the size of the drop objects size vector.
            */
            if (sourceObject == null)
            {
                throw new ArgumentNullException("sourceObject");
            }
            if (dropObject == null)
            {
                throw new ArgumentNullException("dropObject");
            }
            int[] twos ={ 2, 2, 2 };
            int[] drop_half_size = Vector.DivideVector(dropObject.GetSize(), twos);
            //The centre of the source object
            int[] source_half_size = Vector.DivideVector(sourceObject.GetSize(), twos);
            int[] source_centre = Vector.AddVector(sourceObject.GetPosition(), source_half_size);
            //offset from the centre of the source object to the centre of the drop object   
            int[] displ_vect = Vector.AddVector(Vector.MultiplyVector(facing, drop_half_size), Vector.MultiplyVector(facing, source_half_size));
            //add a small offset to distance it from the source object
            int[] sep ={ separation, separation, separation };
            int[] offset_vect = Vector.AddVector(displ_vect, Vector.MultiplyVector(facing, sep));
            //produce the offset position of the corner of the drop object)
            int[] corner_vect = Vector.SubtractVector(offset_vect, drop_half_size);
            int[] test_pos = Vector.AddVector(corner_vect, source_centre);
            return (test_pos);
        }
예제 #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
        /// <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;
                }
            }
        }