void ICmpUpdatable.OnUpdate() { float lastDelta = Time.MsPFMult * Time.TimeMult / 1000; if (this.rigidBody == null) this.rigidBody = this.GameObj.GetComponent<RigidBody>(); if (!this.isDead) { if (DualityApp.Keyboard.KeyHit(Key.Space)) { this.rigidBody.ApplyLocalImpulse(-Vector2.UnitY * this.impulseStrength); flapTime = (Time.MsPFMult / 1000 * 3); } } if(flapTime > 0) { FrontWing.GameObj.Transform.Angle = -MathF.PiOver4; BackWing.GameObj.Transform.Angle = MathF.PiOver4; flapTime -= lastDelta; } if(flapTime < 0) { FrontWing.GameObj.Transform.Angle = 0; BackWing.GameObj.Transform.Angle = 0; flapTime = 0; } if (DualityApp.Keyboard.KeyHit(Key.Escape)) { Scene.SwitchTo(this.menuScene); } }
public void SetUp() { var gameObject = new GameObject(); _rigidBody = new RigidBody(); gameObject.AddComponent(_rigidBody); gameObject.AddComponent(new Transform()); }
public void When_copied_Then_sensor_value_is_copied() { _rigidBody.IsSensor = true; var clone = new RigidBody(); _rigidBody.CopyTo(clone); Assert.IsTrue(clone.IsSensor); }
public void OnInit(InitContext context) { body = (RigidBody)GameObj.GetComponent(typeof(RigidBody)); jumpsRemaining = NumberOfJumps; direction = 0; jumpNextFrame = false; Scriptable scriptable = (Scriptable)GameObj.GetComponent(typeof(Scriptable)); if(scriptable != null) { PlayerApi player = new PlayerApi(scriptable.engine, this); scriptable.AddObject("Player", player); scriptable.Evaluate("A_Down = function() { Player.MoveLeft() };" + "D_Down = function() { Player.MoveRight() };" + "D_Up = function() { Player.Stop() };" + "A_Up = function() { Player.Stop() };" + "Space_Down = function() { Player.Jump() };"); } }
private ShapeInfo PickShape(RigidBody body, Vector2 worldCoord) { // Special case for LoopShapes, because they are by definition unpickable foreach (LoopShapeInfo loop in body.Shapes.OfType<LoopShapeInfo>()) { for (int i = 0; i < loop.Vertices.Length; i++) { Vector2 worldV1 = body.GameObj.Transform.GetWorldPoint(loop.Vertices[i]); Vector2 worldV2 = body.GameObj.Transform.GetWorldPoint(loop.Vertices[(i + 1) % loop.Vertices.Length]); float dist = MathF.PointLineDistance(worldCoord.X, worldCoord.Y, worldV1.X, worldV1.Y, worldV2.X, worldV2.Y); if (dist < 5.0f) return loop; } } // Do a physical picking operation return body.PickShape(worldCoord); }
protected internal override void OnEnterState() { base.OnEnterState(); // Init GUI this.View.SuspendLayout(); this.toolstrip = new ToolStrip(); this.toolstrip.SuspendLayout(); this.toolstrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.toolstrip.Name = "toolstrip"; this.toolstrip.Text = "Collider Editor Tools"; this.toolCreateCircle = new ToolStripButton("Create Circle Shape (C)", Properties.CamViewResCache.IconCmpCircleCollider, this.toolCreateCircle_Clicked); this.toolCreateCircle.DisplayStyle = ToolStripItemDisplayStyle.Image; this.toolCreateCircle.AutoToolTip = true; this.toolstrip.Items.Add(this.toolCreateCircle); this.toolCreatePoly = new ToolStripButton("Create Polygon Shape (P)", Properties.CamViewResCache.IconCmpRectCollider, this.toolCreatePoly_Clicked); this.toolCreatePoly.DisplayStyle = ToolStripItemDisplayStyle.Image; this.toolCreatePoly.AutoToolTip = true; this.toolstrip.Items.Add(this.toolCreatePoly); this.toolCreateLoop = new ToolStripButton("Create Loop Shape (L)", Properties.CamViewResCache.IconCmpLoopCollider, this.toolCreateLoop_Clicked); this.toolCreateLoop.DisplayStyle = ToolStripItemDisplayStyle.Image; this.toolCreateLoop.AutoToolTip = true; this.toolstrip.Items.Add(this.toolCreateLoop); this.toolstrip.Renderer = new Duality.Editor.Controls.ToolStrip.DualitorToolStripProfessionalRenderer(); this.toolstrip.BackColor = Color.FromArgb(212, 212, 212); this.View.Controls.Add(this.toolstrip); this.View.Controls.SetChildIndex(this.toolstrip, this.View.Controls.IndexOf(this.View.ToolbarCamera)); this.toolstrip.ResumeLayout(true); this.View.ResumeLayout(true); // Register events DualityEditorApp.SelectionChanged += this.EditorForm_SelectionChanged; DualityEditorApp.ObjectPropertyChanged += this.EditorForm_ObjectPropertyChanged; // Initial update this.selectedBody = this.QuerySelectedCollider(); this.InvalidateSelectionStats(); this.UpdateToolbar(); this.View.ActivateLayer(typeof(CamViewLayers.RigidBodyShapeCamViewLayer)); this.View.LockLayer(typeof(CamViewLayers.RigidBodyShapeCamViewLayer)); }
private void DrawWorldLooseConstraint(Canvas canvas, RigidBody bodyA, Vector2 anchorA, Vector2 anchorB) { Vector3 bodyPosA = bodyA.GameObj.Transform.Pos; ColorRgba clr = this.JointColor; canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawDashLine( anchorA.X, anchorA.Y, bodyPosA.Z, anchorB.X, anchorB.Y, bodyPosA.Z); }
private void DrawWorldAxisMotor(Canvas canvas, RigidBody body, Vector2 worldAxis, Vector2 localAnchor, Vector2 worldAnchor, float speed, float maxForce, float offset) { Vector3 bodyPos = body.GameObj.Transform.Pos; ColorRgba clr = this.MotorColor; Vector2 anchorToWorld = body.GameObj.Transform.GetWorldVector(localAnchor); float axisAngle = worldAxis.Angle; float maxForceTemp = MathF.Sign(speed) * maxForce * 0.1f; Vector2 arrowBegin = bodyPos.Xy + worldAxis.PerpendicularRight * offset; Vector2 arrowBase = arrowBegin + worldAxis * speed * 10.0f; Vector2 arrowA = Vector2.FromAngleLength(axisAngle + MathF.RadAngle45 + MathF.RadAngle180, MathF.Sign(speed) * MathF.Max(offset * 0.05f, 5.0f)); Vector2 arrowB = Vector2.FromAngleLength(axisAngle - MathF.RadAngle45 + MathF.RadAngle180, MathF.Sign(speed) * MathF.Max(offset * 0.05f, 5.0f)); canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawLine( arrowBegin.X + worldAxis.PerpendicularLeft.X * 2.0f, arrowBegin.Y + worldAxis.PerpendicularLeft.Y * 2.0f, bodyPos.Z, arrowBegin.X + worldAxis.PerpendicularLeft.X * 2.0f + worldAxis.X * maxForceTemp, arrowBegin.Y + worldAxis.PerpendicularLeft.Y * 2.0f + worldAxis.Y * maxForceTemp, bodyPos.Z); canvas.DrawLine( arrowBegin.X + worldAxis.PerpendicularRight.X * 2.0f, arrowBegin.Y + worldAxis.PerpendicularRight.Y * 2.0f, bodyPos.Z, arrowBegin.X + worldAxis.PerpendicularRight.X * 2.0f + worldAxis.X * maxForceTemp, arrowBegin.Y + worldAxis.PerpendicularRight.Y * 2.0f + worldAxis.Y * maxForceTemp, bodyPos.Z); canvas.DrawLine( arrowBegin.X, arrowBegin.Y, bodyPos.Z, arrowBase.X, arrowBase.Y, bodyPos.Z); canvas.DrawLine( arrowBase.X, arrowBase.Y, bodyPos.Z, arrowBase.X + arrowA.X, arrowBase.Y + arrowA.Y, bodyPos.Z); canvas.DrawLine( arrowBase.X, arrowBase.Y, bodyPos.Z, arrowBase.X + arrowB.X, arrowBase.Y + arrowB.Y, bodyPos.Z); }
private void DrawWorldAnchor(Canvas canvas, RigidBody body, Vector2 anchor) { Vector3 colliderPos = body.GameObj.Transform.Pos; float markerCircleRad = body.BoundRadius * 0.02f; ColorRgba clr = this.JointColor; canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.FillCircle( anchor.X, anchor.Y, colliderPos.Z, markerCircleRad); }
private void DrawLocalText(Canvas canvas, RigidBody body, string text, Vector2 pos, float baseAngle) { this.DrawLocalText(canvas, body, text, pos, Vector2.Zero, baseAngle); }
public SelBody(RigidBody obj) { this.bodyObj = obj != null ? obj.GameObj : null; }
public CreateRigidBodyShapeAction(RigidBody parent, params ShapeInfo[] obj) : this(parent, obj as IEnumerable<ShapeInfo>) {}
public CreateRigidBodyShapeAction(RigidBody parent, IEnumerable<ShapeInfo> obj) : base(obj) { this.targetParentObj = parent; }
/// <summary> /// Adds a new joint to the body. /// </summary> /// <param name="joint"></param> public void AddJoint(JointInfo joint, RigidBody other = null) { if (joint == null) throw new ArgumentNullException("joint"); if (joint.ParentBody != null) joint.ParentBody.RemoveJoint(joint); joint.ParentBody = this; joint.OtherBody = other; if (this.joints == null) this.joints = new List<JointInfo>(); this.joints.Add(joint); this.AwakeBody(); if (joint.OtherBody != null) joint.OtherBody.AwakeBody(); joint.UpdateJoint(); }
private void FireBullet(RigidBody body, Transform transform, Vector2 localPos, float localAngle) { ShipBlueprint blueprint = this.blueprint.Res; if (blueprint.BulletType == null) return; Bullet bullet = blueprint.BulletType.Res.CreateBullet(); Vector2 recoilImpulse; Vector2 worldPos = transform.GetWorldPoint(localPos); bullet.Fire(this.owner, body.LinearVelocity, worldPos, transform.Angle + localAngle, out recoilImpulse); body.ApplyWorldImpulse(recoilImpulse); Scene.Current.AddObject(bullet.GameObj); SoundInstance inst = null; if (Player.AlivePlayers.Count() > 1) inst = DualityApp.Sound.PlaySound3D(this.owner.WeaponSound, new Vector3(worldPos)); else inst = DualityApp.Sound.PlaySound(this.owner.WeaponSound); inst.Volume = MathF.Rnd.NextFloat(0.6f, 1.0f); inst.Pitch = MathF.Rnd.NextFloat(0.9f, 1.11f); }
private void DrawLocalLooseConstraint(Canvas canvas, RigidBody bodyA, RigidBody bodyB, Vector2 anchorA, Vector2 anchorB) { Vector3 bodyPosA = bodyA.GameObj.Transform.Pos; Vector3 bodyPosB = bodyB.GameObj.Transform.Pos; ColorRgba clr = this.JointColor; Vector2 anchorAToWorld = bodyA.GameObj.Transform.GetWorldVector(anchorA); Vector2 anchorBToWorld = bodyB.GameObj.Transform.GetWorldVector(anchorB); canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawDashLine( bodyPosA.X + anchorAToWorld.X, bodyPosA.Y + anchorAToWorld.Y, bodyPosA.Z, bodyPosB.X + anchorBToWorld.X, bodyPosB.Y + anchorBToWorld.Y, bodyPosB.Z); }
private void DrawLocalPosConstraint(Canvas canvas, RigidBody bodyA, RigidBody bodyB, Vector2 anchorA, Vector2 anchorB) { Vector3 colliderPosA = bodyA.GameObj.Transform.Pos; Vector3 colliderPosB = bodyB.GameObj.Transform.Pos; ColorRgba clr = this.JointColor; ColorRgba clrErr = this.JointErrorColor; Vector2 anchorAToWorld = bodyA.GameObj.Transform.GetWorldVector(anchorA); Vector2 anchorBToWorld = bodyB.GameObj.Transform.GetWorldVector(anchorB); Vector2 errorVec = (colliderPosB.Xy + anchorBToWorld) - (colliderPosA.Xy + anchorAToWorld); bool hasError = errorVec.Length >= 1.0f; if (hasError) { canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clrErr)); canvas.DrawLine( colliderPosA.X + anchorAToWorld.X, colliderPosA.Y + anchorAToWorld.Y, colliderPosA.Z, colliderPosB.X + anchorBToWorld.X, colliderPosB.Y + anchorBToWorld.Y, colliderPosB.Z); this.DrawLocalText(canvas, bodyA, string.Format("{0:F1}", errorVec.Length), anchorAToWorld + errorVec * 0.5f, new Vector2(0.5f, 0.0f), errorVec.PerpendicularLeft.Angle); } canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawLine( colliderPosA.X, colliderPosA.Y, colliderPosA.Z, colliderPosA.X + anchorAToWorld.X, colliderPosA.Y + anchorAToWorld.Y, colliderPosA.Z); canvas.DrawLine( colliderPosB.X, colliderPosB.Y, colliderPosB.Z, colliderPosB.X + anchorBToWorld.X, colliderPosB.Y + anchorBToWorld.Y, colliderPosB.Z); }
private float GetAnchorDist(RigidBody bodyA, RigidBody bodyB, Vector2 localAnchorA, Vector2 localAnchorB) { Vector3 colliderPosA = bodyA.GameObj.Transform.Pos; Vector3 colliderPosB = bodyB.GameObj.Transform.Pos; Vector2 anchorAToWorld = bodyA.GameObj.Transform.GetWorldVector(localAnchorA); Vector2 anchorBToWorld = bodyB.GameObj.Transform.GetWorldVector(localAnchorB); Vector2 errorVec = (colliderPosB.Xy + anchorBToWorld) - (colliderPosA.Xy + anchorAToWorld); return errorVec.Length; }
private void DrawLocalText(Canvas canvas, RigidBody body, string text, Vector2 pos, Vector2 handle, float baseAngle) { Vector3 bodyPos = body.GameObj.Transform.Pos; Vector2 textSize = canvas.MeasureText(text); bool flipText = MathF.TurnDir(baseAngle - canvas.DrawDevice.RefAngle, MathF.RadAngle90) < 0; baseAngle = MathF.NormalizeAngle(flipText ? baseAngle + MathF.RadAngle180 : baseAngle); handle *= textSize; if (flipText) handle = textSize - handle; canvas.State.TransformHandle = handle; canvas.State.TransformAngle = baseAngle; canvas.DrawText(text, bodyPos.X + pos.X, bodyPos.Y + pos.Y, bodyPos.Z); canvas.State.TransformAngle = 0.0f; canvas.State.TransformHandle = Vector2.Zero; }
private void DrawLocalAngleConstraint(Canvas canvas, RigidBody body, Vector2 anchor, float targetAngle, float currentAngle, float radius) { Vector3 bodyPos = body.GameObj.Transform.Pos; ColorRgba clr = this.JointColor; ColorRgba clrErr = this.JointErrorColor; Vector2 anchorToWorld = body.GameObj.Transform.GetWorldVector(anchor); Vector2 angleVec = Vector2.FromAngleLength(targetAngle, radius); Vector2 errorVec = Vector2.FromAngleLength(currentAngle, radius); bool hasError = MathF.CircularDist(targetAngle, currentAngle) >= MathF.RadAngle1; if (hasError) { float circleBegin = currentAngle; float circleEnd = targetAngle; if (MathF.TurnDir(circleBegin, circleEnd) < 0) { MathF.Swap(ref circleBegin, ref circleEnd); circleEnd = circleBegin + MathF.CircularDist(circleBegin, circleEnd); } canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clrErr)); canvas.DrawLine( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, bodyPos.X + anchorToWorld.X + errorVec.X, bodyPos.Y + anchorToWorld.Y + errorVec.Y, bodyPos.Z); canvas.DrawCircleSegment( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, radius, circleBegin, circleEnd); this.DrawLocalText(canvas, body, string.Format("{0:F0}°", MathF.RadToDeg(MathF.NormalizeAngle(currentAngle))), anchorToWorld + errorVec, Vector2.UnitY, errorVec.Angle); } canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawLine( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, bodyPos.X + anchorToWorld.X + angleVec.X, bodyPos.Y + anchorToWorld.Y + angleVec.Y, bodyPos.Z); this.DrawLocalText(canvas, body, string.Format("{0:F0}°", MathF.RadToDeg(MathF.NormalizeAngle(targetAngle))), anchorToWorld + angleVec, angleVec.Angle); }
private void DrawWorldAxisConstraint(Canvas canvas, RigidBody body, Vector2 worldAxis, Vector2 localAnchor, Vector2 worldAnchor, float min = 1, float max = -1) { Vector3 bodyPos = body.GameObj.Transform.Pos; worldAxis = worldAxis.Normalized; bool infinite = false; if (min > max) { min = -10000000.0f; max = 10000000.0f; infinite = true; } Vector2 anchorToWorld = body.GameObj.Transform.GetWorldVector(localAnchor); float axisVal = Vector2.Dot(bodyPos.Xy + anchorToWorld - worldAnchor, worldAxis); Vector2 basePos = MathF.PointLineNearestPoint( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, worldAnchor.X + worldAxis.X * min, worldAnchor.Y + worldAxis.Y * min, worldAnchor.X + worldAxis.X * max, worldAnchor.Y + worldAxis.Y * max, infinite); float errorVal = (bodyPos.Xy + anchorToWorld - basePos).Length; Vector2 errorVec = basePos - bodyPos.Xy; bool hasError = errorVal >= 1.0f; ColorRgba clr = this.JointColor; ColorRgba clrErr = this.JointErrorColor; if (hasError) { canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clrErr)); canvas.DrawLine( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, basePos.X, basePos.Y, bodyPos.Z); this.DrawLocalText(canvas, body, string.Format("{0:F1}", errorVal), errorVec * 0.5f, new Vector2(0.5f, 0.0f), errorVec.PerpendicularLeft.Angle); } canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawLine( worldAnchor.X + worldAxis.X * min, worldAnchor.Y + worldAxis.Y * min, bodyPos.Z, worldAnchor.X + worldAxis.X * max, worldAnchor.Y + worldAxis.Y * max, bodyPos.Z); if (!infinite) { canvas.DrawLine( worldAnchor.X + worldAxis.X * min + worldAxis.PerpendicularLeft.X * 5.0f, worldAnchor.Y + worldAxis.Y * min + worldAxis.PerpendicularLeft.Y * 5.0f, bodyPos.Z, worldAnchor.X + worldAxis.X * min + worldAxis.PerpendicularRight.X * 5.0f, worldAnchor.Y + worldAxis.Y * min + worldAxis.PerpendicularRight.Y * 5.0f, bodyPos.Z); canvas.DrawLine( worldAnchor.X + worldAxis.X * max + worldAxis.PerpendicularLeft.X * 5.0f, worldAnchor.Y + worldAxis.Y * max + worldAxis.PerpendicularLeft.Y * 5.0f, bodyPos.Z, worldAnchor.X + worldAxis.X * max + worldAxis.PerpendicularRight.X * 5.0f, worldAnchor.Y + worldAxis.Y * max + worldAxis.PerpendicularRight.Y * 5.0f, bodyPos.Z); } }
private void DrawLocalAngleConstraint(Canvas canvas, RigidBody body, Vector2 anchor, float minAngle, float maxAngle, float currentAngle, float radius) { Vector3 bodyPos = body.GameObj.Transform.Pos; ColorRgba clr = this.JointColor; ColorRgba clrErr = this.JointErrorColor; Vector2 anchorToWorld = body.GameObj.Transform.GetWorldVector(anchor); Vector2 angleVecMin = Vector2.FromAngleLength(minAngle, radius); Vector2 angleVecMax = Vector2.FromAngleLength(maxAngle, radius); Vector2 errorVec = Vector2.FromAngleLength(currentAngle, radius); float angleDistMin = MathF.Abs(currentAngle - minAngle); float angleDistMax = MathF.Abs(currentAngle - maxAngle); float angleRange = maxAngle - minAngle; bool hasError = angleDistMin > angleDistMax ? angleDistMin >= angleRange : angleDistMax >= angleRange; if (hasError) { float circleBegin = currentAngle; float circleEnd = angleDistMin < angleDistMax ? minAngle : maxAngle; if (MathF.TurnDir(circleBegin, circleEnd) < 0) { MathF.Swap(ref circleBegin, ref circleEnd); circleEnd = circleBegin + MathF.CircularDist(circleBegin, circleEnd); } canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clrErr)); canvas.DrawLine( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, bodyPos.X + anchorToWorld.X + errorVec.X, bodyPos.Y + anchorToWorld.Y + errorVec.Y, bodyPos.Z); canvas.DrawCircleSegment( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, radius, circleBegin, circleEnd); this.DrawLocalText(canvas, body, string.Format("{0:F0}°", MathF.RadToDeg(currentAngle)), anchorToWorld + errorVec, Vector2.UnitY, errorVec.Angle); } canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawCircleSegment( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, radius, minAngle, maxAngle); canvas.DrawLine( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, bodyPos.X + anchorToWorld.X + angleVecMin.X, bodyPos.Y + anchorToWorld.Y + angleVecMin.Y, bodyPos.Z); canvas.DrawLine( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, bodyPos.X + anchorToWorld.X + angleVecMax.X, bodyPos.Y + anchorToWorld.Y + angleVecMax.Y, bodyPos.Z); this.DrawLocalText(canvas, body, string.Format("{0:F0}°", MathF.RadToDeg(minAngle)), anchorToWorld + angleVecMin, angleVecMin.Angle); this.DrawLocalText(canvas, body, string.Format("{0:F0}°", MathF.RadToDeg(maxAngle)), anchorToWorld + angleVecMax, angleVecMax.Angle); }
private void DrawWorldDistConstraint(Canvas canvas, RigidBody body, Vector2 localAnchor, Vector2 worldAnchor, float minDist, float maxDist) { Vector3 colliderPosA = body.GameObj.Transform.Pos; ColorRgba clr = this.JointColor; ColorRgba clrErr = this.JointErrorColor; float markerCircleRad = body.BoundRadius * 0.02f; Vector2 anchorA = body.GameObj.Transform.GetWorldVector(localAnchor); Vector2 errorVec = worldAnchor - (colliderPosA.Xy + anchorA); Vector2 lineNormal = errorVec.PerpendicularRight.Normalized; float dist = errorVec.Length; Vector2 distVec = errorVec.Normalized * MathF.Clamp(dist, minDist, maxDist); bool hasError = (errorVec - distVec).Length >= 1.0f; if (hasError) { canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clrErr)); canvas.DrawLine( colliderPosA.X + anchorA.X + distVec.X, colliderPosA.Y + anchorA.Y + distVec.Y, colliderPosA.Z, colliderPosA.X + anchorA.X + errorVec.X, colliderPosA.Y + anchorA.Y + errorVec.Y, colliderPosA.Z); this.DrawLocalText(canvas, body, string.Format("{0:F1}", dist), anchorA + errorVec, Vector2.UnitY, errorVec.Angle); } canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawLine( colliderPosA.X + anchorA.X, colliderPosA.Y + anchorA.Y, colliderPosA.Z, colliderPosA.X + anchorA.X + distVec.X, colliderPosA.Y + anchorA.Y + distVec.Y, colliderPosA.Z); if (hasError) { canvas.DrawLine( colliderPosA.X + anchorA.X + distVec.X - lineNormal.X * 5.0f, colliderPosA.Y + anchorA.Y + distVec.Y - lineNormal.Y * 5.0f, colliderPosA.Z, colliderPosA.X + anchorA.X + distVec.X + lineNormal.X * 5.0f, colliderPosA.Y + anchorA.Y + distVec.Y + lineNormal.Y * 5.0f, colliderPosA.Z); } this.DrawLocalText(canvas, body, string.Format("{0:F1}", MathF.Clamp(dist, minDist, maxDist)), anchorA + distVec, Vector2.Zero, errorVec.Angle); }
private void DrawLocalAngleMotor(Canvas canvas, RigidBody body, Vector2 anchor, float speed, float maxTorque, float radius) { Vector3 bodyPos = body.GameObj.Transform.Pos; ColorRgba clr = this.MotorColor; float baseAngle = body.GameObj.Transform.Angle; float speedAngle = baseAngle + speed; float maxTorqueAngle = baseAngle + MathF.Sign(speed) * maxTorque * 0.01f; Vector2 anchorToWorld = body.GameObj.Transform.GetWorldVector(anchor); Vector2 arrowBase = anchorToWorld + Vector2.FromAngleLength(speedAngle, radius); Vector2 arrorA = Vector2.FromAngleLength(speedAngle - MathF.RadAngle45, MathF.Sign(speed) * radius * 0.05f); Vector2 arrorB = Vector2.FromAngleLength(speedAngle - MathF.RadAngle45 + MathF.RadAngle270, MathF.Sign(speed) * radius * 0.05f); canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawCircleSegment( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, radius - 2, MathF.Sign(speed) >= 0 ? baseAngle : maxTorqueAngle, MathF.Sign(speed) >= 0 ? maxTorqueAngle : baseAngle); canvas.DrawCircleSegment( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, radius + 2, MathF.Sign(speed) >= 0 ? baseAngle : maxTorqueAngle, MathF.Sign(speed) >= 0 ? maxTorqueAngle : baseAngle); canvas.DrawCircleSegment( bodyPos.X + anchorToWorld.X, bodyPos.Y + anchorToWorld.Y, bodyPos.Z, radius, MathF.Sign(speed) >= 0 ? baseAngle : speedAngle, MathF.Sign(speed) >= 0 ? speedAngle : baseAngle); canvas.DrawLine( bodyPos.X + arrowBase.X, bodyPos.Y + arrowBase.Y, bodyPos.Z, bodyPos.X + arrowBase.X + arrorA.X, bodyPos.Y + arrowBase.Y + arrorA.Y, bodyPos.Z); canvas.DrawLine( bodyPos.X + arrowBase.X, bodyPos.Y + arrowBase.Y, bodyPos.Z, bodyPos.X + arrowBase.X + arrorB.X, bodyPos.Y + arrowBase.Y + arrorB.Y, bodyPos.Z); }
private void DrawWorldPosConstraint(Canvas canvas, RigidBody body, Vector2 localAnchor, Vector2 worldAnchor) { Vector3 bodyPos = body.GameObj.Transform.Pos; ColorRgba clr = this.JointColor; ColorRgba clrErr = this.JointErrorColor; float angularCircleRadA = body.BoundRadius * 0.25f; float markerCircleRad = body.BoundRadius * 0.02f; Vector2 anchorAToWorld = body.GameObj.Transform.GetWorldVector(localAnchor); Vector2 errorVec = worldAnchor - (bodyPos.Xy + anchorAToWorld); bool hasError = errorVec.Length >= 1.0f; if (hasError) { canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clrErr)); canvas.DrawLine( bodyPos.X + anchorAToWorld.X, bodyPos.Y + anchorAToWorld.Y, bodyPos.Z, worldAnchor.X, worldAnchor.Y, bodyPos.Z); this.DrawLocalText(canvas, body, string.Format("{0:F1}", errorVec.Length), anchorAToWorld + errorVec * 0.5f, new Vector2(0.5f, 0.0f), errorVec.PerpendicularLeft.Angle); } canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.DrawLine( bodyPos.X, bodyPos.Y, bodyPos.Z, bodyPos.X + anchorAToWorld.X, bodyPos.Y + anchorAToWorld.Y, bodyPos.Z); }
private void DrawLocalAxisConstraint(Canvas canvas, RigidBody bodyA, RigidBody bodyB, Vector2 localAxis, Vector2 localAnchorA, Vector2 localAnchorB, float min = 1, float max = -1) { Vector3 bodyPosA = bodyA.GameObj.Transform.Pos; Vector3 bodyPosB = bodyB.GameObj.Transform.Pos; Vector2 worldAxis = bodyB.GameObj.Transform.GetWorldVector(localAxis).Normalized; Vector2 worldAnchorB = bodyB.GameObj.Transform.GetWorldPoint(localAnchorB); this.DrawWorldAxisConstraint(canvas, bodyA, worldAxis, localAnchorA, worldAnchorB, min, max); }
private void EditorForm_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.SameObjects) return; if (!e.AffectedCategories.HasFlag(ObjectSelection.Category.GameObjCmp) && !e.AffectedCategories.HasFlag(ObjectSelection.Category.Other)) return; // Collider selection changed if ((e.AffectedCategories & ObjectSelection.Category.GameObjCmp) != ObjectSelection.Category.None) { RigidBody newBody = this.QuerySelectedCollider(); if (newBody != this.selectedBody) this.LeaveCursorState(); DualityEditorApp.Deselect(this, ObjectSelection.Category.Other); this.selectedBody = newBody; } // Other selection changed if ((e.AffectedCategories & ObjectSelection.Category.Other) != ObjectSelection.Category.None) { if (e.Current.OfType<ShapeInfo>().Any()) this.allObjSel = e.Current.OfType<ShapeInfo>().Select(s => SelShape.Create(s) as SelObj).ToList(); else this.allObjSel = new List<SelObj>(); // Update indirect object selection this.indirectObjSel.Clear(); // Update (parent-free) action object selection this.actionObjSel = this.allObjSel.ToList(); } this.InvalidateSelectionStats(); this.UpdateToolbar(); this.Invalidate(); }
private void DrawLocalAxisMotor(Canvas canvas, RigidBody bodyA, RigidBody bodyB, Vector2 localAxis, Vector2 localAnchorA, Vector2 localAnchorB, float speed, float maxForce, float offset) { Vector3 bodyPosA = bodyA.GameObj.Transform.Pos; Vector3 bodyPosB = bodyB.GameObj.Transform.Pos; Vector2 worldAxis = bodyB.GameObj.Transform.GetWorldVector(localAxis).Normalized; Vector2 worldAnchorB = bodyB.GameObj.Transform.GetWorldPoint(localAnchorB); this.DrawWorldAxisMotor(canvas, bodyA, worldAxis, localAnchorA, worldAnchorB, speed, maxForce, offset); }
private List<ShapeInfo> PickShapes(RigidBody body, Vector2 worldCoord, Vector2 worldSize) { Rect worldRect = new Rect(worldCoord.X, worldCoord.Y, worldSize.X, worldSize.Y); // Do a physical picking operation List<ShapeInfo> result = body.PickShapes(worldCoord, worldSize); // Special case for LoopShapes, because they are by definition unpickable foreach (LoopShapeInfo loop in body.Shapes.OfType<LoopShapeInfo>()) { bool hit = false; for (int i = 0; i < loop.Vertices.Length; i++) { Vector2 worldV1 = body.GameObj.Transform.GetWorldPoint(loop.Vertices[i]); Vector2 worldV2 = body.GameObj.Transform.GetWorldPoint(loop.Vertices[(i + 1) % loop.Vertices.Length]); hit = hit || MathF.LinesCross( worldRect.TopLeft.X, worldRect.TopLeft.Y, worldRect.TopRight.X, worldRect.TopRight.Y, worldV1.X, worldV1.Y, worldV2.X, worldV2.Y); hit = hit || MathF.LinesCross( worldRect.TopLeft.X, worldRect.TopLeft.Y, worldRect.BottomLeft.X, worldRect.BottomLeft.Y, worldV1.X, worldV1.Y, worldV2.X, worldV2.Y); hit = hit || MathF.LinesCross( worldRect.BottomRight.X, worldRect.BottomRight.Y, worldRect.TopRight.X, worldRect.TopRight.Y, worldV1.X, worldV1.Y, worldV2.X, worldV2.Y); hit = hit || MathF.LinesCross( worldRect.BottomRight.X, worldRect.BottomRight.Y, worldRect.BottomLeft.X, worldRect.BottomLeft.Y, worldV1.X, worldV1.Y, worldV2.X, worldV2.Y); hit = hit || worldRect.Contains(worldV1) || worldRect.Contains(worldV2); if (hit) break; } if (hit) { result.Add(loop); continue; } } return result; }
private void DrawLocalFrictionMarker(Canvas canvas, RigidBody body, Vector2 anchor) { Vector3 colliderPos = body.GameObj.Transform.Pos; ColorRgba clr = this.JointColor; float markerCircleRad = body.BoundRadius * 0.02f; Vector2 anchorToWorld = body.GameObj.Transform.GetWorldVector(anchor); canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr)); canvas.FillCircle( colliderPos.X + anchorToWorld.X, colliderPos.Y + anchorToWorld.Y, colliderPos.Z, markerCircleRad * 0.5f); canvas.DrawCircle( colliderPos.X + anchorToWorld.X, colliderPos.Y + anchorToWorld.Y, colliderPos.Z, markerCircleRad); canvas.DrawCircle( colliderPos.X + anchorToWorld.X, colliderPos.Y + anchorToWorld.Y, colliderPos.Z, markerCircleRad * 1.5f); }