Subversion Repositories AndroidProjects

Rev

Rev 1184 | Rev 1195 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.bauzoid.math.collision;

import com.badlogic.gdx.Gdx;
import com.gebauz.bauzoid.graphics.Graphics;
import com.gebauz.bauzoid.graphics.sprite.SpriteTransform;
import com.gebauz.bauzoid.math.Line2;
import com.gebauz.bauzoid.math.Vector2;
import com.gebauz.bauzoid.math.collision.Shape;

/** Interface for shape element. */
public abstract class BaseShapeElement
{
        // Constants========================================================================================

        // Embedded Types===================================================================================

        // Fields===========================================================================================
       
        private Shape mOwner = null;
       
       
        public Line2 trajectory = null;

        // Methods==========================================================================================

        public BaseShapeElement(Shape shape)
        {
                mOwner = shape;
        }
       
        //public abstract boolean isInside(float x, float y);
       
        /** Returns true if the shape intersects with this shape element.
         *  @param shape The shape tested against.
         *  @param transform Transformation matrix that brings this shape element's points into shape's space.
         */

        //public abstract boolean intersects(Shape shape, Matrix4 transform);
       
        /** Returns true if the shape intersects with this shape element. Returns a displacement vector
         *  that specifies by how much this shape element needs to be displaced in order to become non-colliding.
         *  @param shape The shape tested against.  
         *  @param transform Transformation matrix that brings this shape element's points into shape's space.
         */

        /*public abstract boolean intersects(Shape shape, Matrix4 transform, Vector2 displaceResult);
       
        public abstract boolean intersectsLine(Line2 line);*/

       
        /** Calculate intersection with a group of shape elements. */
        public CollisionResult collide(Shape shape)
        {
                return collide(shape, null);
        }
       
        /** Calculate intersection with a group of shape elements along movement vector. */
        public CollisionResult collide(Shape shape, Vector2 move)
        {
                CollisionResult result = new CollisionResult();
               
                // move
                float tempX = getOwner().transform.x;
                float tempY = getOwner().transform.y;
               
                if (move != null)
                {
                        getOwner().transform.x += move.x;
                        getOwner().transform.y += move.y;
                }
               
                //Vector2 contactPoints[] = new Vector2[shape.getShapeElementCount()];
                Vector2 contactPoint = new Vector2();
                int numContactPoints = 0;
               
                for (int i = 0; i < shape.getShapeElementCount(); i++)
                {
                        //Line2[] poly1 = getSweepLineSegments(move);
                        Line2[] poly1 = getLineSegments();
                        Vector2[] axes1 = getProjectionAxes();
                        Line2[] poly2 = shape.getShapeElement(i).getLineSegments();
                        Vector2[] axes2 = shape.getShapeElement(i).getProjectionAxes();
                               
                        // do magic                    
                        CollisionUtil.PenetrationResult penetrationResult = CollisionUtil.calculatePenetration(poly1, poly2, axes1, axes2);
                       
                        if (penetrationResult.penetrationVector != null)
                        {
                                result.isColliding = true;
                                result.penetrationVector.addVector(penetrationResult.penetrationVector);
                                //result.collidingEdge = penetrationResult.penetrationEdge.copy();
                               
                                // apply correction
                                getOwner().transform.x += penetrationResult.penetrationVector.x;
                                getOwner().transform.y += penetrationResult.penetrationVector.y;
                               
                                //contactPoints[numContactPoints] = penetrationResult.contactPoint;
                                numContactPoints = 1;
                                contactPoint = penetrationResult.contactPoint;
                                //contactPoint.addVector(penetrationResult.contactPoint);                              
                                //numContactPoints++;
                        }
                }
               
                if (result.isColliding)
                {                      
                        // get contact point
                        contactPoint.x /= numContactPoints;
                        contactPoint.y /= numContactPoints;
                        result.contactPoint = contactPoint;
                }
               
                // restore original position (result penetration vector is going to be applied outside)
                getOwner().transform.x = tempX;
                getOwner().transform.y = tempY;
                       
                return result;
        }

        /** Render debug output. */
        public abstract void renderDebug(Graphics graphics, SpriteTransform t);
       
        /** Get a list of untransformed points that make up the polygon. */
        public abstract Vector2[] getUntransformedPoints();
       
        /** Get a list of transformed (with the parent shape's SpriteTransform) points that make up the polygon. */
        public abstract Vector2[] getPoints();
       
        /** Get a list of untransformed line segments that make up the polygon. */
        public abstract Line2[] getUntransformedLineSegments();
       
        /** Get a list of transformed (with the parent shape's SpriteTransform) line segments that make up the polygon. */
        public abstract Line2[] getLineSegments();
       
        /** Get a list of transformed line segments including the swept shape. */
        public abstract Line2[] getSweepLineSegments(Vector2 move);
       
        /** Get all vectors for all distinct projection axes for separating axis theorem. */
        public abstract Vector2[] getProjectionAxes();

        // Getters/Setters==================================================================================
       
        public final void setOwner(Shape shape)
        {
                mOwner = shape;
        }
       
        public final Shape getOwner()
        {
                return mOwner;
        }
       
        public final SpriteTransform getTransform()
        {
                return mOwner.transform;
        }
       
        public final Vector2 getCenter()
        {
                Vector2 result = new Vector2();
                Vector2[] points = getPoints();
                for (int i = 0; i < points.length; i++)
                {
                        result.addVector(points[i]);
                }
                result.x /= points.length;
                result.y /= points.length;
               
                return result;
        }
       

}