Ejemplo n.º 1
0
        public override void MarkIntersectWithSurface(ObstacleSurface otherSurface, MovementMechanism forMechanism)
        {
            Hitbox hitbox = forMechanism.Hitbox;

            switch (hitbox.Type)
            {
            case Hitbox.HitboxType.Square:
            {
                //SquareHitbox square = hitbox as SquareHitbox;
            }
            break;

            default:
                throw new NotImplementedException("Unknown hitbox type");
            }
            SimpleVolume vol    = MyVolume;
            Orientation  offset = forMechanism.HitboxOffset(otherSurface);

            //Reverse changes to find how this object intersects with original surface instead of the other way around.
            vol.MinX = vol.MinX - offset.x - hitbox.MaxXIncrease((Rotation)offset);
            vol.MaxX = vol.MaxX - offset.x + hitbox.MaxXDecrease((Rotation)offset);
            vol.MinY = vol.MinY - offset.y - hitbox.MaxYIncrease((Rotation)offset);
            vol.MaxY = vol.MaxY - offset.y + hitbox.MaxYDecrease((Rotation)offset);
            vol.MinZ = vol.MinZ - offset.z - hitbox.MaxZIncrease((Rotation)offset);
            vol.MaxZ = vol.MaxZ - offset.z + hitbox.MaxZDecrease((Rotation)offset);

            Vector normal = otherSurface.GetNormal();
            int    height = otherSurface.GetHeight();

            //Important: These indices match the obstacle point indices.
            int[] differences = new int[8];
            differences[0] = (int)normal.DotProduct(vol.MinX, vol.MinY, vol.MinZ) - height;
            differences[1] = (int)normal.DotProduct(vol.MaxX, vol.MinY, vol.MinZ) - height;
            differences[2] = (int)normal.DotProduct(vol.MaxX, vol.MaxY, vol.MinZ) - height;
            differences[3] = (int)normal.DotProduct(vol.MinX, vol.MaxY, vol.MinZ) - height;
            differences[4] = (int)normal.DotProduct(vol.MinX, vol.MinY, vol.MaxZ) - height;
            differences[5] = (int)normal.DotProduct(vol.MaxX, vol.MinY, vol.MaxZ) - height;
            differences[6] = (int)normal.DotProduct(vol.MaxX, vol.MaxY, vol.MaxZ) - height;
            differences[7] = (int)normal.DotProduct(vol.MinX, vol.MaxY, vol.MaxZ) - height;

            List <int> negativeHeights = new List <int>(8);
            List <int> positiveHeights = new List <int>(8);

            if (differences[0] > 0)
            {
                positiveHeights.Add(0);
            }
            else
            {
                negativeHeights.Add(0);
            }
            if (differences[1] > 0)
            {
                positiveHeights.Add(1);
            }
            else
            {
                negativeHeights.Add(1);
            }
            if (differences[2] > 0)
            {
                positiveHeights.Add(2);
            }
            else
            {
                negativeHeights.Add(2);
            }
            if (differences[3] > 0)
            {
                positiveHeights.Add(3);
            }
            else
            {
                negativeHeights.Add(3);
            }
            if (differences[4] > 0)
            {
                positiveHeights.Add(4);
            }
            else
            {
                negativeHeights.Add(4);
            }
            if (differences[5] > 0)
            {
                positiveHeights.Add(5);
            }
            else
            {
                negativeHeights.Add(5);
            }
            if (differences[6] > 0)
            {
                positiveHeights.Add(6);
            }
            else
            {
                negativeHeights.Add(6);
            }
            if (differences[7] > 0)
            {
                positiveHeights.Add(7);
            }
            else
            {
                negativeHeights.Add(7);
            }

            if (positiveHeights.Count == 0 || negativeHeights.Count == 0)
            {
                return;
            }
            for (int i = 0; i < negativeHeights.Count; i++)
            {
                int pointId = negativeHeights[i];
                for (int j = 0; j < 3; j++)
                {
                    SurfaceLine   line       = PointLine(pointId, j);
                    ObstaclePoint otherPoint = line.Start;
                    if (otherPoint.id == pointId)
                    {
                        otherPoint = line.End;
                    }
                    if (differences[otherPoint.id] > 0)
                    {
                        double ratio = differences[pointId] / (differences[pointId] - differences[otherPoint.id]);
                        Point  start = PointPosition(pointId);
                        Point  end   = otherPoint.Position;
                        Point  intersectPoint;
                        intersectPoint.x = start.x + (int)((end.x - start.x) * ratio);
                        intersectPoint.y = start.y + (int)((end.y - start.y) * ratio);
                        intersectPoint.z = start.z + (int)((end.z - start.z) * ratio);

                        List <Point> IntersectingPoints = new List <Point>();
                        IntersectingPoints.Add(intersectPoint);
                        SurfaceLine previousLine      = line;
                        SurfaceLine nextLine          = new SurfaceLine(); //compiler has failed me for once, this shouldn't need initialization here.
                        int         previousSurfaceId = -1;
                        do
                        {
                            ObstacleSurface nextSurface = previousLine.Left;
                            if (previousSurfaceId == nextSurface.surfaceIndex)
                            {
                                nextSurface = previousLine.Right;
                            }
                            for (int k = 0; k < 4; k++)
                            {
                                nextLine = nextSurface.GetLine(k);
                                if (nextLine.id == previousLine.id)
                                {
                                    continue;
                                }
                                ObstaclePoint nextStart = nextLine.Start;
                                ObstaclePoint nextEnd   = nextLine.End;
                                if ((differences[nextStart.id] > 0 && differences[nextEnd.id] <= 0) ||
                                    (differences[nextStart.id] <= 0 && differences[nextEnd.id] > 0))
                                {
                                    start            = nextStart.Position;
                                    end              = nextEnd.Position;
                                    ratio            = differences[nextStart.id] / (differences[nextStart.id] - differences[nextEnd.id]);
                                    intersectPoint.x = start.x + (int)((end.x - start.x) * ratio);
                                    intersectPoint.y = start.y + (int)((end.y - start.y) * ratio);
                                    intersectPoint.z = start.z + (int)((end.z - start.z) * ratio);

                                    IntersectingPoints.Add(intersectPoint);

                                    break;
                                }
                            }

                            previousSurfaceId = nextSurface.surfaceIndex;
                            previousLine      = nextLine;
                        }while (nextLine.id != line.id);

                        otherSurface.AddIntersectLines(IntersectingPoints, this, forMechanism);

                        return;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public void AddIntersectLines(List <Point> points, int surfaceIndex, Obstacle forObstacle, MovementMechanism forMechanism)
        {
            VolumeTree <ObstacleHitLine> collection = SurfaceObstacleLines[surfaceIndex];

            if (collection == null)
            {
                SimpleVolume surfaceVolume = MyVolume;
                switch (surfaceIndex)
                {
                case 0:
                    surfaceVolume.MaxZ = surfaceVolume.MinZ;
                    break;

                case 1:
                    surfaceVolume.MinZ = surfaceVolume.MaxZ;
                    break;

                case 2:
                    surfaceVolume.MaxY = surfaceVolume.MinY;
                    break;

                case 3:
                    surfaceVolume.MinX = surfaceVolume.MaxX;
                    break;

                case 4:
                    surfaceVolume.MinY = surfaceVolume.MaxY;
                    break;

                case 5:
                    surfaceVolume.MaxX = surfaceVolume.MinX;
                    break;
                }
                collection = new VolumeTree <ObstacleHitLine>(surfaceVolume);
                SurfaceObstacleLines[surfaceIndex] = collection;
            }
            ObstacleHitLineGroup lineGroup = new ObstacleHitLineGroup();

            lineGroup.CausingObstacle = forObstacle;
            lineGroup.Mechanism       = forMechanism;

            lineGroup.SetupPoints(points, collection, SurfaceNormal(surfaceIndex));
        }