public override List <CamViewState.SelObj> PickSelObjIn(int x, int y, int w, int h) { List <CamViewState.SelObj> result = new List <SelObj>(); RigidBody pickedCollider = null; ShapeInfo pickedShape = null; RigidBody[] visibleColliders = this.QueryVisibleColliders() .Where(r => !DesignTimeObjectData.Get(r.GameObj).IsLocked) .ToArray(); visibleColliders.StableSort(delegate(RigidBody c1, RigidBody c2) { return(MathF.RoundToInt(1000.0f * (c1.GameObj.Transform.Pos.Z - c2.GameObj.Transform.Pos.Z))); }); // Pick a collider foreach (RigidBody c in visibleColliders) { Vector3 worldCoord = this.GetSpaceCoord(new Vector3(x, y, c.GameObj.Transform.Pos.Z)); float scale = this.GetScaleAtZ(c.GameObj.Transform.Pos.Z); pickedShape = this.PickShapes(c, worldCoord.Xy, new Vector2(w / scale, h / scale)).FirstOrDefault(); if (pickedShape != null) { pickedCollider = c; result.Add(new SelBody(pickedCollider)); break; } else { pickedShape = null; } } // Pick shapes if (pickedCollider != null) { Vector3 worldCoord = this.GetSpaceCoord(new Vector3(x, y, pickedCollider.GameObj.Transform.Pos.Z)); float scale = this.GetScaleAtZ(pickedCollider.GameObj.Transform.Pos.Z); List <ShapeInfo> picked = this.PickShapes(pickedCollider, worldCoord.Xy, new Vector2(w / scale, h / scale)); if (picked.Count > 0) { result.AddRange(picked.Select(s => SelShape.Create(s) as SelObj)); } } return(result); }
public override ObjectEditorSelObj PickSelObjAt(int x, int y) { Component picked = this.PickRendererAt(x, y) as Component; if (picked == null) { return(null); } if (picked.Disposed) { return(null); } if (DesignTimeObjectData.Get(picked.GameObj).IsLocked) { return(null); } return(new SceneEditorSelGameObj(picked.GameObj)); }
public override CamViewState.SelObj PickSelObjAt(int x, int y) { RigidBody pickedCollider = null; ShapeInfo pickedShape = null; RigidBody[] visibleColliders = this.QueryVisibleColliders() .Where(r => !DesignTimeObjectData.Get(r.GameObj).IsLocked) .ToArray(); visibleColliders.StableSort(delegate(RigidBody c1, RigidBody c2) { return(MathF.RoundToInt(1000.0f * (c1.GameObj.Transform.Pos.Z - c2.GameObj.Transform.Pos.Z))); }); foreach (RigidBody c in visibleColliders) { Vector3 worldCoord = this.GetSpaceCoord(new Vector3(x, y, c.GameObj.Transform.Pos.Z)); // Do a physical picking operation pickedShape = this.PickShape(c, worldCoord.Xy); // Shape picked. if (pickedShape != null) { pickedCollider = c; break; } } if (pickedShape != null) { return(SelShape.Create(pickedShape)); } if (pickedCollider != null) { return(new SelBody(pickedCollider)); } return(null); }
private void UpdateHoverState() { this.activeShape = null; this.activeVertex = -1; this.activeEdge = -1; this.activeEdgeWorldPos = Vector2.Zero; RigidBody body = this.Environment.ActiveBody; if (body == null) { return; } DesignTimeObjectData designTimeData = DesignTimeObjectData.Get(body.GameObj); if (designTimeData.IsHidden) { return; } // Prepare the transform matrix for this object, so // we can move the RigidBody vertices into world space quickly Transform transform = body.GameObj.Transform; float bodyScale = transform.Scale; Vector2 bodyPos = transform.Pos.Xy; Vector2 bodyDotX; Vector2 bodyDotY; MathF.GetTransformDotVec(transform.Angle, bodyScale, out bodyDotX, out bodyDotY); Vector3 mousePosWorld = this.Environment.HoveredWorldPos; foreach (ShapeInfo shape in body.Shapes) { // Determine whether the cursor is hovering something it can interact with bool anythingHovered = false; float hotRadius = 8.0f; float worldHotRadius = hotRadius / MathF.Max(0.0001f, this.Environment.GetScaleAtZ(0.0f)); if (shape is CircleShapeInfo) { CircleShapeInfo circle = shape as CircleShapeInfo; // Determine world space position and radius of the circle shape float circleWorldRadius = circle.Radius * bodyScale; Vector2 circleWorldPos = circle.Position; MathF.TransformDotVec(ref circleWorldPos, ref bodyDotX, ref bodyDotY); circleWorldPos = bodyPos + circleWorldPos; float hoverDist = (circleWorldPos - mousePosWorld.Xy).Length; // Hovering the center if (hoverDist <= worldHotRadius) { this.activeVertex = 0; this.activeEdge = -1; this.activeEdgeWorldPos = circleWorldPos; anythingHovered = true; } // Hovering the edge else if (MathF.Abs(hoverDist - circleWorldRadius) <= worldHotRadius) { this.activeVertex = -1; this.activeEdge = 0; this.activeEdgeWorldPos = circleWorldPos + circleWorldRadius * (mousePosWorld.Xy - circleWorldPos).Normalized; anythingHovered = true; } } else { Vector2[] vertices = this.GetVertices(shape); if (vertices == null) { continue; } Vector2[] worldVertices = new Vector2[vertices.Length]; // Transform the shapes vertices into world space for (int index = 0; index < vertices.Length; index++) { Vector2 vertex = vertices[index]; MathF.TransformDotVec(ref vertex, ref bodyDotX, ref bodyDotY); worldVertices[index] = bodyPos + vertex; } anythingHovered = this.GetHoveredVertex(worldVertices, mousePosWorld.Xy, worldHotRadius, out this.activeVertex, out this.activeEdgeWorldPos) || this.GetHoveredEdge(worldVertices, mousePosWorld.Xy, worldHotRadius, out this.activeEdge, out this.activeEdgeWorldPos); } if (anythingHovered) { this.activeShape = shape; break; } } }
public override void OnWorldOverlayDrawcalls(Canvas canvas) { RigidBody body = this.Environment.ActiveBody; if (body == null) { return; } DesignTimeObjectData designTimeData = DesignTimeObjectData.Get(body.GameObj); if (designTimeData.IsHidden) { return; } float knobSize = 7.0f; float worldKnobSize = knobSize / MathF.Max(0.0001f, canvas.DrawDevice.GetScaleAtZ(0.0f)); // Determine the color in which we'll draw the interaction markers ColorRgba markerColor = this.Environment.FgColor; canvas.State.ZOffset = -1.0f; // Prepare the transform matrix for this object, so // we can move the RigidBody vertices into world space quickly Transform transform = body.GameObj.Transform; Vector2 bodyPos = transform.Pos.Xy; Vector2 bodyDotX; Vector2 bodyDotY; MathF.GetTransformDotVec(transform.Angle, transform.Scale, out bodyDotX, out bodyDotY); // Draw an interaction indicator for every vertex of the active bodies shapes Vector3 mousePosWorld = this.Environment.ActiveWorldPos; foreach (ShapeInfo shape in body.Shapes) { if (shape is CircleShapeInfo) { CircleShapeInfo circle = shape as CircleShapeInfo; Vector2 circleWorldPos = circle.Position; MathF.TransformDotVec(ref circleWorldPos, ref bodyDotX, ref bodyDotY); circleWorldPos = bodyPos + circleWorldPos; // Draw the circles center as a vertex if (this.activeVertex == 0 && this.activeShape == shape) { canvas.State.ColorTint = markerColor; } else { canvas.State.ColorTint = markerColor.WithAlpha(0.75f); } canvas.FillRect( circleWorldPos.X - worldKnobSize * 0.5f, circleWorldPos.Y - worldKnobSize * 0.5f, worldKnobSize, worldKnobSize); } else { Vector2[] vertices = this.GetVertices(shape); if (vertices == null) { continue; } Vector2[] worldVertices = new Vector2[vertices.Length]; // Transform the shapes vertices into world space for (int index = 0; index < vertices.Length; index++) { Vector2 vertex = vertices[index]; MathF.TransformDotVec(ref vertex, ref bodyDotX, ref bodyDotY); worldVertices[index] = bodyPos + vertex; } // Draw the vertices for (int i = 0; i < worldVertices.Length; i++) { if (this.activeVertex == i && this.activeShape == shape) { canvas.State.ColorTint = markerColor; } else { canvas.State.ColorTint = markerColor.WithAlpha(0.75f); } canvas.FillRect( worldVertices[i].X - worldKnobSize * 0.5f, worldVertices[i].Y - worldKnobSize * 0.5f, worldKnobSize, worldKnobSize); } } } // Interaction indicator for an existing vertex if (this.activeVertex != -1) { canvas.State.ColorTint = markerColor; canvas.DrawRect( this.activeEdgeWorldPos.X - worldKnobSize, this.activeEdgeWorldPos.Y - worldKnobSize, worldKnobSize * 2.0f, worldKnobSize * 2.0f); } // Interaction indicator for a vertex-to-be-created else if (this.activeEdge != -1) { canvas.State.ColorTint = markerColor.WithAlpha(0.35f); canvas.FillRect( this.activeEdgeWorldPos.X - worldKnobSize * 0.5f, this.activeEdgeWorldPos.Y - worldKnobSize * 0.5f, worldKnobSize * 1.0f, worldKnobSize * 1.0f); canvas.State.ColorTint = markerColor; canvas.DrawRect( this.activeEdgeWorldPos.X - worldKnobSize, this.activeEdgeWorldPos.Y - worldKnobSize, worldKnobSize * 2.0f, worldKnobSize * 2.0f); } }