protected void DrawLockedAxes(Canvas canvas, float x, float y, float z, float r) { Vector3 refPos = canvas.DrawDevice.ViewerPos; float nearZ = canvas.DrawDevice.NearZ; canvas.PushState(); if (this.actionLockedAxis == ObjectEditorAxisLock.X) { canvas.State.SetMaterial(DrawTechnique.Solid); canvas.State.ColorTint = ColorRgba.Lerp(this.FgColor, ColorRgba.Red, 0.5f); canvas.DrawLine(x - r, y, z, x + r, y, z); } if (this.actionLockedAxis == ObjectEditorAxisLock.Y) { canvas.State.SetMaterial(DrawTechnique.Solid); canvas.State.ColorTint = ColorRgba.Lerp(this.FgColor, ColorRgba.Green, 0.5f); canvas.DrawLine(x, y - r, z, x, y + r, z); } if (this.actionLockedAxis == ObjectEditorAxisLock.Z) { canvas.State.SetMaterial(DrawTechnique.Solid); canvas.State.ColorTint = ColorRgba.Lerp(this.FgColor, ColorRgba.Blue, 0.5f); canvas.DrawLine(x, y, MathF.Max(z - r, refPos.Z + nearZ + 10), x, y, z); canvas.DrawLine(x, y, z, x, y, z + r); } canvas.PopState(); }
public Particle DoAction(Particle particle, float deltaTime) { var particleColor = ColorRgba.Lerp(particle.StartingColor, particle.EndingColor, particle.Life.AgeRatio); var newParticle = new Particle(particle.Position, particle.Velocity, particleColor, particle.StartingColor, particle.EndingColor, particle.Size, particle.Life); return(newParticle); }
[Test] public void ColorRgbaAnimation() { AnimationTrack <ColorRgba> track; track = new AnimationTrack <ColorRgba>(ColorRgba.Red, ColorRgba.Green); Assert.AreEqual(ColorRgba.Red, track[0.0f]); Assert.AreEqual(ColorRgba.Lerp(ColorRgba.Red, ColorRgba.Green, 0.5f), track[0.5f]); Assert.AreEqual(ColorRgba.Green, track[1.0f]); }
[Test] public void LerpOperation() { Assert.AreEqual(0.6f, GenericOperator.Lerp(0.0f, 1.0f, 0.6f)); Assert.AreEqual(0, GenericOperator.Lerp(0, 1, 0.61f)); Assert.AreEqual(1, GenericOperator.Lerp(0, 2, 0.61f)); Assert.AreEqual(6, GenericOperator.Lerp(0, 10, 0.61f)); Assert.AreEqual(ColorRgba.Lerp(ColorRgba.Red, ColorRgba.Blue, 0.6f), GenericOperator.Lerp(ColorRgba.Red, ColorRgba.Blue, 0.6f)); Assert.AreEqual(Vector2.Lerp(Vector2.UnitX, Vector2.UnitY, 0.6f), GenericOperator.Lerp(Vector2.UnitX, Vector2.UnitY, 0.6f)); }
public void OnInit(InitContext context) { if (context == InitContext.Activate) { var asr = GameObj.GetComponent <AdvSpriteRenderer>(); if (asr != null) { var color = asr.Color; var fadeColor = color; fadeColor.A = 0; _fadeFunc = (float a) => asr.Color = ColorRgba.Lerp(color, fadeColor, a); } } }
void ICmpInitializable.OnInit(InitContext context) { if (context == InitContext.Activate) { var sprite = GameObj.GetComponent <SpriteRenderer>(); if (sprite != null) { var color = sprite.ColorTint; var fadeColor = color; fadeColor.A = 0; _fadeFunc = (float a) => sprite.ColorTint = ColorRgba.Lerp(color, fadeColor, a); } } }
protected virtual void OnCollectStateOverlayDrawcalls(Canvas canvas) { // Gather general data Point cursorPos = this.PointToClient(Cursor.Position); // Collect the views overlay layer drawcalls this.CollectLayerOverlayDrawcalls(canvas); // Collect the states overlay drawcalls canvas.PushState(); { // Draw camera movement indicators if (this.camAction != CameraAction.None) { canvas.PushState(); canvas.State.ColorTint *= ColorRgba.White.WithAlpha(0.5f); if (this.camAction == CameraAction.DragScene) { // Don't draw anything. } else if (this.camAction == CameraAction.Move) { canvas.FillCircle(this.camActionBeginLoc.X, this.camActionBeginLoc.Y, 3); canvas.DrawLine(this.camActionBeginLoc.X, this.camActionBeginLoc.Y, cursorPos.X, cursorPos.Y); } canvas.PopState(); } } canvas.PopState(); // Draw a focus indicator at the view border canvas.PushState(); { ColorRgba focusColor = ColorRgba.Lerp(this.FgColor, this.BgColor, 0.25f).WithAlpha(255); ColorRgba noFocusColor = ColorRgba.Lerp(this.FgColor, this.BgColor, 0.75f).WithAlpha(255); canvas.State.ColorTint *= this.Focused ? focusColor : noFocusColor; canvas.DrawRect(0, 0, canvas.DrawDevice.TargetSize.X, canvas.DrawDevice.TargetSize.Y); } canvas.PopState(); }
protected void DrawLockedAxes(Canvas canvas, float x, float y, float z, float r) { Vector3 refPos = canvas.DrawDevice.RefCoord; float nearZ = canvas.DrawDevice.NearZ; canvas.PushState(); if (this.actionLockedAxis == LockedAxis.X) { canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, ColorRgba.Lerp(this.FgColor, ColorRgba.Red, 0.5f))); canvas.DrawLine(x - r, y, z, x + r, y, z); } if (this.actionLockedAxis == LockedAxis.Y) { canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, ColorRgba.Lerp(this.FgColor, ColorRgba.Green, 0.5f))); canvas.DrawLine(x, y - r, z, x, y + r, z); } if (this.actionLockedAxis == LockedAxis.Z) { canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, ColorRgba.Lerp(this.FgColor, ColorRgba.Blue, 0.5f))); canvas.DrawLine(x, y, MathF.Max(z - r, refPos.Z + nearZ + 10), x, y, z); canvas.DrawLine(x, y, z, x, y, z + r); } canvas.PopState(); }
internal void Update() { this.AcquireConfigObjects(); Transform transform = this.GameObj.Transform; float scaledRad = this.radius * transform.Scale; Agent[] otherAgents = AgentManager.Instance.FindNeighborAgents(this).ToArray(); this.sampler.Reset(); bool keepSampling = true; Vector2 bestVelocity = Vector2.Zero; float bestScore = float.PositiveInfinity; while (keepSampling) { Vector2 sample = this.sampler.GetCurrentSample(this) * this.characteristics.MaxSpeed; // penalities float toiPenality = 0f; // check against every obstacle foreach (Agent otherAgent in otherAgents) { Transform otherTransform = otherAgent.GameObj.Transform; float curToiPenality = 0f; // calculate helper variables for RVO Vector2 relPos = otherTransform.Pos.Xy - transform.Pos.Xy; // -> calculate side (only sign is of interest) for HRVO Vector2 averageVel = 0.5f * (transform.Vel.Xy + otherTransform.Vel.Xy); float side = Vector2.Dot(relPos.PerpendicularRight, sample - averageVel); float selfFactor = 0f; float otherFactor = 1f; if (side >= 0f) { // this is different from original RVO - we use the ratio of the observed velocities to determine // how much responsibility one agent has float selfSpeed = transform.Vel.Xy.Length; float otherSpeed = otherTransform.Vel.Xy.Length; selfFactor = 0.5f; var selfPlusOtherSpeed = selfSpeed + otherSpeed; if (selfPlusOtherSpeed > float.Epsilon) { selfFactor = otherSpeed / selfPlusOtherSpeed; } otherFactor = 1f - selfFactor; } // check time of impact float curMinToi; float curMaxToi; Vector2 expectedRelVel = sample - (selfFactor * transform.Vel.Xy + otherFactor * otherTransform.Vel.Xy); float otherScaledRad = otherAgent.radius * otherTransform.Scale; if (ToiCircleCircle(relPos, scaledRad + otherScaledRad, expectedRelVel, out curMinToi, out curMaxToi) && 0f < curMaxToi) { if (curMinToi <= 0f) { // we collided - check which way we get here out if (MathF.Abs(curMinToi) < MathF.Abs(curMaxToi)) { // => if minT (which is behind us) is lower then it's a bad idea to keep going because the // other way would bring us out earlier curToiPenality = float.PositiveInfinity; } else { curToiPenality = curMaxToi; } } else { // this is a new minimum toi // => calculate penality curToiPenality = MathF.Max(0f, this.toiHorizon - curMinToi) / this.toiHorizon; } } toiPenality = MathF.Max(toiPenality, curToiPenality); } // ask the characteristics implementation how good this sample is float score = characteristics.CalculateVelocityCost(this, sample, toiPenality); // update sampler and check if we should stop keepSampling = sampler.SetCurrentCost(score); // check if this velocity is better then everything else we've seen so far if (score < bestScore) { bestScore = score; bestVelocity = sample; } #region visual logging of all sampled velocities #if DEBUG if (DebugVisualizationMode != VisualLoggingMode.None && DebugVisualizationMode != VisualLoggingMode.VelocityOnly && DebugVisualizationMode != VisualLoggingMode.AllVelocities) { Vector2 debugPos = sample / this.characteristics.MaxSpeed * DebugVelocityRadius; float debugColorFactor = 0.0f; switch (DebugVisualizationMode) { case VisualLoggingMode.Cost: debugColorFactor = score; break; case VisualLoggingMode.ToiPenalty: debugColorFactor = toiPenality; break; } ColorRgba debugColor = ColorRgba.Lerp(ColorRgba.White, ColorRgba.Black, MathF.Pow(debugColorFactor, 1f / 4f)); VisualDebugLog.DrawCircle(debugPos.X, debugPos.Y, 4f).AnchorAt(this.GameObj).WithColor(debugColor); } #endif #endregion } this.suggestedVel = bestVelocity; #region visual logging of the velocities #if DEBUG if (DebugVisualizationMode == VisualLoggingMode.AllVelocities) { Vector2 selfDebugVelocity = transform.Vel.Xy / Characteristics.MaxSpeed * DebugVelocityRadius; VisualDebugLog.DrawVector(0f, 0f, selfDebugVelocity.X, selfDebugVelocity.Y).AnchorAt(GameObj).WithColor(ColorRgba.DarkGrey); foreach (var otherAgent in otherAgents) { Transform otherTransform = otherAgent.GameObj.Transform; Vector2 debugVelocity = otherTransform.Vel.Xy / otherAgent.Characteristics.MaxSpeed * DebugVelocityRadius; VisualDebugLog.DrawVector(0f, 0f, debugVelocity.X, debugVelocity.Y).AnchorAt(otherAgent.GameObj).WithColor(ColorRgba.DarkGrey); } } if (DebugVisualizationMode != VisualLoggingMode.None) { Vector2 curVelocity = transform.Vel.Xy / Characteristics.MaxSpeed * DebugVelocityRadius; VisualDebugLog.DrawVector(0f, 0f, curVelocity.X, curVelocity.Y).AnchorAt(GameObj).WithColor(ColorRgba.DarkGrey); var debugVelocity = this.suggestedVel / characteristics.MaxSpeed * DebugVelocityRadius; VisualDebugLog.DrawVector(0f, 0f, debugVelocity.X, debugVelocity.Y).AnchorAt(this.GameObj); } #endif #endregion }
void ICmpRenderer.Draw(IDrawDevice device) { Profile.BeginMeasure(@"ProfileRenderer"); Canvas canvas = new Canvas(device); canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White, null)); bool anyTextReport = this.textReportPerf || this.textReportStat; bool anyGraph = this.drawGraphs && this.counterGraphs.Count > 0; // Determine geometry int areaWidth = (int)device.TargetSize.X - 20; if (anyGraph && anyTextReport) { areaWidth = (areaWidth - 10) / 2; } Rect textReportRect = new Rect( 10, 10, anyTextReport ? areaWidth : 0, (int)device.TargetSize.Y - 20); Rect graphRect = new Rect( anyTextReport ? (textReportRect.MaximumX + 10) : 10, 10, anyGraph ? areaWidth : 0, (int)device.TargetSize.Y - 20); // Text Reports if (anyTextReport) { // Update Report IEnumerable <ProfileCounter> counters = Profile.GetUsedCounters(); if (!this.textReportPerf) { counters = counters.Where(c => !(c is TimeCounter)); } if (!this.textReportStat) { counters = counters.Where(c => !(c is StatCounter)); } if (this.textReport == null || (Time.MainTimer - this.textReportLast).TotalMilliseconds > this.updateInterval) { string report = Profile.GetTextReport(counters, this.textReportOptions | ProfileReportOptions.FormattedText); if (this.textReport == null) { this.textReport = new FormattedText(); this.textReport.Fonts = new[] { Font.GenericMonospace8 }; } this.textReport.MaxWidth = (int)textReportRect.W; this.textReport.SourceText = report; this.textReportLast = Time.MainTimer; } // Draw Report canvas.DrawText(textReport, ref textReportTextVert, ref textReportIconVert, textReportRect.X, textReportRect.Y, drawBackground: true); } // Counter Graphs if (anyGraph) { // Mark graph cache as unused foreach (GraphCacheEntry entry in this.graphCache.Values) { entry.WasUsed = false; } int space = 5; int graphY = (int)graphRect.Y; int graphH = MathF.Min((int)(graphRect.H / this.counterGraphs.Count) - space, (int)graphRect.W / 2); foreach (string counterName in this.counterGraphs) { ProfileCounter counter = Profile.GetCounter <ProfileCounter>(counterName); if (counter == null) { return; } // Create or retrieve graph cache entry GraphCacheEntry cache = null; if (!this.graphCache.TryGetValue(counterName, out cache)) { cache = new GraphCacheEntry(); cache.GraphValues = new float[ProfileCounter.ValueHistoryLen]; cache.GraphColors = new ColorRgba[ProfileCounter.ValueHistoryLen]; this.graphCache[counterName] = cache; } cache.WasUsed = true; float cursorRatio = 0.0f; if (counter is TimeCounter) { TimeCounter timeCounter = counter as TimeCounter; for (int i = 0; i < ProfileCounter.ValueHistoryLen; i++) { float factor = timeCounter.ValueGraph[i] / Time.MsPFMult; cache.GraphValues[i] = factor * 0.75f; cache.GraphColors[i] = ColorRgba.Lerp(ColorRgba.White, ColorRgba.Red, factor); } canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f); canvas.FillRect(graphRect.X, graphY, graphRect.W, graphH); canvas.State.ColorTint = ColorRgba.White; this.DrawHorizontalGraph(canvas, cache.GraphValues, cache.GraphColors, ref cache.VertGraph, graphRect.X, graphY, graphRect.W, graphH); cursorRatio = (float)timeCounter.ValueGraphCursor / (float)ProfileCounter.ValueHistoryLen; } else if (counter is StatCounter) { StatCounter statCounter = counter as StatCounter; for (int i = 0; i < ProfileCounter.ValueHistoryLen; i++) { cache.GraphValues[i] = (float)(statCounter.ValueGraph[i] - statCounter.MinValue) / statCounter.MaxValue; cache.GraphColors[i] = ColorRgba.White; } canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f); canvas.FillRect(graphRect.X, graphY, graphRect.W, graphH); canvas.State.ColorTint = ColorRgba.White; this.DrawHorizontalGraph(canvas, cache.GraphValues, cache.GraphColors, ref cache.VertGraph, graphRect.X, graphY, graphRect.W, graphH); cursorRatio = (float)statCounter.ValueGraphCursor / (float)ProfileCounter.ValueHistoryLen; } canvas.DrawText(new string[] { counter.FullName }, ref cache.VertText, graphRect.X, graphY); canvas.DrawLine(graphRect.X + graphRect.W * cursorRatio, graphY, graphRect.X + graphRect.W * cursorRatio, graphY + graphH); graphY += graphH + space; } // Remove unused graph cache entries foreach (var pair in this.graphCache.ToArray()) { if (!pair.Value.WasUsed) { pair.Value.GraphColors = null; pair.Value.GraphValues = null; pair.Value.VertGraph = null; pair.Value.VertText = null; this.graphCache.Remove(pair.Key); } } } Profile.EndMeasure(@"ProfileRenderer"); }
/// <summary> /// Creates a text report of the current profiling data and returns it as string. /// </summary> /// <param name="filePath"></param> public static string GetTextReport(IEnumerable <ProfileCounter> reportCounters, ProfileReportOptions options = ProfileReportOptions.LastValue) { bool omitMinor = (options & ProfileReportOptions.OmitMinorValues) != ProfileReportOptions.None; // Group Counters by Type Dictionary <Type, List <ProfileCounter> > countersByType = new Dictionary <Type, List <ProfileCounter> >(); Type[] existingTypes = reportCounters.Select(c => c.GetType()).Distinct().ToArray(); foreach (Type type in existingTypes) { countersByType[type] = reportCounters.Where(c => c.GetType() == type).ToList(); } // Prepare text building StringBuilder reportBuilder = new StringBuilder(countersByType.Count * 256); // Handle each group separately foreach (var pair in countersByType) { IEnumerable <ProfileCounter> counters = pair.Value; int minDepth = counters.Min(c => c.ParentDepth); IEnumerable <ProfileCounter> rootCounters = counters.Where(c => c.ParentDepth == minDepth); int maxNameLen = counters.Max(c => c.DisplayName.Length + c.ParentDepth * 2); if (options.HasFlag(ProfileReportOptions.GroupHeader)) { reportBuilder.Append(options.HasFlag(ProfileReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); reportBuilder.AppendLine(("[ " + pair.Key.Name + " ]").PadLeft(35, '-').PadRight(50, '-')); reportBuilder.Append(options.HasFlag(ProfileReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); } else if (reportBuilder.Length > 0) { reportBuilder.Append(options.HasFlag(ProfileReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); } if (options.HasFlag(ProfileReportOptions.Header)) { if (options.HasFlag(ProfileReportOptions.FormattedText)) { reportBuilder.Append(FormattedText.FormatColor(ColorRgba.White.WithAlpha(0.5f))); } reportBuilder.Append("Name"); reportBuilder.Append(' ', 1 + Math.Max((1 + maxNameLen) - "Name".Length, 0)); if (options.HasFlag(ProfileReportOptions.LastValue)) { reportBuilder.Append(" Last Value "); } if (options.HasFlag(ProfileReportOptions.AverageValue)) { reportBuilder.Append(" Avg. Value "); } if (options.HasFlag(ProfileReportOptions.MinValue)) { reportBuilder.Append(" Min. Value "); } if (options.HasFlag(ProfileReportOptions.MaxValue)) { reportBuilder.Append(" Max. Value "); } if (options.HasFlag(ProfileReportOptions.SampleCount)) { reportBuilder.Append(" Samples "); } reportBuilder.Append(options.HasFlag(ProfileReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); if (options.HasFlag(ProfileReportOptions.FormattedText)) { reportBuilder.Append(FormattedText.FormatColor(ColorRgba.White)); } } Stack <ProfileCounter> appendStack = new Stack <ProfileCounter>(rootCounters.Reverse()); while (appendStack.Count > 0) { ProfileCounter current = appendStack.Pop(); ProfileReportCounterData data; current.GetReportData(out data); if (omitMinor && data.Severity <= 0.005f) { continue; } if (options.HasFlag(ProfileReportOptions.FormattedText)) { float severity = data.Severity; ColorRgba lineColor = severity >= 0.5f ? ColorRgba.Lerp(ColorRgba.White, ColorRgba.Red, 2.0f * (severity - 0.5f)) : ColorRgba.Lerp(ColorRgba.TransparentWhite, ColorRgba.White, 0.1f + 0.9f * (2.0f * severity)); reportBuilder.Append(FormattedText.FormatColor(lineColor)); } reportBuilder.Append(' ', current.ParentDepth * 2); reportBuilder.Append(current.DisplayName); reportBuilder.Append(':'); reportBuilder.Append(' ', 1 + Math.Max((1 + maxNameLen) - (current.ParentDepth * 2 + current.DisplayName.Length + 1), 0)); if (options.HasFlag(ProfileReportOptions.LastValue)) { string valStr = data.LastValue ?? "-"; reportBuilder.Append(' ', Math.Max(13 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } if (options.HasFlag(ProfileReportOptions.AverageValue)) { string valStr = data.AverageValue ?? "-"; reportBuilder.Append(' ', Math.Max(13 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } if (options.HasFlag(ProfileReportOptions.MinValue)) { string valStr = data.MinValue ?? "-"; reportBuilder.Append(' ', Math.Max(13 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } if (options.HasFlag(ProfileReportOptions.MaxValue)) { string valStr = data.MaxValue ?? "-"; reportBuilder.Append(' ', Math.Max(13 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } if (options.HasFlag(ProfileReportOptions.SampleCount)) { string valStr = data.SampleCount ?? "-"; reportBuilder.Append(' ', Math.Max(15 - valStr.Length, 0)); reportBuilder.Append(valStr); reportBuilder.Append(' '); } reportBuilder.Append(options.HasFlag(ProfileReportOptions.FormattedText) ? FormattedText.FormatNewline : Environment.NewLine); IEnumerable <ProfileCounter> childCounters = counters.Where(c => c.Parent == current); foreach (ProfileCounter child in childCounters.Reverse()) { appendStack.Push(child); } } if (options.HasFlag(ProfileReportOptions.FormattedText)) { reportBuilder.Append(FormattedText.FormatColor(ColorRgba.White)); } } return(reportBuilder.ToString());; }
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 virtual void OnCollectStateOverlayDrawcalls(Canvas canvas) { // Gather general data Point cursorPos = this.PointToClient(Cursor.Position); // Update action text from hovered / selection / action object Vector2 actionTextPos = new Vector2(cursorPos.X + 30, cursorPos.Y + 10); this.actionText.SourceText = this.UpdateActionText(ref actionTextPos); // Collect the views overlay layer drawcalls this.CollectLayerOverlayDrawcalls(canvas); // Collect the states overlay drawcalls canvas.PushState(); { // Draw camera movement indicators if (this.camAction != CameraAction.None) { canvas.PushState(); canvas.State.ColorTint = ColorRgba.White.WithAlpha(0.5f); if (this.camAction == CameraAction.DragScene) { // Don't draw anything. } else if (this.camAction == CameraAction.Move) { canvas.FillCircle(this.camActionBeginLoc.X, this.camActionBeginLoc.Y, 3); canvas.DrawLine(this.camActionBeginLoc.X, this.camActionBeginLoc.Y, cursorPos.X, cursorPos.Y); } canvas.PopState(); } // Normalize action text position if (this.actionText.Fonts != null && this.actionText.Fonts.Any(r => r.IsAvailable && r.Res.IsPixelGridAligned)) { actionTextPos.X = MathF.Round(actionTextPos.X); actionTextPos.Y = MathF.Round(actionTextPos.Y); } // Draw current action text if (!this.actionText.IsEmpty) { canvas.DrawText(this.actionText, actionTextPos.X, actionTextPos.Y, drawBackground: true); } // Update / Draw current status text { this.statusText.SourceText = this.UpdateStatusText(); if (!this.statusText.IsEmpty) { Vector2 statusTextSize = this.statusText.Size; canvas.DrawText(this.statusText, 10, this.ClientSize.Height - statusTextSize.Y - 10, drawBackground: true); } } } canvas.PopState(); // Draw a focus indicator at the view border canvas.PushState(); { ColorRgba focusColor = ColorRgba.Lerp(this.FgColor, this.BgColor, 0.25f).WithAlpha(255); ColorRgba noFocusColor = ColorRgba.Lerp(this.FgColor, this.BgColor, 0.75f).WithAlpha(255); canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Mask, this.Focused ? focusColor : noFocusColor)); canvas.DrawRect(0, 0, this.ClientSize.Width, this.ClientSize.Height); } canvas.PopState(); }
protected override void OnCollectStateWorldOverlayDrawcalls(Canvas canvas) { base.OnCollectStateWorldOverlayDrawcalls(canvas); // Assure we know how to display the current selection this.ValidateSelectionStats(); List <ObjectEditorSelObj> transformObjSel = this.allObjSel.Where(s => s.HasTransform).ToList(); Point cursorPos = this.PointToClient(Cursor.Position); canvas.PushState(); canvas.State.ZOffset = -1.0f; // Draw indirectly selected object overlay canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, ColorRgba.Lerp(this.FgColor, this.BgColor, 0.75f))); this.DrawSelectionMarkers(canvas, this.indirectObjSel); if (this.mouseoverObject != null && (this.mouseoverAction == ObjectEditorAction.RectSelect || this.mouseoverSelect) && !transformObjSel.Contains(this.mouseoverObject)) { this.DrawSelectionMarkers(canvas, new [] { this.mouseoverObject }); } // Draw selected object overlay canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, this.FgColor)); this.DrawSelectionMarkers(canvas, transformObjSel); // Draw overall selection boundary if (transformObjSel.Count > 1) { float midZ = transformObjSel.Average(t => t.Pos.Z); float maxZDiff = transformObjSel.Max(t => MathF.Abs(t.Pos.Z - midZ)); if (maxZDiff > 0.001f) { canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, ColorRgba.Lerp(this.FgColor, this.BgColor, 0.5f))); canvas.DrawSphere( this.selectionCenter.X, this.selectionCenter.Y, this.selectionCenter.Z, this.selectionRadius); } else { canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, ColorRgba.Lerp(this.FgColor, this.BgColor, 0.5f))); canvas.DrawCircle( this.selectionCenter.X, this.selectionCenter.Y, this.selectionCenter.Z, this.selectionRadius); } } // Draw scale action dots bool canMove = this.actionObjSel.Any(s => s.IsActionAvailable(ObjectEditorAction.Move)); bool canScale = (canMove && this.actionObjSel.Count > 1) || this.actionObjSel.Any(s => s.IsActionAvailable(ObjectEditorAction.Scale)); if (canScale) { float dotR = 3.0f / this.GetScaleAtZ(this.selectionCenter.Z); canvas.State.ZOffset -= 0.1f; canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, this.FgColor)); canvas.FillCircle( this.selectionCenter.X + this.selectionRadius, this.selectionCenter.Y, this.selectionCenter.Z, dotR); canvas.FillCircle( this.selectionCenter.X - this.selectionRadius, this.selectionCenter.Y, this.selectionCenter.Z, dotR); canvas.FillCircle( this.selectionCenter.X, this.selectionCenter.Y + this.selectionRadius, this.selectionCenter.Z, dotR); canvas.FillCircle( this.selectionCenter.X, this.selectionCenter.Y - this.selectionRadius, this.selectionCenter.Z, dotR); canvas.State.ZOffset += 0.1f; } if (this.action != ObjectEditorAction.None) { // Draw action lock axes this.DrawLockedAxes(canvas, this.selectionCenter.X, this.selectionCenter.Y, this.selectionCenter.Z, this.selectionRadius * 4); } canvas.PopState(); }
void ICmpUpdatable.OnUpdate() { Transform transform = this.GameObj.Transform; CharacterController character = this.GameObj.GetComponent <CharacterController>(); // temp hack to test HitNotAnEnemy() if (DualityApp.Keyboard.KeyHit(Key.E)) { HitNotAnEnemy(); } // Find out which waypoint we're travelling to Transform waypoint = this.travelPath.Waypoints[this.waypointIndex]; this.targetPos = waypoint.Pos.Xy; // Adjust walking speed this.walkSpeed += Time.TimeMult * 0.04f * MathF.Rnd.NextFloat(-1.0f, 1.0f); this.walkSpeed = MathF.Clamp(this.walkSpeed, 0.5f, 1.0f); // Walk directly to the target Vector2 diffToTarget = this.targetPos - transform.Pos.Xy; Vector2 directionToTarget = diffToTarget.Normalized; float targetDistance = diffToTarget.Length; float movementSpeed = this.walkSpeed * MathF.Clamp(targetDistance / 64.0f, 0.0f, 1.0f); Vector2 movementDirection = directionToTarget; // Raycast to see if there is someone in front of us Vector2 rayStart = transform.Pos.Xy; Vector2 rayEnd = rayStart + directionToTarget * 64.0f; RayCastData rayFirstHit; bool rayHitAnything = RigidBody.RayCast(rayStart, rayEnd, data => { if (data.GameObj == character.GameObj) { return(-1); } if (data.Body.BodyType == BodyType.Static) { return(-1); } if (data.Fraction < 0.5f) { return(-1); } return(data.Fraction); }, out rayFirstHit); if (rayHitAnything) { Vector2 offset = (((int)Time.GameTimer.TotalSeconds / 5) % 2) == 0 ? movementDirection.PerpendicularLeft : movementDirection.PerpendicularRight; movementDirection = movementDirection + offset; movementDirection.Normalize(); //VisualLog.Default.DrawConnection(new Vector3(rayStart, 0.0f), rayFirstHit.Pos).WithOffset(-100).WithColor(ColorRgba.Red); } else { //VisualLog.Default.DrawConnection(new Vector3(rayStart, 0.0f), rayEnd).WithOffset(-100); } // Switch to the next waypoint when arriving if (targetDistance < 16.0f) { if (this.walkBackwards) { this.waypointIndex--; if (this.waypointIndex < 0) { this.walkBackwards = false; this.carriesStuff = true; this.carryType = MathF.Rnd.Next(1, 5); this.waypointIndex += 2; } } else { this.waypointIndex++; if (this.waypointIndex >= this.travelPath.Waypoints.Count) { this.Score(false); this.walkBackwards = true; this.carriesStuff = false; this.waypointIndex -= 2; } } } // Color the guy green ActorRenderer renderer = this.GameObj.GetComponent <ActorRenderer>(); ActorAnimator animator = this.GameObj.GetComponent <ActorAnimator>(); animator.Animations[1].DirectionMap[0].SpriteSheetIndex = this.carriesStuff ? 2 + this.carryType : 1; animator.Animations[1].DirectionMap[1].SpriteSheetIndex = this.carriesStuff ? 2 + this.carryType : 1; animator.Animations[1].DirectionMap[2].SpriteSheetIndex = this.carriesStuff ? 2 + this.carryType : 1; animator.Animations[1].DirectionMap[3].SpriteSheetIndex = this.carriesStuff ? 2 + this.carryType : 1; float redShift = MathF.Clamp(1.0f - (((float)Time.GameTimer.TotalSeconds - this.lastHitTime) / 0.5f), 0.0f, 1.0f); renderer.ColorTint = ColorRgba.Lerp(ColorRgba.White, ColorRgba.Red, redShift); character.TargetMovement = movementDirection * movementSpeed; // Hit Animation code if (hitAnimationStart + hitAnimationDuration > Time.GameTimer.TotalSeconds) { hitAnimationBlinkframes++; if (hitAnimationBlinkframes > hitAnimationBlinkrate) { hitAnimationBlinkframes = 0; if (renderer.Active == true) { renderer.Active = false; } else { renderer.Active = true; } } } else { renderer.Active = true; } }