Пример #1
0
        public static PolyShapeInfo CloneAndTransformShape(PolyShapeInfo poly, Transform xform, Vector2 spriteSize, SpriteRenderer.FlipMode flip)
        {
            MathF.GetTransformDotVec(xform.Angle, xform.Scale, out var xDot, out var yDot);
            var shape  = new PolyShapeInfo();
            var center = spriteSize / 2;
            var verts  = poly.Vertices.Select(v =>
            {
                v = v * PhysicsUnit.LengthToDuality - center;
                if (flip.HasFlag(SpriteRenderer.FlipMode.Horizontal))
                {
                    v.X *= -1;
                }
                if (flip.HasFlag(SpriteRenderer.FlipMode.Vertical))
                {
                    v.Y *= -1;
                }
                //Vector2.Transform(ref v, ref matrix, out var v2);
                MathF.TransformDotVec(ref v, ref xDot, ref yDot);
                v += xform.Pos.Xy;
                return(v);
            });

            if (flip.HasFlag(SpriteRenderer.FlipMode.Horizontal) ^ flip.HasFlag(SpriteRenderer.FlipMode.Vertical))
            {
                verts = verts.Reverse();
            }
            shape.Vertices = verts.ToArray();
            return(shape);
        }
Пример #2
0
        protected override void OnCollectStateDrawcalls(Canvas canvas)
        {
            base.OnCollectStateDrawcalls(canvas);

            GameObject selGameObj   = this.selectedBody != null ? this.selectedBody.GameObj : null;
            Transform  selTransform = selGameObj != null ? selGameObj.Transform : null;

            if (selTransform == null)
            {
                return;
            }

            if (this.mouseState == CursorState.CreatePolygon)
            {
                SelPolyShape selPolyShape = this.allObjSel.OfType <SelPolyShape>().FirstOrDefault();
                if (selPolyShape != null)
                {
                    PolyShapeInfo polyShape      = selPolyShape.ActualObject as PolyShapeInfo;
                    Vector2       lockedPos      = this.createPolyIndex > 0 ? polyShape.Vertices[this.createPolyIndex - 1] : Vector2.Zero;
                    Vector3       lockedPosWorld = selTransform.GetWorldPoint(new Vector3(lockedPos));
                    this.DrawLockedAxes(canvas, lockedPosWorld.X, lockedPosWorld.Y, lockedPosWorld.Z, polyShape.AABB.BoundingRadius * 4);
                }
            }
            else if (this.mouseState == CursorState.CreateLoop)
            {
                SelLoopShape selLoopShape = this.allObjSel.OfType <SelLoopShape>().FirstOrDefault();
                if (selLoopShape != null)
                {
                    LoopShapeInfo loopShape      = selLoopShape.ActualObject as LoopShapeInfo;
                    Vector2       lockedPos      = this.createPolyIndex > 0 ? loopShape.Vertices[this.createPolyIndex - 1] : Vector2.Zero;
                    Vector3       lockedPosWorld = selTransform.GetWorldPoint(new Vector3(lockedPos));
                    this.DrawLockedAxes(canvas, lockedPosWorld.X, lockedPosWorld.Y, lockedPosWorld.Z, loopShape.AABB.BoundingRadius * 4);
                }
            }
        }
Пример #3
0
        private void DrawShapeOutline(Canvas canvas, Transform transform, PolyShapeInfo shape)
        {
            Vector3 pos   = transform.Pos;
            float   angle = transform.Angle;
            float   scale = transform.Scale;

            if (this.wrapTexture)
            {
                Rect pointBoundingRect = shape.Vertices.BoundingBox();
                canvas.State.TextureCoordinateRect = new Rect(
                    pointBoundingRect.W / canvas.State.TextureBaseSize.X,
                    pointBoundingRect.H / canvas.State.TextureBaseSize.Y);
            }
            canvas.State.TransformAngle = angle;
            canvas.State.TransformScale = new Vector2(scale, scale);
            canvas.FillPolygonOutline(shape.Vertices, this.outlineWidth, pos.X, pos.Y, pos.Z);
        }
Пример #4
0
 private void DrawShapeArea(Canvas canvas, Transform transform, ShapeInfo shape)
 {
     canvas.PushState();
     if (shape is CircleShapeInfo)
     {
         this.DrawShapeArea(canvas, transform, shape as CircleShapeInfo);
     }
     else if (shape is PolyShapeInfo)
     {
         PolyShapeInfo polyShape = shape as PolyShapeInfo;
         Rect          bounds    = polyShape.Vertices.BoundingBox();
         Rect          texRect   = new Rect(1.0f, 1.0f);
         if (this.wrapTexture)
         {
             texRect.W = bounds.W / canvas.State.TextureBaseSize.X;
             texRect.H = bounds.H / canvas.State.TextureBaseSize.Y;
         }
         if (polyShape.ConvexPolygons != null)
         {
             foreach (Vector2[] convexPolygon in polyShape.ConvexPolygons)
             {
                 Rect localBounds  = convexPolygon.BoundingBox();
                 Rect localTexRect = new Rect(
                     texRect.X + texRect.W * (localBounds.X - bounds.X) / bounds.W,
                     texRect.Y + texRect.H * (localBounds.Y - bounds.Y) / bounds.H,
                     texRect.W * localBounds.W / bounds.W,
                     texRect.H * localBounds.H / bounds.H);
                 this.DrawShapeArea(canvas, transform, convexPolygon, localTexRect);
             }
         }
     }
     else if (shape is VertexBasedShapeInfo)
     {
         VertexBasedShapeInfo vertexShape = shape as VertexBasedShapeInfo;
         bool isSolid = (vertexShape.ShapeTraits & VertexShapeTrait.IsSolid) != VertexShapeTrait.None;
         if (isSolid || this.fillHollowShapes)
         {
             this.DrawShapeArea(canvas, transform, vertexShape.Vertices);
         }
     }
     canvas.PopState();
 }
Пример #5
0
        protected override string UpdateActionText()
        {
            Vector2 vertex = Vector2.Zero;

            if (this.mouseState == CursorState.CreatePolygon || this.mouseState == CursorState.CreateLoop)
            {
                Point        mousePos     = this.PointToClient(Cursor.Position);
                GameObject   selGameObj   = this.selectedBody != null ? this.selectedBody.GameObj : null;
                Transform    selTransform = selGameObj != null ? selGameObj.Transform : null;
                SelPolyShape selPolyShape = this.allObjSel.OfType <SelPolyShape>().FirstOrDefault();
                SelLoopShape selLoopShape = this.allObjSel.OfType <SelLoopShape>().FirstOrDefault();
                bool         hasData      = false;
                if (selPolyShape != null)
                {
                    PolyShapeInfo polyShape = selPolyShape.ActualObject as PolyShapeInfo;
                    vertex  = polyShape.Vertices[this.createPolyIndex];
                    hasData = true;
                }
                else if (selLoopShape != null)
                {
                    LoopShapeInfo loopShape = selLoopShape.ActualObject as LoopShapeInfo;
                    vertex  = loopShape.Vertices[this.createPolyIndex];
                    hasData = true;
                }
                else if (selTransform != null)
                {
                    Vector3 spaceCoord = this.GetSpaceCoord(new Vector3(mousePos.X, mousePos.Y, selTransform.Pos.Z));
                    vertex  = selTransform.GetLocalPoint(spaceCoord).Xy;
                    hasData = true;
                }

                if (hasData)
                {
                    return
                        (string.Format("Vertex X:{0,9:0.00}/n", vertex.X) +
                         string.Format("Vertex Y:{0,9:0.00}", vertex.Y));
                }
            }
            return(base.UpdateActionText());
        }
Пример #6
0
        private void DrawShape(Canvas canvas, Transform transform, PolyShapeInfo shape, ColorRgba fillColor, ColorRgba outlineColor)
        {
            if (shape.ConvexPolygons != null)
            {
                // Fill each convex polygon individually
                foreach (Vector2[] polygon in shape.ConvexPolygons)
                {
                    this.FillPolygon(canvas, transform, polygon, fillColor);
                }

                // Draw all convex polygon edges that are not outlines
                canvas.State.DepthOffset = this.depthOffset - 0.05f;
                this.DrawPolygonInternals(canvas, transform, shape.Vertices, shape.ConvexPolygons, outlineColor);
                canvas.State.DepthOffset = this.depthOffset;
            }


            // Draw the polygon outline
            canvas.State.DepthOffset = this.depthOffset - 0.1f;
            this.DrawPolygonOutline(canvas, transform, shape.Vertices, outlineColor, true);
            canvas.State.DepthOffset = this.depthOffset;
        }
        protected internal override void OnCollectDrawcalls(Canvas canvas)
        {
            base.OnCollectDrawcalls(canvas);
            List <RigidBody> visibleColliders = this.QueryVisibleColliders().ToList();

            RigidBody selectedBody = this.QuerySelectedCollider();

            canvas.State.TextFont           = Font.GenericMonospace10;
            canvas.State.TextInvariantScale = true;
            canvas.State.ZOffset            = -1;
            Font textFont = canvas.State.TextFont.Res;

            // Draw Shape layer
            foreach (RigidBody c in visibleColliders)
            {
                if (!c.Shapes.Any())
                {
                    continue;
                }
                float   colliderAlpha = c == selectedBody ? 1.0f : (selectedBody != null ? 0.25f : 0.5f);
                float   maxDensity    = c.Shapes.Max(s => s.Density);
                float   minDensity    = c.Shapes.Min(s => s.Density);
                float   avgDensity    = (maxDensity + minDensity) * 0.5f;
                Vector3 colliderPos   = c.GameObj.Transform.Pos;
                float   colliderScale = c.GameObj.Transform.Scale;
                int     index         = 0;
                foreach (ShapeInfo s in c.Shapes)
                {
                    CircleShapeInfo circle = s as CircleShapeInfo;
                    PolyShapeInfo   poly   = s as PolyShapeInfo;
                    //	EdgeShapeInfo edge = s as EdgeShapeInfo;
                    LoopShapeInfo loop = s as LoopShapeInfo;

                    ObjectEditorCamViewState editorState = this.View.ActiveState as ObjectEditorCamViewState;
                    float     shapeAlpha      = colliderAlpha * (selectedBody == null || editorState == null || editorState.SelectedObjects.Any(sel => sel.ActualObject == s) ? 1.0f : 0.5f);
                    float     densityRelative = MathF.Abs(maxDensity - minDensity) < 0.01f ? 1.0f : s.Density / avgDensity;
                    ColorRgba clr             = s.IsSensor ? this.ShapeSensorColor : this.ShapeColor;
                    ColorRgba fontClr         = this.FgColor;
                    Vector2   center          = Vector2.Zero;

                    if (!c.IsAwake)
                    {
                        clr = clr.ToHsva().WithSaturation(0.0f).ToRgba();
                    }
                    if (!s.IsValid)
                    {
                        clr = this.ShapeErrorColor;
                    }

                    if (circle != null)
                    {
                        Vector2 circlePos = circle.Position * colliderScale;
                        MathF.TransformCoord(ref circlePos.X, ref circlePos.Y, c.GameObj.Transform.Angle);

                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr.WithAlpha((0.25f + densityRelative * 0.25f) * shapeAlpha)));
                        canvas.FillCircle(
                            colliderPos.X + circlePos.X,
                            colliderPos.Y + circlePos.Y,
                            colliderPos.Z,
                            circle.Radius * colliderScale);
                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr.WithAlpha(shapeAlpha)));
                        canvas.DrawCircle(
                            colliderPos.X + circlePos.X,
                            colliderPos.Y + circlePos.Y,
                            colliderPos.Z,
                            circle.Radius * colliderScale);

                        center = circlePos;
                    }
                    else if (poly != null)
                    {
                        Vector2[] polyVert = poly.Vertices.ToArray();
                        for (int i = 0; i < polyVert.Length; i++)
                        {
                            center += polyVert[i];
                            Vector2.Multiply(ref polyVert[i], colliderScale, out polyVert[i]);
                            MathF.TransformCoord(ref polyVert[i].X, ref polyVert[i].Y, c.GameObj.Transform.Angle);
                        }
                        center /= polyVert.Length;
                        Vector2.Multiply(ref center, colliderScale, out center);
                        MathF.TransformCoord(ref center.X, ref center.Y, c.GameObj.Transform.Angle);

                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr.WithAlpha((0.25f + densityRelative * 0.25f) * shapeAlpha)));
                        canvas.FillPolygon(polyVert, colliderPos.X, colliderPos.Y, colliderPos.Z);
                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr.WithAlpha(shapeAlpha)));
                        canvas.DrawPolygon(polyVert, colliderPos.X, colliderPos.Y, colliderPos.Z);
                    }
                    else if (loop != null)
                    {
                        Vector2[] loopVert = loop.Vertices.ToArray();
                        for (int i = 0; i < loopVert.Length; i++)
                        {
                            center += loopVert[i];
                            Vector2.Multiply(ref loopVert[i], colliderScale, out loopVert[i]);
                            MathF.TransformCoord(ref loopVert[i].X, ref loopVert[i].Y, c.GameObj.Transform.Angle);
                        }
                        center /= loopVert.Length;
                        Vector2.Multiply(ref center, colliderScale, out center);
                        MathF.TransformCoord(ref center.X, ref center.Y, c.GameObj.Transform.Angle);

                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr.WithAlpha(shapeAlpha)));
                        canvas.DrawPolygon(loopVert, colliderPos.X, colliderPos.Y, colliderPos.Z);
                    }

                    // Draw shape index
                    if (c == selectedBody)
                    {
                        Vector2 textSize = textFont.MeasureText(index.ToString(CultureInfo.InvariantCulture));
                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, fontClr.WithAlpha((shapeAlpha + 1.0f) * 0.5f)));
                        canvas.State.TransformHandle = textSize * 0.5f;
                        canvas.DrawText(index.ToString(CultureInfo.InvariantCulture),
                                        colliderPos.X + center.X,
                                        colliderPos.Y + center.Y,
                                        colliderPos.Z);
                        canvas.State.TransformHandle = Vector2.Zero;
                    }

                    index++;
                }

                // Draw center of mass
                if (c.BodyType == BodyType.Dynamic)
                {
                    Vector2 localMassCenter = c.LocalMassCenter;
                    MathF.TransformCoord(ref localMassCenter.X, ref localMassCenter.Y, c.GameObj.Transform.Angle, c.GameObj.Transform.Scale);
                    canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, this.MassCenterColor.WithAlpha(colliderAlpha)));
                    canvas.DrawLine(
                        colliderPos.X + localMassCenter.X - 5.0f,
                        colliderPos.Y + localMassCenter.Y,
                        colliderPos.Z,
                        colliderPos.X + localMassCenter.X + 5.0f,
                        colliderPos.Y + localMassCenter.Y,
                        colliderPos.Z);
                    canvas.DrawLine(
                        colliderPos.X + localMassCenter.X,
                        colliderPos.Y + localMassCenter.Y - 5.0f,
                        colliderPos.Z,
                        colliderPos.X + localMassCenter.X,
                        colliderPos.Y + localMassCenter.Y + 5.0f,
                        colliderPos.Z);
                }
            }
        }
Пример #8
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            Transform selTransform = this.selectedBody != null && this.selectedBody.GameObj != null ? this.selectedBody.GameObj.Transform : null;
            Vector3   spaceCoord   = selTransform != null?this.GetSpaceCoord(new Vector3(e.X, e.Y, selTransform.Pos.Z)) : Vector3.Zero;

            Vector2 localPos = selTransform != null?selTransform.GetLocalPoint(spaceCoord).Xy : Vector2.Zero;

            if (this.mouseState != CursorState.Normal)
            {
                this.UpdateCursorImage();
            }

            if (this.mouseState == CursorState.CreatePolygon && this.allObjSel.Any(sel => sel is SelPolyShape))
            {
                SelPolyShape   selPolyShape = this.allObjSel.OfType <SelPolyShape>().First();
                PolyShapeInfo  polyShape    = selPolyShape.ActualObject as PolyShapeInfo;
                List <Vector2> vertices     = polyShape.Vertices.ToList();
                Vector2        lockedPos    = this.createPolyIndex > 0 ? vertices[this.createPolyIndex - 1] : Vector2.Zero;
                MathF.TransformCoord(ref lockedPos.X, ref lockedPos.Y, selTransform.Angle);
                MathF.TransformCoord(ref localPos.X, ref localPos.Y, selTransform.Angle);
                localPos = this.ApplyAxisLock(localPos, lockedPos);
                MathF.TransformCoord(ref localPos.X, ref localPos.Y, -selTransform.Angle);

                vertices[this.createPolyIndex] = localPos;

                polyShape.Vertices = vertices.ToArray();
                selPolyShape.UpdatePolyStats();

                // Update the body directly after modifying it
                this.selectedBody.SynchronizeBodyShape();

                DualityEditorApp.NotifyObjPropChanged(this,
                                                      new ObjectSelection(this.selectedBody),
                                                      ReflectionInfo.Property_RigidBody_Shapes);
            }
            else if (this.mouseState == CursorState.CreateLoop && this.allObjSel.Any(sel => sel is SelLoopShape))
            {
                SelLoopShape   selPolyShape = this.allObjSel.OfType <SelLoopShape>().First();
                LoopShapeInfo  polyShape    = selPolyShape.ActualObject as LoopShapeInfo;
                List <Vector2> vertices     = polyShape.Vertices.ToList();
                Vector2        lockedPos    = this.createPolyIndex > 0 ? vertices[this.createPolyIndex - 1] : Vector2.Zero;
                MathF.TransformCoord(ref lockedPos.X, ref lockedPos.Y, selTransform.Angle);
                MathF.TransformCoord(ref localPos.X, ref localPos.Y, selTransform.Angle);
                localPos = this.ApplyAxisLock(localPos, lockedPos);
                MathF.TransformCoord(ref localPos.X, ref localPos.Y, -selTransform.Angle);

                vertices[this.createPolyIndex] = localPos;

                polyShape.Vertices = vertices.ToArray();
                selPolyShape.UpdateLoopStats();

                // Update the body directly after modifying it
                this.selectedBody.SynchronizeBodyShape();

                DualityEditorApp.NotifyObjPropChanged(this,
                                                      new ObjectSelection(this.selectedBody),
                                                      ReflectionInfo.Property_RigidBody_Shapes);
            }
        }
Пример #9
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            GameObject selGameObj   = this.selectedBody != null ? this.selectedBody.GameObj : null;
            Transform  selTransform = selGameObj != null ? selGameObj.Transform : null;

            if (selTransform == null)
            {
                return;
            }

            Vector3 spaceCoord = this.GetSpaceCoord(new Vector3(e.X, e.Y, selTransform.Pos.Z));
            Vector2 localPos   = selTransform.GetLocalPoint(spaceCoord).Xy;

            if (this.mouseState == CursorState.CreateCircle)
            {
                #region CreateCircle
                if (e.Button == MouseButtons.Left)
                {
                    CircleShapeInfo newShape = new CircleShapeInfo(1.0f, localPos, 1.0f);

                    UndoRedoManager.BeginMacro();
                    UndoRedoManager.Do(new CreateRigidBodyShapeAction(this.selectedBody, newShape));

                    this.createAction = true;
                    this.LeaveCursorState();
                    this.SelectObjects(new[] { SelShape.Create(newShape) });
                    this.BeginAction(ObjectAction.Scale);
                }
                else if (e.Button == MouseButtons.Right)
                {
                    this.LeaveCursorState();
                }
                #endregion
            }
            else if (this.mouseState == CursorState.CreatePolygon)
            {
                #region CreatePolygon
                if (e.Button == MouseButtons.Left)
                {
                    bool success = false;
                    if (!this.allObjSel.Any(sel => sel is SelPolyShape))
                    {
                        PolyShapeInfo newShape = new PolyShapeInfo(new Vector2[] { localPos, localPos, localPos }, 1.0f);
                        UndoRedoManager.Do(new CreateRigidBodyShapeAction(this.selectedBody, newShape));
                        this.SelectObjects(new[] { SelShape.Create(newShape) });
                        this.createPolyIndex++;
                    }
                    else
                    {
                        SelPolyShape  selPolyShape = this.allObjSel.OfType <SelPolyShape>().First();
                        PolyShapeInfo polyShape    = selPolyShape.ActualObject as PolyShapeInfo;
                        if (this.createPolyIndex <= 2 || MathF.IsPolygonConvex(polyShape.Vertices))
                        {
                            Vector2 lockedPos = this.createPolyIndex > 0 ? polyShape.Vertices[this.createPolyIndex - 1] : Vector2.Zero;
                            MathF.TransformCoord(ref lockedPos.X, ref lockedPos.Y, selTransform.Angle);
                            MathF.TransformCoord(ref localPos.X, ref localPos.Y, selTransform.Angle);
                            localPos = this.ApplyAxisLock(localPos, lockedPos);
                            MathF.TransformCoord(ref localPos.X, ref localPos.Y, -selTransform.Angle);

                            if (polyShape.Vertices.Length < PolyShapeInfo.MaxVertices)
                            {
                                List <Vector2> vertices = polyShape.Vertices.ToList();

                                vertices[this.createPolyIndex] = localPos;
                                if (this.createPolyIndex >= vertices.Count - 1)
                                {
                                    vertices.Add(localPos);
                                }

                                polyShape.Vertices = vertices.ToArray();
                                selPolyShape.UpdatePolyStats();
                                this.createPolyIndex++;
                            }
                            else
                            {
                                Vector2[] vertices = polyShape.Vertices;

                                vertices[this.createPolyIndex] = localPos;
                                polyShape.Vertices             = vertices;
                                selPolyShape.UpdatePolyStats();

                                this.LeaveCursorState();
                            }
                        }
                    }

                    if (success)
                    {
                        DualityEditorApp.NotifyObjPropChanged(this,
                                                              new ObjectSelection(this.selectedBody),
                                                              ReflectionInfo.Property_RigidBody_Shapes);
                    }
                }
                else if (e.Button == MouseButtons.Right)
                {
                    if (this.allObjSel.Any(sel => sel is SelPolyShape))
                    {
                        SelPolyShape   selPolyShape = this.allObjSel.OfType <SelPolyShape>().First();
                        PolyShapeInfo  polyShape    = selPolyShape.ActualObject as PolyShapeInfo;
                        List <Vector2> vertices     = polyShape.Vertices.ToList();

                        vertices.RemoveAt(this.createPolyIndex);
                        if (vertices.Count < 3 || this.createPolyIndex < 2)
                        {
                            this.DeleteObjects(new SelPolyShape[] { selPolyShape });
                        }
                        else
                        {
                            polyShape.Vertices = vertices.ToArray();
                            selPolyShape.UpdatePolyStats();
                        }

                        DualityEditorApp.NotifyObjPropChanged(this,
                                                              new ObjectSelection(this.selectedBody),
                                                              ReflectionInfo.Property_RigidBody_Shapes);
                    }

                    this.LeaveCursorState();
                }
                #endregion
            }
            else if (this.mouseState == CursorState.CreateLoop)
            {
                #region CreateLoop
                if (e.Button == MouseButtons.Left)
                {
                    bool success = false;
                    if (!this.allObjSel.Any(sel => sel is SelLoopShape))
                    {
                        LoopShapeInfo newShape = new LoopShapeInfo(new Vector2[] { localPos, localPos + Vector2.UnitX, localPos + Vector2.One });
                        UndoRedoManager.Do(new CreateRigidBodyShapeAction(this.selectedBody, newShape));
                        this.SelectObjects(new[] { SelShape.Create(newShape) });
                        success = true;
                    }
                    else
                    {
                        SelLoopShape   selPolyShape = this.allObjSel.OfType <SelLoopShape>().First();
                        LoopShapeInfo  polyShape    = selPolyShape.ActualObject as LoopShapeInfo;
                        List <Vector2> vertices     = polyShape.Vertices.ToList();
                        Vector2        lockedPos    = this.createPolyIndex > 0 ? vertices[this.createPolyIndex - 1] : Vector2.Zero;
                        MathF.TransformCoord(ref lockedPos.X, ref lockedPos.Y, selTransform.Angle);
                        MathF.TransformCoord(ref localPos.X, ref localPos.Y, selTransform.Angle);
                        localPos = this.ApplyAxisLock(localPos, lockedPos);
                        MathF.TransformCoord(ref localPos.X, ref localPos.Y, -selTransform.Angle);

                        vertices[this.createPolyIndex] = localPos;
                        if (this.createPolyIndex >= vertices.Count - 1)
                        {
                            vertices.Add(localPos);
                        }

                        polyShape.Vertices = vertices.ToArray();
                        selPolyShape.UpdateLoopStats();
                        success = true;
                    }

                    if (success)
                    {
                        this.createPolyIndex++;
                        DualityEditorApp.NotifyObjPropChanged(this,
                                                              new ObjectSelection(this.selectedBody),
                                                              ReflectionInfo.Property_RigidBody_Shapes);
                    }
                }
                else if (e.Button == MouseButtons.Right)
                {
                    if (this.allObjSel.Any(sel => sel is SelLoopShape))
                    {
                        SelLoopShape   selPolyShape = this.allObjSel.OfType <SelLoopShape>().First();
                        LoopShapeInfo  polyShape    = selPolyShape.ActualObject as LoopShapeInfo;
                        List <Vector2> vertices     = polyShape.Vertices.ToList();

                        vertices.RemoveAt(this.createPolyIndex);
                        if (vertices.Count < 3 || this.createPolyIndex < 2)
                        {
                            this.DeleteObjects(new SelLoopShape[] { selPolyShape });
                        }
                        else
                        {
                            polyShape.Vertices = vertices.ToArray();
                            selPolyShape.UpdateLoopStats();
                        }

                        DualityEditorApp.NotifyObjPropChanged(this,
                                                              new ObjectSelection(this.selectedBody),
                                                              ReflectionInfo.Property_RigidBody_Shapes);
                    }

                    this.LeaveCursorState();
                }
                #endregion
            }
            //else if (this.mouseState == CursorState.CreateEdge)
            //{
            //    #region CreateEdge
            //    if (e.Button == MouseButtons.Left)
            //    {
            //        bool success = false;
            //        if (!this.allObjSel.Any(sel => sel is SelEdgeShape))
            //        {
            //            EdgeShapeInfo newShape = new EdgeShapeInfo(localPos, localPos + Vector2.UnitX);

            //            this.selectedCollider.AddShape(newShape);
            //            this.SelectObjects(new[] { SelShape.Create(newShape) });
            //            success = true;
            //        }
            //        else
            //        {
            //            SelEdgeShape selEdgeShape = this.allObjSel.OfType<SelEdgeShape>().First();
            //            EdgeShapeInfo edgeShape = selEdgeShape.ActualObject as EdgeShapeInfo;

            //            switch (this.createPolyIndex)
            //            {
            //                case 0:	edgeShape.VertexStart = localPos;	break;
            //                case 1:	edgeShape.VertexEnd = localPos;		break;
            //            }

            //            selEdgeShape.UpdateEdgeStats();
            //            success = true;
            //        }

            //        if (success)
            //        {
            //            this.createPolyIndex++;
            //            DualityEditorApp.NotifyObjPropChanged(this,
            //                new ObjectSelection(this.selectedCollider),
            //                ReflectionInfo.Property_RigidBody_Shapes);

            //            if (this.createPolyIndex >= 2)
            //                this.LeaveCursorState();
            //        }
            //    }
            //    else if (e.Button == MouseButtons.Right)
            //    {
            //        if (this.allObjSel.Any(sel => sel is SelEdgeShape))
            //        {
            //            SelEdgeShape selEdgeShape = this.allObjSel.OfType<SelEdgeShape>().First();
            //            EdgeShapeInfo edgeShape = selEdgeShape.ActualObject as EdgeShapeInfo;

            //            if (this.createPolyIndex < 1)
            //                this.DeleteObjects(new SelEdgeShape[] { selEdgeShape });
            //            else
            //                selEdgeShape.UpdateEdgeStats();

            //            DualityEditorApp.NotifyObjPropChanged(this,
            //                new ObjectSelection(this.selectedCollider),
            //                ReflectionInfo.Property_RigidBody_Shapes);
            //        }

            //        this.LeaveCursorState();
            //    }
            //    #endregion
            //}
        }
Пример #10
0
        protected internal override void OnCollectWorldOverlayDrawcalls(Canvas canvas)
        {
            base.OnCollectWorldOverlayDrawcalls(canvas);
            List <RigidBody> visibleColliders = this.QueryVisibleColliders().ToList();

            RigidBody selectedBody = this.QuerySelectedCollider();

            canvas.State.TextFont           = Font.GenericMonospace10;
            canvas.State.TextInvariantScale = true;
            canvas.State.ZOffset            = -0.5f;
            Font textFont = canvas.State.TextFont.Res;

            // Draw Shape layer
            foreach (RigidBody body in visibleColliders)
            {
                if (!body.Shapes.Any())
                {
                    continue;
                }
                float   colliderAlpha = body == selectedBody ? 1.0f : (selectedBody != null ? 0.25f : 0.5f);
                float   maxDensity    = body.Shapes.Max(s => s.Density);
                float   minDensity    = body.Shapes.Min(s => s.Density);
                float   avgDensity    = (maxDensity + minDensity) * 0.5f;
                Vector3 objPos        = body.GameObj.Transform.Pos;
                float   objAngle      = body.GameObj.Transform.Angle;
                float   objScale      = body.GameObj.Transform.Scale;
                int     index         = 0;
                foreach (ShapeInfo shape in body.Shapes)
                {
                    CircleShapeInfo circle = shape as CircleShapeInfo;
                    PolyShapeInfo   poly   = shape as PolyShapeInfo;
                    ChainShapeInfo  chain  = shape as ChainShapeInfo;
                    LoopShapeInfo   loop   = shape as LoopShapeInfo;

                    ObjectEditorCamViewState editorState = this.View.ActiveState as ObjectEditorCamViewState;
                    float     shapeAlpha      = colliderAlpha * (selectedBody == null || editorState == null || editorState.SelectedObjects.Any(sel => sel.ActualObject == shape) ? 1.0f : 0.5f);
                    float     densityRelative = MathF.Abs(maxDensity - minDensity) < 0.01f ? 1.0f : shape.Density / avgDensity;
                    ColorRgba clr             = shape.IsSensor ? this.ShapeSensorColor : this.ShapeColor;
                    ColorRgba fontClr         = this.FgColor;
                    Vector2   center          = Vector2.Zero;

                    if (!body.IsAwake)
                    {
                        clr = clr.ToHsva().WithSaturation(0.0f).ToRgba();
                    }
                    if (!shape.IsValid)
                    {
                        clr = this.ShapeErrorColor;
                    }

                    bool      fillShape     = (poly != null || circle != null);
                    Vector2[] shapeVertices = null;
                    if (poly != null)
                    {
                        shapeVertices = poly.Vertices;
                    }
                    else if (loop != null)
                    {
                        shapeVertices = loop.Vertices;
                    }
                    else if (chain != null)
                    {
                        shapeVertices = chain.Vertices;
                    }

                    if (circle != null)
                    {
                        Vector2 circlePos = circle.Position * objScale;
                        MathF.TransformCoord(ref circlePos.X, ref circlePos.Y, objAngle);

                        if (fillShape)
                        {
                            canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr.WithAlpha((0.25f + densityRelative * 0.25f) * shapeAlpha)));
                            canvas.FillCircle(
                                objPos.X + circlePos.X,
                                objPos.Y + circlePos.Y,
                                objPos.Z,
                                circle.Radius * objScale);
                        }
                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr.WithAlpha(shapeAlpha)));
                        canvas.DrawCircle(
                            objPos.X + circlePos.X,
                            objPos.Y + circlePos.Y,
                            objPos.Z,
                            circle.Radius * objScale);

                        center = circlePos;
                    }
                    else if (shapeVertices != null)
                    {
                        ColorRgba vertexFillColor    = canvas.State.ColorTint * clr.WithAlpha((0.25f + densityRelative * 0.25f) * shapeAlpha);
                        ColorRgba vertexOutlineColor = canvas.State.ColorTint * clr;

                        // Prepare vertices to submit. We can't use higher-level canvas functionality
                        // here, because we want direct control over the vertex mode.
                        float   viewSpaceScale = objScale;
                        Vector3 viewSpacePos   = objPos;
                        canvas.DrawDevice.PreprocessCoords(ref viewSpacePos, ref viewSpaceScale);
                        VertexC1P3T2[] drawVertices = new VertexC1P3T2[shapeVertices.Length];
                        for (int i = 0; i < drawVertices.Length; i++)
                        {
                            drawVertices[i].Pos.X = shapeVertices[i].X;
                            drawVertices[i].Pos.Y = shapeVertices[i].Y;
                            drawVertices[i].Pos.Z = 0.0f;
                            MathF.TransformCoord(ref drawVertices[i].Pos.X, ref drawVertices[i].Pos.Y, objAngle, viewSpaceScale);

                            drawVertices[i].Pos.X += viewSpacePos.X;
                            drawVertices[i].Pos.Y += viewSpacePos.Y;
                            drawVertices[i].Pos.Z += viewSpacePos.Z;
                            drawVertices[i].Color  = vertexOutlineColor;
                        }

                        // Calculate the center coordinate
                        for (int i = 0; i < drawVertices.Length; i++)
                        {
                            center += shapeVertices[i];
                        }
                        center /= shapeVertices.Length;
                        MathF.TransformCoord(ref center.X, ref center.Y, objAngle, objScale);

                        // Make sure to render using an alpha material
                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));

                        // Fill the shape
                        if (fillShape)
                        {
                            VertexC1P3T2[] fillVertices = drawVertices.Clone() as VertexC1P3T2[];
                            for (int i = 0; i < fillVertices.Length; i++)
                            {
                                fillVertices[i].Color = vertexFillColor;
                            }
                            canvas.DrawVertices(fillVertices, VertexMode.TriangleFan);
                        }

                        // Draw the outline
                        canvas.DrawVertices(drawVertices, shape is ChainShapeInfo ? VertexMode.LineStrip : VertexMode.LineLoop);
                    }

                    // Draw shape index
                    if (body == selectedBody)
                    {
                        string  indexText = index.ToString();
                        Vector2 textSize  = textFont.MeasureText(indexText);
                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, fontClr.WithAlpha((shapeAlpha + 1.0f) * 0.5f)));
                        canvas.DrawText(indexText,
                                        objPos.X + center.X,
                                        objPos.Y + center.Y,
                                        objPos.Z);
                    }

                    index++;
                }

                // Draw center of mass
                if (body.BodyType == BodyType.Dynamic)
                {
                    Vector2 localMassCenter = body.LocalMassCenter;
                    MathF.TransformCoord(ref localMassCenter.X, ref localMassCenter.Y, objAngle, objScale);
                    canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, this.MassCenterColor.WithAlpha(colliderAlpha)));
                    canvas.DrawLine(
                        objPos.X + localMassCenter.X - 5.0f,
                        objPos.Y + localMassCenter.Y,
                        objPos.Z,
                        objPos.X + localMassCenter.X + 5.0f,
                        objPos.Y + localMassCenter.Y,
                        objPos.Z);
                    canvas.DrawLine(
                        objPos.X + localMassCenter.X,
                        objPos.Y + localMassCenter.Y - 5.0f,
                        objPos.Z,
                        objPos.X + localMassCenter.X,
                        objPos.Y + localMassCenter.Y + 5.0f,
                        objPos.Z);
                }
            }
        }
Пример #11
0
 public RigidBodyEditorSelPolyShape(PolyShapeInfo shape) : base(shape)
 {
 }
 public SelPolyShape(PolyShapeInfo shape) : base(shape)
 {
     this.poly = shape;
     this.UpdatePolyStats();
 }
        protected internal override void OnCollectWorldOverlayDrawcalls(Canvas canvas)
        {
            base.OnCollectWorldOverlayDrawcalls(canvas);
            List <RigidBody> visibleColliders = this.QueryVisibleColliders().ToList();

            RigidBody selectedBody = this.QuerySelectedCollider();

            canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));
            canvas.State.TextFont           = Font.GenericMonospace10;
            canvas.State.TextInvariantScale = true;
            canvas.State.ZOffset            = this.depthOffset;
            Font textFont = canvas.State.TextFont.Res;

            // Retrieve selected shapes
            ObjectEditorCamViewState editorState = this.View.ActiveState as ObjectEditorCamViewState;

            object[] editorSelectedObjects = editorState != null?editorState.SelectedObjects.Select(item => item.ActualObject).ToArray() : new object[0];

            bool isAnyBodySelected  = (selectedBody != null);
            bool isAnyShapeSelected = isAnyBodySelected && editorSelectedObjects.OfType <ShapeInfo>().Any();

            // Draw Shape layer
            foreach (RigidBody body in visibleColliders)
            {
                if (!body.Shapes.Any())
                {
                    continue;
                }

                Vector3 objPos   = body.GameObj.Transform.Pos;
                float   objAngle = body.GameObj.Transform.Angle;
                float   objScale = body.GameObj.Transform.Scale;

                bool isBodySelected = (body == selectedBody);

                float bodyAlpha  = isBodySelected ? 1.0f : (isAnyBodySelected ? 0.5f : 1.0f);
                float maxDensity = body.Shapes.Max(s => s.Density);
                float minDensity = body.Shapes.Min(s => s.Density);
                float avgDensity = (maxDensity + minDensity) * 0.5f;

                int shapeIndex = 0;
                foreach (ShapeInfo shape in body.Shapes)
                {
                    CircleShapeInfo circle = shape as CircleShapeInfo;
                    PolyShapeInfo   poly   = shape as PolyShapeInfo;
                    ChainShapeInfo  chain  = shape as ChainShapeInfo;
                    LoopShapeInfo   loop   = shape as LoopShapeInfo;

                    bool isShapeSelected = isBodySelected && editorSelectedObjects.Contains(shape);

                    float     shapeAlpha      = bodyAlpha * (isShapeSelected ? 1.0f : (isAnyShapeSelected && isBodySelected ? 0.75f : 1.0f));
                    float     densityRelative = MathF.Abs(maxDensity - minDensity) < 0.01f ? 1.0f : shape.Density / avgDensity;
                    ColorRgba shapeColor      = shape.IsSensor ? this.ShapeSensorColor : this.ShapeColor;
                    ColorRgba fontColor       = this.FgColor;

                    if (!body.IsAwake)
                    {
                        shapeColor = shapeColor.ToHsva().WithSaturation(0.0f).ToRgba();
                    }
                    if (!shape.IsValid)
                    {
                        shapeColor = this.ShapeErrorColor;
                    }

                    // Draw the shape itself
                    ColorRgba fillColor    = shapeColor.WithAlpha((0.25f + densityRelative * 0.25f) * shapeAlpha);
                    ColorRgba outlineColor = ColorRgba.Lerp(shapeColor, fontColor, isShapeSelected ? 0.75f : 0.25f).WithAlpha(shapeAlpha);
                    this.DrawShape(canvas, body.GameObj.Transform, shape, fillColor, outlineColor);

                    // Calculate the center coordinate
                    Vector2 shapeCenter = Vector2.Zero;
                    if (circle != null)
                    {
                        shapeCenter = circle.Position * objScale;
                    }
                    else
                    {
                        Vector2[] shapeVertices = null;
                        if (poly != null)
                        {
                            shapeVertices = poly.Vertices;
                        }
                        else if (loop != null)
                        {
                            shapeVertices = loop.Vertices;
                        }
                        else if (chain != null)
                        {
                            shapeVertices = chain.Vertices;
                        }

                        for (int i = 0; i < shapeVertices.Length; i++)
                        {
                            shapeCenter += shapeVertices[i];
                        }

                        shapeCenter /= shapeVertices.Length;
                        MathF.TransformCoord(ref shapeCenter.X, ref shapeCenter.Y, objAngle, objScale);
                    }

                    // Draw shape index
                    if (body == selectedBody)
                    {
                        string  indexText = shapeIndex.ToString();
                        Vector2 textSize  = textFont.MeasureText(indexText);
                        canvas.State.ColorTint = fontColor.WithAlpha((shapeAlpha + 1.0f) * 0.5f);
                        canvas.DrawText(indexText,
                                        objPos.X + shapeCenter.X,
                                        objPos.Y + shapeCenter.Y,
                                        0.0f);
                    }

                    shapeIndex++;
                }

                // Draw center of mass
                if (body.BodyType == BodyType.Dynamic)
                {
                    Vector2 localMassCenter = body.LocalMassCenter;
                    MathF.TransformCoord(ref localMassCenter.X, ref localMassCenter.Y, objAngle, objScale);

                    float size = this.GetScreenConstantScale(canvas, 6.0f);

                    canvas.State.ColorTint = this.MassCenterColor.WithAlpha(bodyAlpha);
                    canvas.DrawLine(
                        objPos.X + localMassCenter.X - size,
                        objPos.Y + localMassCenter.Y,
                        0.0f,
                        objPos.X + localMassCenter.X + size,
                        objPos.Y + localMassCenter.Y,
                        0.0f);
                    canvas.DrawLine(
                        objPos.X + localMassCenter.X,
                        objPos.Y + localMassCenter.Y - size,
                        0.0f,
                        objPos.X + localMassCenter.X,
                        objPos.Y + localMassCenter.Y + size,
                        0.0f);
                }

                // Draw transform center
                if (body.BodyType == BodyType.Dynamic)
                {
                    float size = this.GetScreenConstantScale(canvas, 3.0f);
                    canvas.State.ColorTint = this.ObjectCenterColor.WithAlpha(bodyAlpha);
                    canvas.FillCircle(objPos.X, objPos.Y, 0.0f, size);
                }
            }
        }
Пример #14
0
 public SelVertex(PolyShapeInfo shape, int vertexIndex)
 {
     Guard.NotNull(shape, "A null shape was selected");
     this.shape = shape;
     this.index = vertexIndex;
 }