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); } } }
protected internal override void OnCollectWorldOverlayDrawcalls(Canvas canvas) { base.OnCollectWorldOverlayDrawcalls(canvas); List <RigidBody> visibleColliders = this.QueryVisibleColliders().ToList(); RigidBody selectedBody = this.QuerySelectedCollider(); canvas.State.SetMaterial(DrawTechnique.Alpha); canvas.State.TextFont = Font.GenericMonospace10; canvas.State.DepthOffset = 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) { 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 (shape is CircleShapeInfo) { CircleShapeInfo circleShape = shape as CircleShapeInfo; shapeCenter = circleShape.Position * objScale; } else if (shape is VertexBasedShapeInfo) { VertexBasedShapeInfo vertexShape = shape as VertexBasedShapeInfo; Vector2[] shapeVertices = vertexShape.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.State.TransformScale = Vector2.One / canvas.DrawDevice.GetScaleAtZ(0.0f); canvas.DrawText(indexText, objPos.X + shapeCenter.X, objPos.Y + shapeCenter.Y, 0.0f); canvas.State.TransformScale = Vector2.One; } 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 { float size = this.GetScreenConstantScale(canvas, 3.0f); canvas.State.ColorTint = this.ObjectCenterColor.WithAlpha(bodyAlpha); canvas.FillCircle(objPos.X, objPos.Y, 0.0f, size); } } }
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); } } }
protected internal override void OnCollectDrawcalls(Canvas canvas) { base.OnCollectDrawcalls(canvas); IDrawDevice device = canvas.DrawDevice; float scaleTemp = 1.0f; Vector3 posTemp = Vector3.Zero; device.PreprocessCoords(ref posTemp, ref scaleTemp); if (posTemp.Z <= canvas.DrawDevice.NearZ) { return; } float alphaTemp = 0.5f; alphaTemp *= (float)Math.Min(1.0d, ((posTemp.Z - device.NearZ) / (device.NearZ * 5.0f))); if (alphaTemp <= 0.005f) { return; } float stepTemp = 4.0f * this.gridSize * MathF.Max(0.25f, MathF.Pow(2.0f, -MathF.Round(1.0f - MathF.Log(1.0f / scaleTemp, 2.0f)))); float scaledStep = stepTemp * scaleTemp; float viewBoundRad = device.TargetSize.Length * 0.5f; int lineCount = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / scaledStep)) * 4; ColorRgba gridColor = this.FgColor.WithAlpha(alphaTemp); VertexC1P3[] vertices = new VertexC1P3[lineCount * 4]; float beginPos; float pos; int lineIndex; int vertOff = 0; beginPos = posTemp.X % scaledStep - (lineCount / 8) * scaledStep; pos = beginPos; lineIndex = 0; for (int x = 0; x < lineCount; x++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + x * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + x * 2 + 0].Pos.X = pos; vertices[vertOff + x * 2 + 0].Pos.Y = -viewBoundRad; vertices[vertOff + x * 2 + 0].Pos.Z = posTemp.Z + 1; vertices[vertOff + x * 2 + 1] = vertices[vertOff + x * 2 + 0]; vertices[vertOff + x * 2 + 1].Pos.Y = viewBoundRad; pos += scaledStep / 4; lineIndex++; } vertOff += lineCount * 2; beginPos = posTemp.Y % scaledStep - (lineCount / 8) * scaledStep; pos = beginPos; lineIndex = 0; for (int y = 0; y < lineCount; y++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + y * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + y * 2 + 0].Pos.X = -viewBoundRad; vertices[vertOff + y * 2 + 0].Pos.Y = pos; vertices[vertOff + y * 2 + 0].Pos.Z = posTemp.Z + 1; vertices[vertOff + y * 2 + 1] = vertices[vertOff + y * 2 + 0]; vertices[vertOff + y * 2 + 1].Pos.X = viewBoundRad; pos += scaledStep / 4; lineIndex++; } vertOff += lineCount * 2; device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.Lines, vertices); }
protected internal override void OnCollectDrawcalls(Canvas canvas) { base.OnCollectDrawcalls(canvas); IDrawDevice device = canvas.DrawDevice; float scaleTemp = 1.0f; Vector3 posTemp = Vector3.Zero; device.PreprocessCoords(ref posTemp, ref scaleTemp); if (posTemp.Z <= canvas.DrawDevice.NearZ) { return; } float alphaTemp = 0.5f; alphaTemp *= (float)Math.Min(1.0d, ((posTemp.Z - device.NearZ) / (device.NearZ * 5.0f))); if (alphaTemp <= 0.005f) { return; } ColorRgba gridColor = this.FgColor.WithAlpha(alphaTemp); float gridVisualMinSize = 50.0f; Vector2 gridBaseSize = this.View.EditingUserGuides.GridSize.Xy; if (gridBaseSize.X <= 0.0f) { gridBaseSize.X = 100.0f; } if (gridBaseSize.Y <= 0.0f) { gridBaseSize.Y = 100.0f; } Vector2 adjustedGridBaseSize; adjustedGridBaseSize.X = gridBaseSize.X * MathF.NextPowerOfTwo((int)MathF.Ceiling(gridVisualMinSize / gridBaseSize.X)); adjustedGridBaseSize.Y = gridBaseSize.Y * MathF.NextPowerOfTwo((int)MathF.Ceiling(gridVisualMinSize / gridBaseSize.Y)); float scaleAdjustmentFactor = 4.0f * MathF.Pow(2.0f, -MathF.Round(1.0f - MathF.Log(1.0f / scaleTemp, 2.0f))); Vector2 adjustedGridSize; adjustedGridSize.X = MathF.Max(adjustedGridBaseSize.X * scaleAdjustmentFactor, gridBaseSize.X); adjustedGridSize.Y = MathF.Max(adjustedGridBaseSize.Y * scaleAdjustmentFactor, gridBaseSize.Y); Vector2 stepTemp = adjustedGridSize; Vector2 scaledStep = stepTemp * scaleTemp; float viewBoundRad = device.TargetSize.Length * 0.5f; int lineCountX = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / scaledStep.X)) * 4; int lineCountY = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / scaledStep.Y)) * 4; int vertexCount = (lineCountX * 2 + lineCountY * 2); if (this.vertexBuffer == null) { this.vertexBuffer = new RawList <VertexC1P3>(vertexCount); } this.vertexBuffer.Count = vertexCount; VertexC1P3[] vertices = this.vertexBuffer.Data; float beginPos; float pos; int lineIndex; int vertOff = 0; beginPos = posTemp.X % scaledStep.X - (lineCountX / 8) * scaledStep.X; pos = beginPos; lineIndex = 0; for (int x = 0; x < lineCountX; x++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + x * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + x * 2 + 0].Pos.X = pos; vertices[vertOff + x * 2 + 0].Pos.Y = -viewBoundRad; vertices[vertOff + x * 2 + 0].Pos.Z = posTemp.Z + 1; vertices[vertOff + x * 2 + 1] = vertices[vertOff + x * 2 + 0]; vertices[vertOff + x * 2 + 1].Pos.Y = viewBoundRad; pos += scaledStep.X / 4; lineIndex++; } vertOff += lineCountX * 2; beginPos = posTemp.Y % scaledStep.Y - (lineCountY / 8) * scaledStep.Y; pos = beginPos; lineIndex = 0; for (int y = 0; y < lineCountY; y++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + y * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + y * 2 + 0].Pos.X = -viewBoundRad; vertices[vertOff + y * 2 + 0].Pos.Y = pos; vertices[vertOff + y * 2 + 0].Pos.Z = posTemp.Z + 1; vertices[vertOff + y * 2 + 1] = vertices[vertOff + y * 2 + 0]; vertices[vertOff + y * 2 + 1].Pos.X = viewBoundRad; pos += scaledStep.Y / 4; lineIndex++; } vertOff += lineCountY * 2; device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.Lines, vertices, this.vertexBuffer.Count); }
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); } }
protected internal override void OnCollectDrawcalls(Canvas canvas) { base.OnCollectDrawcalls(canvas); IDrawDevice device = canvas.DrawDevice; GridLayerData displayedData = default(GridLayerData); this.View.ActiveState.GetDisplayedGridData(Point.Empty, ref displayedData); float distanceToCamera = 0.0f - device.ViewerPos.Z; if (distanceToCamera <= device.NearZ) { return; } float alphaTemp = 0.5f; alphaTemp *= (float)Math.Min(1.0d, ((distanceToCamera - device.NearZ) / (device.NearZ * 5.0f))); if (alphaTemp <= 0.005f) { return; } ColorRgba gridColor = this.FgColor.WithAlpha(alphaTemp); float gridVisualMinSize = 50.0f; Vector2 gridBaseSize = displayedData.GridBaseSize; if (gridBaseSize.X <= 0.0f) { gridBaseSize.X = 100.0f; } if (gridBaseSize.Y <= 0.0f) { gridBaseSize.Y = 100.0f; } Vector2 adjustedGridBaseSize; adjustedGridBaseSize.X = gridBaseSize.X * MathF.NextPowerOfTwo((int)MathF.Ceiling(gridVisualMinSize / gridBaseSize.X)); adjustedGridBaseSize.Y = gridBaseSize.Y * MathF.NextPowerOfTwo((int)MathF.Ceiling(gridVisualMinSize / gridBaseSize.Y)); float scaleAtGrid = device.GetScaleAtZ(0.0f); float scaleAdjustmentFactor = 4.0f * MathF.Pow(2.0f, -MathF.Round(1.0f - MathF.Log(1.0f / scaleAtGrid, 2.0f))); Vector2 adjustedGridSize; adjustedGridSize.X = MathF.Max(adjustedGridBaseSize.X * scaleAdjustmentFactor, gridBaseSize.X); adjustedGridSize.Y = MathF.Max(adjustedGridBaseSize.Y * scaleAdjustmentFactor, gridBaseSize.Y); Vector2 stepSize = adjustedGridSize; float viewBoundRad = MathF.Distance(device.TargetSize.X, device.TargetSize.Y) * 0.5f / scaleAtGrid; int lineCountX = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / stepSize.X)) * 4; int lineCountY = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / stepSize.Y)) * 4; int vertexCount = (lineCountX * 2 + lineCountY * 2); if (this.vertexBuffer == null) { this.vertexBuffer = new RawList <VertexC1P3>(vertexCount); } this.vertexBuffer.Count = vertexCount; VertexC1P3[] vertices = this.vertexBuffer.Data; float beginPos; float pos; int lineIndex; int vertOff = 0; beginPos = stepSize.X * (int)(device.ViewerPos.X / stepSize.X - (lineCountX / 8)); pos = beginPos; lineIndex = 0; for (int x = 0; x < lineCountX; x++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + x * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + x * 2 + 0].Pos.X = pos; vertices[vertOff + x * 2 + 0].Pos.Y = device.ViewerPos.Y - viewBoundRad; vertices[vertOff + x * 2 + 0].Pos.Z = 0.0f; vertices[vertOff + x * 2 + 0].DepthOffset = 1.0f; vertices[vertOff + x * 2 + 1] = vertices[vertOff + x * 2 + 0]; vertices[vertOff + x * 2 + 1].Pos.Y = device.ViewerPos.Y + viewBoundRad; pos += stepSize.X / 4; lineIndex++; } vertOff += lineCountX * 2; beginPos = stepSize.Y * (int)(device.ViewerPos.Y / stepSize.Y - (lineCountY / 8)); pos = beginPos; lineIndex = 0; for (int y = 0; y < lineCountY; y++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + y * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + y * 2 + 0].Pos.X = device.ViewerPos.X - viewBoundRad; vertices[vertOff + y * 2 + 0].Pos.Y = pos; vertices[vertOff + y * 2 + 0].Pos.Z = 0.0f; vertices[vertOff + y * 2 + 0].DepthOffset = 1.0f; vertices[vertOff + y * 2 + 1] = vertices[vertOff + y * 2 + 0]; vertices[vertOff + y * 2 + 1].Pos.X = device.ViewerPos.X + viewBoundRad; pos += stepSize.Y / 4; lineIndex++; } vertOff += lineCountY * 2; BatchInfo material = device.RentMaterial(); material.Technique = DrawTechnique.Alpha; device.AddVertices(material, VertexMode.Lines, vertices, this.vertexBuffer.Count); }