/// <summary>
        /// Given a set of points ordered counter-clockwise along a contour and a set of holes, return triangle indexes.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="holes"></param>
        /// <param name="indexes">Indices outside of the points list index into holes when layed out linearly.
        /// {vertices 0,1,2...vertices.length-1, holes 0 values, hole 1 values etc.} </param>
        /// <returns></returns>
        public static bool Triangulate(IList <Vector2> points, IList <IList <Vector2> > holes, out List <int> indexes)
        {
            indexes = new List <int>();

            int index = 0;

            var allPoints = new List <Vector2>(points);

            Polygon polygon = new Polygon(points.Select(x => new PolygonPoint(x.x, x.y, index++)));

            if (holes != null)
            {
                for (int i = 0; i < holes.Count; i++)
                {
                    allPoints.AddRange(holes[i]);
                    var holePolgyon = new Polygon(holes[i].Select(x => new PolygonPoint(x.x, x.y, index++)));
                    polygon.AddHole(holePolgyon);
                }
            }

            try
            {
                P2T.Triangulate(TriangulationAlgorithm.DTSweep, polygon);
            }
            catch (System.Exception e)
            {
                Log.Info("Triangulation failed: " + e.ToString());
                return(false);
            }

            foreach (DelaunayTriangle d in polygon.Triangles)
            {
                if (d.Points[0].Index < 0 || d.Points[1].Index < 0 || d.Points[2].Index < 0)
                {
                    Log.Info("Triangulation failed: Additional vertices were inserted.");
                    return(false);
                }

                indexes.Add(d.Points[0].Index);
                indexes.Add(d.Points[1].Index);
                indexes.Add(d.Points[2].Index);
            }

            WindingOrder originalWinding = SurfaceTopology.GetWindingOrder(points);

            // if the re-triangulated first tri doesn't match the winding order of the original
            // vertices, flip 'em

            if (SurfaceTopology.GetWindingOrder(new Vector2[3]
            {
                allPoints[indexes[0]],
                allPoints[indexes[1]],
                allPoints[indexes[2]],
            }) != originalWinding)
            {
                indexes.Reverse();
            }

            return(true);
        }
Example #2
0
 // Return the modular distance from one angle to another using the given winding order.
 public static int GetAngleDistance(int startAngle, int endAngle, WindingOrder windingOrder)
 {
     if (windingOrder == WindingOrder.Clockwise)
     {
         if (endAngle > startAngle)
         {
             return(startAngle + Angles.AngleCount - endAngle);
         }
         else
         {
             return(startAngle - endAngle);
         }
     }
     else
     {
         if (endAngle < startAngle)
         {
             return(endAngle + Angles.AngleCount - startAngle);
         }
         else
         {
             return(endAngle - startAngle);
         }
     }
 }
Example #3
0
 // Ensures that a set of vertices are wound in the desired winding order
 public void EnsureWindingOrder(WindingOrder windingOrder)
 {
     if (!DetermineWindingOrder().Equals(windingOrder))
     {
         ReverseWindingOrder();
     }
 }
Example #4
0
        public override Vertices GenerateAroundCentroid(Vector2 centroid, float vertexAlignmentRay = 0, bool alignAroundRay = true,
                                                        WindingOrder windingOrder = WindingOrder.CounterClockwise)
        {
            var vertices            = GenerateFromInitial(Vector2.Zero, 0, windingOrder);
            var transformedVertices = new List <Vector2>(NumVertices);

            var currentCentroid = new Vector2();

            currentCentroid  = vertices.Aggregate(currentCentroid, (current, tempVertex) => (Vector2)(current + tempVertex));
            currentCentroid *= 1f / NumVertices;

            for (int i = 0; i < NumVertices; i++)
            {
                transformedVertices.Add((Vector2)vertices[i]);
                transformedVertices[i] -= currentCentroid;
            }

            float alignmentAngle = vertexAlignmentRay - (alignAroundRay
                                       ? (transformedVertices[0].Direction + transformedVertices[1].Direction) / 2
                                       : transformedVertices[0].Direction);

            vertices = new Vertices(transformedVertices);
            var transform = new Transform();

            transform.Rotate(alignmentAngle);
            transform.Translate(centroid);

            return(transform.ApplyTransform(vertices));
        }
        //-----------------------------------------------------------------------------
        // Constructor
        //-----------------------------------------------------------------------------

        public PlayerSpinSwordState()
        {
            limitTilesToDirection = false;
            isReswingable         = false;

            lunge = false;
            swingAnglePullBack   = 0;
            swingAngleDurations  = new int[] { 3, 2, 3, 2, 3, 2, 3, 2, 5 };
            weaponSwingAnimation = GameData.ANIM_SWORD_SPIN;
            playerSwingAnimation = GameData.ANIM_PLAYER_SPIN;

            // Will always spin clockwise.
            swingWindingOrders = new WindingOrder[] {
                WindingOrder.Clockwise,
                WindingOrder.Clockwise,
                WindingOrder.Clockwise,
                WindingOrder.Clockwise
            };

            swingCollisionBoxesNoLunge = new Rectangle2I[4, 9];
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    int angle = GMath.Wrap((i * 2) - j, Angles.AngleCount);
                    swingCollisionBoxesNoLunge[i, j] = SWING_TOOL_BOXES_SPIN[angle];
                }
            }
        }
        //-----------------------------------------------------------------------------
        // Constructor
        //-----------------------------------------------------------------------------
        public PlayerSpinSwordState()
        {
            limitTilesToDirection	= false;
            isReswingable			= false;

            lunge					= false;
            swingAnglePullBack		= 0;
            swingAngleDurations		= new int[] { 3, 2, 3, 2, 3, 2, 3, 2, 5 };
            weaponSwingAnimation	= GameData.ANIM_SWORD_SPIN;
            playerSwingAnimation	= GameData.ANIM_PLAYER_SPIN;

            // Will always spin clockwise.
            swingWindingOrders = new WindingOrder[] {
                WindingOrder.Clockwise,
                WindingOrder.Clockwise,
                WindingOrder.Clockwise,
                WindingOrder.Clockwise
            };

            swingCollisionBoxesNoLunge = new Rectangle2I[4, 9];
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 9; j++) {
                    int angle = GMath.Wrap((i * 2) - j, Angles.AngleCount);
                    swingCollisionBoxesNoLunge[i, j] = SWING_TOOL_BOXES_SPIN[angle];
                }
            }
        }
Example #7
0
 //-----------------------------------------------------------------------------
 // Methods
 //-----------------------------------------------------------------------------
 public static int Add(int direction, int addAmount, WindingOrder windingOrder)
 {
     if (windingOrder == WindingOrder.Clockwise)
         direction -= addAmount;
     else
         direction += addAmount;
     return GMath.Wrap(direction, Directions.Count);
 }
Example #8
0
 //-----------------------------------------------------------------------------
 // Methods
 //-----------------------------------------------------------------------------
 public static int Add(int angle, int addAmount, WindingOrder windingOrder)
 {
     if (windingOrder == WindingOrder.Clockwise)
         angle -= addAmount;
     else
         angle += addAmount;
     return GMath.Wrap(angle, Angles.AngleCount);
 }
Example #9
0
        /// <summary>
        /// Ensures that a set of vertices are wound in a particular order, reversing them if necessary.
        /// </summary>
        /// <param name="vertices">The vertices of the polygon.</param>
        /// <param name="windingOrder">The desired winding order.</param>
        /// <returns>A new set of vertices if the winding order didn't match; otherwise the original set.</returns>
        public static Vector2[] EnsureWindingOrder(Vector2[] vertices, WindingOrder windingOrder)
        {
            if (DetermineWindingOrder(vertices) != windingOrder)
            {
                return(ReverseWindingOrder(vertices));
            }

            return(vertices);
        }
Example #10
0
 public MaskedMeshParamters(UnityHeightMap heightMap, UnityHeightMap maskMap, float maskThreshold, int meshResolution, Vector3 meshScale, int meshType, WindingOrder winding)
 {
     Heightmap      = heightMap;
     Maskmap        = maskMap;
     MaskThreshold  = maskThreshold;
     MeshResolution = meshResolution;
     MeshScale      = meshScale;
     MeshType       = meshType;
     Winding        = winding;
 }
Example #11
0
        //-----------------------------------------------------------------------------
        // Methods
        //-----------------------------------------------------------------------------

        public static int Add(int direction, int addAmount, WindingOrder windingOrder)
        {
            if (windingOrder == WindingOrder.Clockwise)
            {
                direction -= addAmount;
            }
            else
            {
                direction += addAmount;
            }
            return(GMath.Wrap(direction, Directions.Count));
        }
Example #12
0
 public VoxelizationInput()
 {
     m_voxelLevel    = 6;
     m_minVolume     = 0.65f;
     m_minOcclusion  = 0.03f;
     m_type          = OcclusionType.BoxExpansion;
     m_retriangulate = true;
     m_removeTop     = false;
     m_removeBottom  = false;
     m_upAxis        = UpAxis.Y;
     m_windingOrder  = WindingOrder.CounterClockwise;
 }
Example #13
0
        //-----------------------------------------------------------------------------
        // Methods
        //-----------------------------------------------------------------------------

        public static int Add(int angle, int addAmount, WindingOrder windingOrder)
        {
            if (windingOrder == WindingOrder.Clockwise)
            {
                angle -= addAmount;
            }
            else
            {
                angle += addAmount;
            }
            return(GMath.Wrap(angle, Angles.AngleCount));
        }
Example #14
0
 public static int Subtract(int angle, int subtractAmount, WindingOrder windingOrder)
 {
     if (windingOrder == WindingOrder.Clockwise)
     {
         angle += subtractAmount;
     }
     else
     {
         angle -= subtractAmount;
     }
     return(GMath.Wrap(angle, Angles.AngleCount));
 }
Example #15
0
        /// <summary>
        /// Ensures that a set of vertices are wound in a particular order, reversing them if necessary.
        /// </summary>
        /// <param name="vertices">The vertices of the polygon.</param>
        /// <param name="windingOrder">The desired winding order.</param>
        /// <returns>A new set of vertices if the winding order didn't match; otherwise the original set.</returns>
        public static Vector2[] EnsureWindingOrder(Vector2[] vertices, WindingOrder windingOrder)
        {
            Log("Ensuring winding order of {0}...", windingOrder);
            if (DetermineWindingOrder(vertices) != windingOrder)
            {
                Log("Reversing vertices...");
                return(ReverseWindingOrder(vertices));
            }

            Log("No reversal needed.");
            return(vertices);
        }
Example #16
0
        /// <summary>
        /// Given a set of points ordered counter-clockwise along a contour, return triangle indexes.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="indexes"></param>
        /// <param name="convex">Triangulation may optionally be set to convex, which will result in some a convex shape.</param>
        /// <returns></returns>
        public static bool Triangulate(IList <Vector2> points, out List <int> indexes, bool convex = false)
        {
            indexes = new List <int>();

            int index = 0;

            Triangulatable soup = convex
                ? new PointSet(points.Select(x => new TriangulationPoint(x.x, x.y, index++)).ToList())
                : (Triangulatable) new Polygon(points.Select(x => new PolygonPoint(x.x, x.y, index++)));

            try
            {
                triangulationContext.Clear();
                triangulationContext.PrepareTriangulation(soup);
                DTSweep.Triangulate((DTSweepContext)triangulationContext);
            }
            catch (System.Exception e)
            {
                Log.Info("Triangulation failed: " + e.ToString());
                return(false);
            }

            foreach (DelaunayTriangle d in soup.Triangles)
            {
                if (d.Points[0].Index < 0 || d.Points[1].Index < 0 || d.Points[2].Index < 0)
                {
                    Log.Info("Triangulation failed: Additional vertices were inserted.");
                    return(false);
                }

                indexes.Add(d.Points[0].Index);
                indexes.Add(d.Points[1].Index);
                indexes.Add(d.Points[2].Index);
            }

            WindingOrder originalWinding = SurfaceTopology.GetWindingOrder(points);

            // if the re-triangulated first tri doesn't match the winding order of the original
            // vertices, flip 'em

            if (SurfaceTopology.GetWindingOrder(new Vector2[3]
            {
                points[indexes[0]],
                points[indexes[1]],
                points[indexes[2]],
            }) != originalWinding)
            {
                indexes.Reverse();
            }

            return(true);
        }
Example #17
0
        private void Swing(int direction)
        {
            swingDirection      = direction;
            swingAngleDirection = swingWindingOrders[swingDirection];
            swingAngleStart     = Directions.ToAngle(swingDirection);
            swingAngleStart     = Angles.Subtract(swingAngleStart, swingAnglePullBack, swingAngleDirection);
            swingAngle          = swingAngleStart;
            swingAngleIndex     = 0;

            player.Direction = direction;
            playerTool       = GetSwingTool();
            player.EquipTool(playerTool);
            playerTool.AnimationPlayer.SubStripIndex = direction;

            if (player.IsInMinecart)
            {
                playerTool.PlayAnimation(weaponSwingAnimation);
                player.Graphics.PlayAnimation(playerSwingAnimationInMinecart);
                swingCollisionBoxes = swingCollisionBoxesNoLunge;
            }
            else if (lunge)
            {
                playerTool.PlayAnimation(weaponSwingAnimationLunge);
                player.Graphics.PlayAnimation(playerSwingAnimationLunge);
                swingCollisionBoxes = swingCollisionBoxesLunge;
            }
            else
            {
                playerTool.PlayAnimation(weaponSwingAnimation);
                player.Graphics.PlayAnimation(playerSwingAnimation);
                swingCollisionBoxes = swingCollisionBoxesNoLunge;
            }

            OnSwingBegin();

            // Perform an initial swing tile peak.
            Vector2F hitPoint        = player.Center + (Angles.ToVector(swingAngle, false) * 13);
            Point2I  hitTileLocation = player.RoomControl.GetTileLocation(hitPoint);

            OnSwingTilePeak(swingAngle, hitTileLocation);

            // Invoke any actions set to occur at time 0.
            if (timedActions.ContainsKey(0))
            {
                timedActions[0].Invoke();
            }

            Rectangle2I toolBox = swingCollisionBoxes[swingDirection, Math.Min(swingCollisionBoxes.Length - 1, swingAngleIndex)];

            toolBox.Point          += (Point2I)player.CenterOffset;
            playerTool.CollisionBox = toolBox;
        }
        public static void MenuConformNormals()
        {
            pb_Editor editor = pb_Editor.instance;

            if (editor == null)
            {
                return;                                 // this should be redundant, but y'know... safety first?
            }
            pb_Object[] selection = pbUtil.GetComponents <pb_Object>(Selection.transforms);

            pbUndo.RecordObjects(selection, "Conform " + (editor.selectedFaceCount > 0 ? "Face" : "Object") + " Normals.");

            foreach (pb_Object pb in selection)
            {
                pb_Face[] faces = pb.SelectedFaceCount > 0 ? pb.SelectedFaces : pb.faces;
                int       len   = faces.Length;

                int            toggle  = 0;
                WindingOrder[] winding = new WindingOrder[len];

                // First figure out what the majority of the faces' winding order is
                for (int i = 0; i < len; i++)
                {
                    winding[i] = pb.GetWindingOrder(faces[i]);
                    toggle    += (winding[i] == WindingOrder.Unknown ? 0: (winding[i] == WindingOrder.Clockwise ? 1 : -1));
                }

                int flipped = 0;

                // if toggle >= 0 wind clockwise, else ccw
                for (int i = 0; i < len; i++)
                {
                    if ((toggle >= 0 && winding[i] == WindingOrder.CounterClockwise) ||
                        (toggle < 0 && winding[i] == WindingOrder.Clockwise))
                    {
                        faces[i].ReverseIndices();
                        flipped++;
                    }
                }

                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();

                if (pb_Editor.instance != null)
                {
                    pb_Editor.instance.UpdateSelection();
                }

                pb_Editor_Utility.ShowNotification(flipped > 0 ? "Reversed " + flipped + " Faces" : "Normals Already Uniform");
            }
        }
Example #19
0
        public static FrontFaceDirection To(WindingOrder windingOrder)
        {
            switch (windingOrder)
            {
            case WindingOrder.Clockwise:
                return(FrontFaceDirection.Cw);

            case WindingOrder.Counterclockwise:
                return(FrontFaceDirection.Ccw);
            }

            throw new ArgumentException("windingOrder");
        }
		public static void MenuConformNormals()
		{
			pb_Editor editor = pb_Editor.instance;
			if(editor == null) return;	// this should be redundant, but y'know... safety first?

			pb_Object[] selection = pbUtil.GetComponents<pb_Object>(Selection.transforms);

			pbUndo.RecordObjects(selection, "Conform " + (editor.selectedFaceCount > 0 ? "Face" : "Object") + " Normals.");

			foreach(pb_Object pb in selection)
			{
				pb_Face[] faces = pb.SelectedFaceCount > 0 ? pb.SelectedFaces : pb.faces;
				int len = faces.Length;

				int toggle = 0;
				WindingOrder[] winding = new WindingOrder[len];

				// First figure out what the majority of the faces' winding order is
				for(int i = 0; i < len; i++)
				{
					winding[i] = pb.GetWindingOrder( faces[i] );
					toggle += (winding[i] == WindingOrder.Unknown ? 0: (winding[i] == WindingOrder.Clockwise ? 1 : -1));
				}

				int flipped = 0;

				// if toggle >= 0 wind clockwise, else ccw
				for(int i = 0; i < len; i++)
				{
					if( (toggle >= 0 && winding[i] == WindingOrder.CounterClockwise) ||
						(toggle < 0 && winding[i] == WindingOrder.Clockwise) )
					{
						faces[i].ReverseIndices();
						flipped++;
					}
				}

				pb.ToMesh();
				pb.Refresh();
				pb.Optimize();

				if(pb_Editor.instance != null)
					pb_Editor.instance.UpdateSelection();

				pb_Editor_Utility.ShowNotification(flipped > 0 ? "Reversed " + flipped + " Faces" : "Normals Already Uniform");
			}
		}
Example #21
0
 public void ToggleDirection()
 {
     if (windingOrder == WindingOrder.Clockwise)
     {
         windingOrder = WindingOrder.CounterClockwise;
         arrowsAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ARROWS_COUNTERCLOCKWISE);
         turnstileAnimationPlayer.SubStripIndex = 1;
         Properties.Set("clockwise", false);
     }
     else
     {
         windingOrder = WindingOrder.Clockwise;
         arrowsAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ARROWS_CLOCKWISE);
         turnstileAnimationPlayer.SubStripIndex = 0;
         Properties.Set("clockwise", true);
     }
 }
Example #22
0
        //-----------------------------------------------------------------------------
        // Overridden methods
        //-----------------------------------------------------------------------------

        public override void OnInitialize()
        {
            base.OnInitialize();

            // Create the turnstile collision model.
            // It loooks like this: (each character is a quarter-tile)
            // X    X
            //  X  X
            //   XX
            //   XX
            //  X  X
            // X    X

            CollisionModel = new CollisionModel();
            CollisionModel.AddBox(0, 0, 8, 8);
            CollisionModel.AddBox(8, 8, 8, 8);
            CollisionModel.AddBox(40, 0, 8, 8);
            CollisionModel.AddBox(32, 8, 8, 8);
            CollisionModel.AddBox(0, 40, 8, 8);
            CollisionModel.AddBox(8, 32, 8, 8);
            CollisionModel.AddBox(40, 40, 8, 8);
            CollisionModel.AddBox(32, 32, 8, 8);
            CollisionModel.AddBox(16, 16, 16, 16);             // center.

            SolidType     = TileSolidType.Solid;
            IsSolid       = true;
            turnDirection = -1;

            // Setup based on the winding order.
            windingOrder = (Properties.GetBoolean("clockwise", false) ?
                            WindingOrder.Clockwise : WindingOrder.CounterClockwise);

            if (windingOrder == WindingOrder.Clockwise)
            {
                arrowsAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ARROWS_CLOCKWISE);
                turnstileAnimationPlayer.SubStripIndex = 0;
            }
            else
            {
                arrowsAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ARROWS_COUNTERCLOCKWISE);
                turnstileAnimationPlayer.SubStripIndex = 1;
            }

            turnstileAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ROTATE_CLOCKWISE);
            turnstileAnimationPlayer.SkipToEnd();
        }
Example #23
0
        public override Vertices GenerateAroundCentroid(Vector2 centroid, float vertexAlignmentRay = 0,
                                                        bool alignAroundRay = true, WindingOrder windingOrder = WindingOrder.CounterClockwise)
        {
            float e = EdgeLength / 2;

            return(new Vertices(new[]
            {
                // front
                new Vector3(-e, -e, e),
                new Vector3(e, -e, e),
                new Vector3(e, e, e),
                new Vector3(-e, e, e),
                // back
                new Vector3(-e, -e, -e),
                new Vector3(e, -e, -e),
                new Vector3(e, e, -e),
                new Vector3(-e, e, -e)
            }));
        }
Example #24
0
        public override Vertices GenerateFromInitial(Vector2 initialVertex, float initialExteriorAngle = 0,
                                                     WindingOrder windingOrder = WindingOrder.CounterClockwise)
        {
            var tempSides    = new List <Complex>(NumVertices);
            var tempVertices = new List <Complex>(NumVertices)
            {
                (Complex)initialVertex, (Complex)initialVertex + SideLengths[0] * Math.Exp(initialExteriorAngle * Math.I)
            };

            tempSides.Add(SideLengths[0] * Math.Exp(initialExteriorAngle * Math.I));

            for (int i = 1; i < NumVertices - 1; i++)
            {
                tempSides.Add(tempSides[i - 1] * Math.Exp(ExteriorAngles[i - 1] * Math.I) * SideLengths[i] / tempSides[i - 1].Magnitude);
                tempVertices.Add(tempVertices[i] + tempSides[i]);
            }

            if (windingOrder == WindingOrder.Clockwise)
            {
                tempVertices.Reverse(1, NumVertices - 1);
            }

            return(new Vertices((from tempVertex in tempVertices select(Vector2) tempVertex).ToList()));
        }
Example #25
0
        /// <summary>
        /// Ensures that a set of vertices are wound in a particular order, reversing them if necessary.
        /// </summary>
        /// <param name="vertices">The vertices of the polygon.</param>
        /// <param name="windingOrder">The desired winding order.</param>
        /// <returns>A new set of vertices if the winding order didn't match; otherwise the original set.</returns>
        public static Vector2[] EnsureWindingOrder(Vector2[] vertices, WindingOrder windingOrder)
        {
            Log("\nEnsuring winding order of {0}...", windingOrder);
            if (DetermineWindingOrder(vertices) != windingOrder)
            {
                Log("Reversing vertices...");
                return ReverseWindingOrder(vertices);
            }

            Log("No reversal needed.");
            return vertices;
        }
Example #26
0
 public static int Subtract(int angle, int subtractAmount, WindingOrder windingOrder)
 {
     if (windingOrder == WindingOrder.Clockwise)
         angle += subtractAmount;
     else
         angle -= subtractAmount;
     return GMath.Wrap(angle, Angles.AngleCount);
 }
        private void Swing(int direction)
        {
            swingDirection		= direction;
            swingAngleDirection	= swingWindingOrders[swingDirection];
            swingAngleStart		= Directions.ToAngle(swingDirection);
            swingAngleStart		= Angles.Subtract(swingAngleStart, swingAnglePullBack, swingAngleDirection);
            swingAngle			= swingAngleStart;
            swingAngleIndex		= 0;

            player.Direction = direction;
            playerTool = GetSwingTool();
            player.EquipTool(playerTool);
            playerTool.AnimationPlayer.SubStripIndex = direction;

            if (player.IsInMinecart) {
                playerTool.PlayAnimation(weaponSwingAnimation);
                player.Graphics.PlayAnimation(playerSwingAnimationInMinecart);
                swingCollisionBoxes = swingCollisionBoxesNoLunge;
            }
            else if (lunge) {
                playerTool.PlayAnimation(weaponSwingAnimationLunge);
                player.Graphics.PlayAnimation(playerSwingAnimationLunge);
                swingCollisionBoxes = swingCollisionBoxesLunge;
            }
            else {
                playerTool.PlayAnimation(weaponSwingAnimation);
                player.Graphics.PlayAnimation(playerSwingAnimation);
                swingCollisionBoxes = swingCollisionBoxesNoLunge;
            }

            OnSwingBegin();

            // Perform an initial swing tile peak.
            Vector2F hitPoint = player.Center + (Angles.ToVector(swingAngle, false) * 13);
            Point2I hitTileLocation = player.RoomControl.GetTileLocation(hitPoint);
            OnSwingTilePeak(swingAngle, hitTileLocation);

            // Invoke any actions set to occur at time 0.
            if (timedActions.ContainsKey(0))
                timedActions[0].Invoke();

            Rectangle2I toolBox = swingCollisionBoxes[swingDirection, Math.Min(swingCollisionBoxes.Length - 1, swingAngleIndex)];
            toolBox.Point += (Point2I) player.CenterOffset;
            playerTool.CollisionBox = toolBox;
        }
        //-----------------------------------------------------------------------------
        // Overridden methods
        //-----------------------------------------------------------------------------
        public override void OnInitialize()
        {
            base.OnInitialize();

            // Create the turnstile collision model.
            // It loooks like this: (each character is a quarter-tile)
            // X    X
            //  X  X
            //   XX
            //   XX
            //  X  X
            // X    X

            CollisionModel = new CollisionModel();
            CollisionModel.AddBox( 0,  0, 8, 8);
            CollisionModel.AddBox( 8,  8, 8, 8);
            CollisionModel.AddBox(40,  0, 8, 8);
            CollisionModel.AddBox(32,  8, 8, 8);
            CollisionModel.AddBox( 0, 40, 8, 8);
            CollisionModel.AddBox( 8, 32, 8, 8);
            CollisionModel.AddBox(40, 40, 8, 8);
            CollisionModel.AddBox(32, 32, 8, 8);
            CollisionModel.AddBox(16, 16, 16, 16); // center.

            SolidType		= TileSolidType.Solid;
            IsSolid			= true;
            turnDirection	= -1;

            // Setup based on the winding order.
            windingOrder = (Properties.GetBoolean("clockwise", false) ?
                    WindingOrder.Clockwise : WindingOrder.CounterClockwise);

            if (windingOrder == WindingOrder.Clockwise) {
                arrowsAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ARROWS_CLOCKWISE);
                turnstileAnimationPlayer.SubStripIndex = 0;
            }
            else {
                arrowsAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ARROWS_COUNTERCLOCKWISE);
                turnstileAnimationPlayer.SubStripIndex = 1;
            }

            turnstileAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ROTATE_CLOCKWISE);
            turnstileAnimationPlayer.SkipToEnd();
        }
Example #29
0
 public abstract Vertices GenerateAroundCentroid(Vector2 centroid, float vertexAlignmentRay = 0,
                                                 bool alignAroundRay = true, WindingOrder windingOrder = WindingOrder.CounterClockwise);
Example #30
0
 public abstract Vertices GenerateFromInitial(Vector2 initialVertex, float initialExteriorAngle = 0,
                                              WindingOrder windingOrder = WindingOrder.CounterClockwise);
Example #31
0
 // Return the modular distance from one angle to another using the given winding order.
 public static float GetAngleDistance(float startAngle, float endAngle, WindingOrder windingOrder)
 {
     if (windingOrder == WindingOrder.Clockwise) {
     if (endAngle > startAngle)
         return (startAngle + GMath.FullAngle - endAngle);
     else
         return (startAngle - endAngle);
     }
     else {
     if (endAngle < startAngle)
         return (endAngle + GMath.FullAngle - startAngle);
     else
         return (endAngle - startAngle);
     }
 }
 public void ToggleDirection()
 {
     if (windingOrder == WindingOrder.Clockwise) {
         windingOrder = WindingOrder.CounterClockwise;
         arrowsAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ARROWS_COUNTERCLOCKWISE);
         turnstileAnimationPlayer.SubStripIndex = 1;
         Properties.Set("clockwise", false);
     }
     else {
         windingOrder = WindingOrder.Clockwise;
         arrowsAnimationPlayer.Play(GameData.ANIM_TURNSTILE_ARROWS_CLOCKWISE);
         turnstileAnimationPlayer.SubStripIndex = 0;
         Properties.Set("clockwise", true);
     }
 }
Example #33
0
        /// <summary>
        /// Triangulates a 2D polygon produced the indexes required to render the points as a triangle list.
        /// </summary>
        /// <param name="inputVertices">The polygon vertices in counter-clockwise winding order.</param>
        /// <param name="desiredWindingOrder">The desired output winding order.</param>
        /// <param name="outputVertices">The resulting vertices that include any reversals of winding order and holes.</param>
        /// <param name="indices">The resulting indices for rendering the shape as a triangle list.</param>
        public static void Triangulate(
			Vector2[] inputVertices,
			WindingOrder desiredWindingOrder,
			out Vector2[] outputVertices,
			out int[] indices)
        {
            Log("\nBeginning triangulation...");

            List<Triangle> triangles = new List<Triangle>();

            //make sure we have our vertices wound properly
            if (DetermineWindingOrder(inputVertices) == WindingOrder.Clockwise)
            {
                outputVertices = ReverseWindingOrder(inputVertices);

                System.Console.WriteLine(WindingOrder.Clockwise.ToString());
            }
            else
            {
                outputVertices = (Vector2[])inputVertices.Clone();
                System.Console.WriteLine(WindingOrder.CounterClockwise.ToString());
            }
            //clear all of the lists
            polygonVertices.Clear();
            earVertices.Clear();
            convexVertices.Clear();
            reflexVertices.Clear();

            //generate the cyclical list of vertices in the polygon
            for (int i = 0; i < outputVertices.Length; i++)
                polygonVertices.AddLast(new Vertex(outputVertices[i], i));

            //categorize all of the vertices as convex, reflex, and ear
            FindConvexAndReflexVertices();
            FindEarVertices();

            //clip all the ear vertices
            while (polygonVertices.Count > 3 && earVertices.Count > 0)
                ClipNextEar(triangles);

            //if there are still three points, use that for the last triangle
            if (polygonVertices.Count == 3)
                triangles.Add(new Triangle(
                    polygonVertices[0].Value,
                    polygonVertices[1].Value,
                    polygonVertices[2].Value));

            //add all of the triangle indices to the output array
            indices = new int[triangles.Count * 3];

            //move the if statement out of the loop to prevent all the
            //redundant comparisons
            if (desiredWindingOrder == WindingOrder.CounterClockwise)
            {
                for (int i = 0; i < triangles.Count; i++)
                {
                    indices[(i * 3)] = triangles[i].A.Index;
                    indices[(i * 3) + 1] = triangles[i].B.Index;
                    indices[(i * 3) + 2] = triangles[i].C.Index;
                }
            }
            else
            {
                for (int i = 0; i < triangles.Count; i++)
                {
                    indices[(i * 3)] = triangles[i].C.Index;
                    indices[(i * 3) + 1] = triangles[i].B.Index;
                    indices[(i * 3) + 2] = triangles[i].A.Index;
                }
            }
        }
Example #34
0
 // Return the modular distance from one angle to another using the given winding order.
 public static int GetAngleDistance(int startAngle, int endAngle, WindingOrder windingOrder)
 {
     if (windingOrder == WindingOrder.Clockwise) {
         if (endAngle > startAngle)
             return (startAngle + Angles.AngleCount - endAngle);
         else
             return (startAngle - endAngle);
     }
     else {
         if (endAngle < startAngle)
             return (endAngle + Angles.AngleCount - startAngle);
         else
             return (endAngle - startAngle);
     }
 }
        public void ControlFlow(string message, object someFoo, WindingOrder windingOrder)          // | Use c# aliases of System types (e.g. object instead of Object, float instead of Single, etc.)
        {
            for (int i = 0; i < k_MaxCount; ++i)                                                    // | Using i and j for trivial local iterators is encouraged
            {
                // all of this is nonsense, and is just meant to demonstrate formatting             // | Place comments about multiple lines of code directly above them, with one empty line above the comment to visually group it with its code
                if ((i % -3) - 1 == 0)                                                              // | Wrap parens around subexpressions is optional but recommended to make operator precedence clear
                {
                    ++m_CurrentCount;
                    s_SharedCount *= (int)k_DefaultLength.x + totalCount;

                    do                                                                              // | 'while', 'do', 'for', 'foreach', 'switch' are always on a separate line from the code block they control
                    {
                        i += s_SharedCount;
                    }while (i < m_CurrentCount);
                }
                else                                                                                // | 'else' always at same indentation level as its 'if'
                {
                    Debug.LogWarning("Skipping over " + i);                                         // | Drop 'ToString()' when not required by compiler
                    goto skip;                                                                      // | Goto's not necessarily considered harmful, not disallowed, but should be scrutinized for utility before usage
                }
            }

skip:       // | Goto label targets un-indented from parent scope one tab stop

            // more nonsense code for demo purposes
            switch (windingOrder)
            {
            case WindingOrder.Clockwise:                                                            // | Case labels indented under switch
            case WindingOrder.CounterClockwise:                                                     // | Braces optional if not needed for scope (but note indentation of braces and contents)
                if (s_SharedCount == DisplayData.MaxItems)                                          // | Constants go on the right in comparisons (do not follow 'yoda' style)
                {
                    var warningDetails = someFoo.ToString();                                        // | 'var' for the result of assignments is optional (either way, good variable naming is most important)
                    for (var i = 0; i < s_SharedCount; ++i)
                    {
                        Debug.LogWarning("Spinning a " + warningDetails);
                    }
                }
                break;                                                                              // | 'break' inside case braces, if any

            case WindingOrder.Charm:
                Debug.LogWarning("Check quark");                                                    // | Indentation is the same, with or without scope braces
                break;

            case WindingOrder.Singularity:
            {
                var warningDetails = message;                                                       // | (this seemingly pointless variable is here solely to require braces on the case statements and show the required formatting)

                if (message == Registry.ClassesRoot.ToString())
                {
                    // Already correct so we don't need to do anything here                     // | Empty blocks should (a) only be used when it helps readability, (b) always use empty braces (never a standalone semicolon), and (c) be commented as to why the empty block is there
                }
                else if (m_CurrentCount > 3)
                {
                    if (s_SharedCount < 10)                                                         // | Braces can only be omitted at the deepest level of nested code
                    {
                        Debug.LogWarning("Singularity! (" + warningDetails + ")");
                    }
                }
                else if (s_SharedCount > 5)                                                         // | 'else if' always on same line together
                {
                    throw new IndexOutOfRangeException();
                }
                else if ((s_SharedCount > 7 && m_CurrentCount != 0) || message == null)             // | Always wrap subexpressions in parens when peer precedence is close enough to be ambiguous (e.g. && and || are commonly confused)
                {
                    throw new NotImplementedException();
                }

                break;
            }

            default:
                throw new InvalidOperationException("What's a " + windingOrder + "?");
            }
        }
Example #36
0
        /// <summary>
        /// Ensures that a set of vertices are wound in a particular order, reversing them if necessary.
        /// </summary>
        /// <param name="vertices">The vertices of the polygon.</param>
        /// <param name="windingOrder">The desired winding order.</param>
        /// <returns>A new set of vertices if the winding order didn't match; otherwise the original set.</returns>
        public static Vector2[] EnsureWindingOrder(Vector2[] vertices, WindingOrder windingOrder)
        {
            if (DetermineWindingOrder(vertices) != windingOrder)
            {
                return ReverseWindingOrder(vertices);
            }

            return vertices;
        }
        public static FrontFaceDirection To(WindingOrder windingOrder)
        {
            switch (windingOrder)
            {
                case WindingOrder.Clockwise:
                    return FrontFaceDirection.Cw;
                case WindingOrder.Counterclockwise:
                    return FrontFaceDirection.Ccw;
            }

            throw new ArgumentException("windingOrder");
        }
Example #38
0
 private static extern MeshData FbxNodeGetMeshAttribute(IntPtr node, WindingOrder preferedWindingOrder, bool limitBoneWeights);
Example #39
0
 public override Vertices GenerateFromInitial(Vector2 initialVertex, float initialExteriorAngle = 0,
                                              WindingOrder windingOrder = WindingOrder.CounterClockwise)
 {
     return(GenerateAroundCentroid(Vector2.Zero));
 }
Example #40
0
        /// <summary>
        /// Triangulates a 2D polygon produced the indexes required to render the points as a triangle list.
        /// </summary>
        /// <param name="inputVertices">The polygon vertices in counter-clockwise winding order.</param>
        /// <param name="desiredWindingOrder">The desired output winding order.</param>
        /// <param name="outputVertices">The resulting vertices that include any reversals of winding order and holes.</param>
        /// <param name="indices">The resulting indices for rendering the shape as a triangle list.</param>
        public static void Triangulate(
            Vector2[] inputVertices,
            WindingOrder desiredWindingOrder,
            out Vector2[] outputVertices,
            out ushort[] indices)
        {
            Log("Beginning triangulation...");

            List <Triangle> triangles = new List <Triangle>();

            //make sure we have our vertices wound properly
            if (DetermineWindingOrder(inputVertices) == WindingOrder.Clockwise)
            {
                outputVertices = ReverseWindingOrder(inputVertices);
            }
            else
            {
                outputVertices = (Vector2[])inputVertices.Clone();
            }

            //clear all of the lists
            polygonVertices.Clear();
            earVertices.Clear();
            convexVertices.Clear();
            reflexVertices.Clear();

            //generate the cyclical list of vertices in the polygon
            for (int i = 0; i < outputVertices.Length; i++)
            {
                polygonVertices.AddLast(new Vertex(outputVertices[i], (ushort)i));
            }

            //categorize all of the vertices as convex, reflex, and ear
            FindConvexAndReflexVertices();
            FindEarVertices();

            //clip all the ear vertices
            while (polygonVertices.Count > 3 && earVertices.Count > 0)
            {
                ClipNextEar(triangles);
            }

            //if there are still three points, use that for the last triangle
            if (polygonVertices.Count == 3)
            {
                triangles.Add(new Triangle(
                                  polygonVertices[0].Value,
                                  polygonVertices[1].Value,
                                  polygonVertices[2].Value));
            }

            //add all of the triangle indices to the output array
            indices = new ushort[triangles.Count * 3];

            //move the if statement out of the loop to prevent all the
            //redundant comparisons
            if (desiredWindingOrder == WindingOrder.CounterClockwise)
            {
                for (int i = 0; i < triangles.Count; i++)
                {
                    indices[(i * 3)]     = triangles[i].A.Index;
                    indices[(i * 3) + 1] = triangles[i].B.Index;
                    indices[(i * 3) + 2] = triangles[i].C.Index;
                }
            }
            else
            {
                for (int i = 0; i < triangles.Count; i++)
                {
                    indices[(i * 3)]     = triangles[i].C.Index;
                    indices[(i * 3) + 1] = triangles[i].B.Index;
                    indices[(i * 3) + 2] = triangles[i].A.Index;
                }
            }
        }
Example #41
0
        public bool Open(string meshFile, WindingOrder order)
        {
            if (Context != null)
            {
                Context.Dispose();
                Context = null;
            }

            Context = new VoxelizationContext();

            try
            {
                IImporter importer = IOFactory.ImporterFactory(meshFile);
                Context.CurrentMeshFile = meshFile;
                Context.CurrentMesh     = importer.Load(meshFile);
            }
            catch (IOException)
            {
                Logger.DisplayError("Unable to open the file: " + meshFile);
                return(false);
            }

            Context.Octree = new VoxelizingOctree(Input.OctreeLevels);
            Context.Octree.GenerateOctree(Context.CurrentMesh);

            Vector4[] orignalVertices = new Vector4[Context.CurrentMesh.Vertices.Length];
            for (int i = 0; i < orignalVertices.Length; i++)
            {
                orignalVertices[i] = new Vector4(Context.CurrentMesh.Vertices[i], 1);
            }

            int[] originalIndicies = new int[Context.CurrentMesh.Tris.Length * 3];

            if (order == WindingOrder.CounterClockwise)
            {
                for (int i = 0; i < Context.CurrentMesh.Tris.Length; i++)
                {
                    Tri t     = Context.CurrentMesh.Tris[i];
                    int index = i * 3;
                    originalIndicies[index + 0] = t.P1.Vertex;
                    originalIndicies[index + 1] = t.P2.Vertex;
                    originalIndicies[index + 2] = t.P3.Vertex;
                }
            }
            else if (order == WindingOrder.Clockwise)
            {
                for (int i = 0; i < Context.CurrentMesh.Tris.Length; i++)
                {
                    Tri t     = Context.CurrentMesh.Tris[i];
                    int index = i * 3;
                    originalIndicies[index + 0] = t.P1.Vertex;
                    originalIndicies[index + 2] = t.P2.Vertex;
                    originalIndicies[index + 1] = t.P3.Vertex;
                }
            }

            if (Context.OriginalMesh != null)
            {
                Context.OriginalMesh.Dispose();
                Context.OriginalMesh = null;
            }

            Mesh mesh = new Mesh();

            mesh.Indicies = originalIndicies;
            mesh.Vertices = orignalVertices;

            Context.OriginalMesh = new RenderableMesh(mesh, true);

            return(true);
        }