private static void OnEntered() { switchLock++; if (current.ResWeak != null) { // Apply physical properties ResetPhysics(); physicsWorld.Gravity = PhysicsConvert.ToPhysicalUnit(current.ResWeak.GlobalGravity / Time.SPFMult); // When in the editor, apply prefab links if (DualityApp.ExecEnvironment == DualityApp.ExecutionEnvironment.Editor) { current.ResWeak.ApplyPrefabLinks(); } // When running the game, break prefab links if (DualityApp.ExecContext == DualityApp.ExecutionContext.Game) { current.ResWeak.BreakPrefabLinks(); } // Activate GameObjects foreach (GameObject o in current.ResWeak.ActiveObjects.ToArray()) { o.OnActivate(); } } isSwitching = false; if (Entered != null) { Entered(current, null); } switchLock--; }
protected static Vector2 GetFarseerPoint(RigidBody c, Vector2 dualityPoint) { if (c == null) { return(PhysicsConvert.ToPhysicalUnit(dualityPoint)); } float scale = (c.GameObj != null && c.GameObj.Transform != null) ? c.GameObj.Transform.Scale : 1.0f; return(PhysicsConvert.ToPhysicalUnit(dualityPoint * scale)); }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } FixedFrictionJoint j = this.joint as FixedFrictionJoint; j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchor); j.MaxForce = PhysicsConvert.ToPhysicalUnit(this.maxForce) / Time.SPFMult; j.MaxTorque = PhysicsConvert.ToPhysicalUnit(this.maxTorque) / Time.SPFMult; }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } RopeJoint j = this.joint as RopeJoint; j.LocalAnchorB = GetFarseerPoint(this.BodyB, this.localAnchorB); j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchorA); j.MaxLength = PhysicsConvert.ToPhysicalUnit(this.maxLength); }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } AngleJoint j = this.joint as AngleJoint; j.TargetAngle = this.angle; j.BiasFactor = this.biasFactor; j.Softness = this.softness; j.MaxImpulse = this.maxImpulse < 0.0f ? float.MaxValue : PhysicsConvert.ToPhysicalUnit(this.maxImpulse); }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } FixedMouseJoint j = this.joint as FixedMouseJoint; j.WorldAnchorB = PhysicsConvert.ToPhysicalUnit(this.worldAnchor); j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchor); j.DampingRatio = this.dampingRatio; j.Frequency = this.frequency; j.MaxForce = PhysicsConvert.ToPhysicalUnit(this.maxForce) / Time.SPFMult; }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } FixedDistanceJoint j = this.joint as FixedDistanceJoint; j.WorldAnchorB = PhysicsConvert.ToPhysicalUnit(this.worldAnchor); j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchor); j.DampingRatio = this.dampingRatio; j.Frequency = this.frequency; j.Length = PhysicsConvert.ToPhysicalUnit(this.length); }
private FarseerPhysics.Common.Vertices CreateVertices(float scale) { if (this.vertices == null || this.vertices.Length < 3) { return(null); } Vector2[] vertices = this.vertices.ToArray(); FarseerPhysics.Common.Vertices farseerVert = new FarseerPhysics.Common.Vertices(vertices.Length); for (int i = 0; i < vertices.Length; i++) { farseerVert.Add(new Vector2( PhysicsConvert.ToPhysicalUnit(vertices[i].X * scale), PhysicsConvert.ToPhysicalUnit(vertices[i].Y * scale))); } return(farseerVert); }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } LineJoint j = this.joint as LineJoint; j.LocalAnchorB = GetFarseerPoint(this.BodyB, this.localAnchorB); j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchorA); j.LocalXAxis = this.moveAxis; j.MotorEnabled = this.motorEnabled; j.MotorSpeed = this.motorSpeed / Time.SPFMult; j.MaxMotorTorque = PhysicsConvert.ToPhysicalUnit(this.maxMotorTorque / Time.SPFMult); j.DampingRatio = this.dampingRatio; j.Frequency = this.frequency; }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } PulleyJoint j = this.joint as PulleyJoint; j.LocalAnchorB = GetFarseerPoint(this.BodyB, this.localAnchorB); j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchorA); j.GroundAnchorB = PhysicsConvert.ToPhysicalUnit(this.worldAnchorB); j.GroundAnchorA = PhysicsConvert.ToPhysicalUnit(this.worldAnchorA); j.MaxLengthA = PhysicsConvert.ToPhysicalUnit(this.maxLengthA); j.MaxLengthB = PhysicsConvert.ToPhysicalUnit(this.maxLengthB); j.TotalLength = PhysicsConvert.ToPhysicalUnit(this.totalLength); j.Ratio = this.ratio; }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } FixedRevoluteJoint j = this.joint as FixedRevoluteJoint; j.WorldAnchorB = PhysicsConvert.ToPhysicalUnit(this.worldAnchor); j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchor); j.MotorEnabled = this.motorEnabled; j.MotorSpeed = -this.motorSpeed / Time.SPFMult; j.MaxMotorTorque = PhysicsConvert.ToPhysicalUnit(this.maxMotorTorque) / Time.SPFMult; j.LimitEnabled = this.limitEnabled; j.LowerLimit = -this.upperLimit; j.UpperLimit = -this.lowerLimit; j.ReferenceAngle = -this.refAngle; }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } PrismaticJoint j = this.joint as PrismaticJoint; j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchorA); j.LocalAnchorB = GetFarseerPoint(this.BodyB, this.localAnchorB); j.ReferenceAngle = this.refAngle; j.LocalXAxis1 = this.BodyA.GameObj.Transform.GetWorldVector(this.moveAxis).Normalized; j.LimitEnabled = this.limitEnabled; j.LowerLimit = -PhysicsConvert.ToPhysicalUnit(this.upperLimit); j.UpperLimit = -PhysicsConvert.ToPhysicalUnit(this.lowerLimit); j.MotorEnabled = this.motorEnabled; j.MotorSpeed = -PhysicsConvert.ToPhysicalUnit(this.motorSpeed) / Time.SPFMult; j.MaxMotorForce = PhysicsConvert.ToPhysicalUnit(this.maxMotorForce) / Time.SPFMult; }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } FixedPrismaticJoint j = this.joint as FixedPrismaticJoint; j.LocalAnchorA = PhysicsConvert.ToPhysicalUnit(this.worldAnchor); j.LocalAnchorB = Vector2.Zero; j.ReferenceAngle = this.refAngle; j.LocalXAxis1 = this.moveAxis; j.LimitEnabled = this.limitEnabled; j.LowerLimit = PhysicsConvert.ToPhysicalUnit(this.lowerLimit); j.UpperLimit = PhysicsConvert.ToPhysicalUnit(this.upperLimit); j.MotorEnabled = this.motorEnabled; j.MotorSpeed = PhysicsConvert.ToPhysicalUnit(this.motorSpeed) / Time.SPFMult; j.MaxMotorForce = PhysicsConvert.ToPhysicalUnit(this.maxMotorForce) / Time.SPFMult; }
private static void OnEntered() { if (current.ResWeak != null) { ResetPhysics(); physicsWorld.Gravity = PhysicsConvert.ToPhysicalUnit(current.ResWeak.GlobalGravity / Time.SPFMult); // When in the editor, apply prefab links if (DualityApp.ExecEnvironment == DualityApp.ExecutionEnvironment.Editor) { current.ResWeak.ApplyPrefabLinks(); } // Activate GameObjects foreach (GameObject o in current.ResWeak.ActiveObjects.ToArray()) { o.OnActivate(); } } if (Entered != null) { Entered(current, null); } }
internal override void UpdateFixture(bool updateShape = false) { base.UpdateFixture(updateShape); if (this.fixture == null) { return; } if (this.Parent == null) { return; } float scale = 1.0f; if (this.Parent.GameObj != null && this.Parent.GameObj.Transform != null) { scale = this.Parent.GameObj.Transform.Scale; } CircleShape circle = this.fixture.Shape as CircleShape; circle.Radius = PhysicsConvert.ToPhysicalUnit(this.radius * scale); circle.Position = PhysicsConvert.ToPhysicalUnit(new Vector2(this.position.X * scale, this.position.Y * scale)); }
/// <summary> /// Updates the Scene /// </summary> internal void Update() { if (!this.IsCurrent) { throw new InvalidOperationException("Can't update non-current Scene!"); } switchLock++; // Update physics bool physUpdate = false; double physBegin = Time.MainTimer.TotalMilliseconds; if (Scene.PhysicsFixedTime) { physicsAcc += Time.MsPFMult * Time.TimeMult; int iterations = 0; if (physicsAcc >= Time.MsPFMult) { Profile.TimeUpdatePhysics.BeginMeasure(); double timeUpdateBegin = Time.MainTimer.TotalMilliseconds; while (physicsAcc >= Time.MsPFMult) { // Catch up on updating progress FarseerPhysics.Settings.VelocityThreshold = PhysicsConvert.ToPhysicalUnit(DualityApp.AppData.PhysicsVelocityThreshold / Time.SPFMult); physicsWorld.Step(Time.SPFMult); physicsAcc -= Time.MsPFMult; iterations++; double timeSpent = Time.MainTimer.TotalMilliseconds - timeUpdateBegin; if (timeSpent >= Time.MsPFMult * 10.0f) { break; // Emergency exit } } physUpdate = true; Profile.TimeUpdatePhysics.EndMeasure(); } } else { Profile.TimeUpdatePhysics.BeginMeasure(); FarseerPhysics.Settings.VelocityThreshold = PhysicsConvert.ToPhysicalUnit(Time.TimeMult * DualityApp.AppData.PhysicsVelocityThreshold / Time.SPFMult); physicsWorld.Step(Time.TimeMult * Time.SPFMult); if (Time.TimeMult == 0.0f) { physicsWorld.ClearForces(); // Complete freeze? Clear forces, so they don't accumulate. } physicsAcc = PhysicsAccStart; physUpdate = true; Profile.TimeUpdatePhysics.EndMeasure(); } double physTime = Time.MainTimer.TotalMilliseconds - physBegin; // Apply Farseers internal measurements to Duality if (physUpdate) { Profile.TimeUpdatePhysicsAddRemove.Set(1000.0f * physicsWorld.AddRemoveTime / System.Diagnostics.Stopwatch.Frequency); Profile.TimeUpdatePhysicsContacts.Set(1000.0f * physicsWorld.ContactsUpdateTime / System.Diagnostics.Stopwatch.Frequency); Profile.TimeUpdatePhysicsContinous.Set(1000.0f * physicsWorld.ContinuousPhysicsTime / System.Diagnostics.Stopwatch.Frequency); Profile.TimeUpdatePhysicsController.Set(1000.0f * physicsWorld.ControllersUpdateTime / System.Diagnostics.Stopwatch.Frequency); Profile.TimeUpdatePhysicsSolve.Set(1000.0f * physicsWorld.SolveUpdateTime / System.Diagnostics.Stopwatch.Frequency); } // Update low fps physics state if (!physicsLowFps) { physicsLowFps = Time.LastDelta > Time.MsPFMult && physTime > Time.LastDelta * 0.85f; } else { physicsLowFps = !(Time.LastDelta < Time.MsPFMult * 0.9f || physTime < Time.LastDelta * 0.6f); } Profile.TimeUpdateScene.BeginMeasure(); { // Update all GameObjects GameObject[] activeObj = this.objectManager.ActiveObjects.ToArray(); foreach (GameObject obj in activeObj) { obj.Update(); } } Profile.TimeUpdateScene.EndMeasure(); // Perform a scheduled Scene switch if (switchToScheduled) { Scene.Current = switchToTarget.Res; switchToTarget = null; switchToScheduled = false; } switchLock--; }
private FarseerPhysics.Common.Vertices CreateVertices(float scale) { if (this.vertices == null || this.vertices.Length < 3) { return(null); } if (!MathF.IsPolygonConvex(this.vertices)) { return(null); } // Be sure to not exceed the maximum vertex count Vector2[] sortedVertices = this.vertices.ToArray(); if (sortedVertices.Length > MaxVertices) { Array.Resize(ref sortedVertices, MaxVertices); Log.Core.WriteWarning("Maximum Polygon Shape vertex count exceeded: {0} > {1}", this.vertices.Length, MaxVertices); } // Don't let all vertices be aligned on one axis (zero-area polygons) if (sortedVertices.Length > 0) { Vector2 firstVertex = sortedVertices[0]; bool alignX = true; bool alignY = true; for (int i = 0; i < sortedVertices.Length; i++) { if (sortedVertices[i].X != firstVertex.X) { alignX = false; } if (sortedVertices[i].Y != firstVertex.Y) { alignY = false; } if (!alignX && !alignY) { break; } } if (alignX) { sortedVertices[0].X += 0.01f; } if (alignY) { sortedVertices[0].Y += 0.01f; } } // Sort vertices clockwise before submitting them to Farseer Vector2 centroid = Vector2.Zero; for (int i = 0; i < sortedVertices.Length; i++) { centroid += sortedVertices[i]; } centroid /= sortedVertices.Length; sortedVertices.StableSort(delegate(Vector2 first, Vector2 second) { return(MathF.RoundToInt( 1000000.0f * MathF.Angle(centroid.X, centroid.Y, first.X, first.Y) - 1000000.0f * MathF.Angle(centroid.X, centroid.Y, second.X, second.Y))); }); // Shrink a little bit //for (int i = 0; i < sortedVertices.Length; i++) //{ // Vector2 rel = (sortedVertices[i] - centroid); // float len = rel.Length; // sortedVertices[i] = centroid + rel.Normalized * MathF.Max(0.0f, len - 1.5f); //} // Submit vertices FarseerPhysics.Common.Vertices v = new FarseerPhysics.Common.Vertices(sortedVertices.Length); for (int i = 0; i < sortedVertices.Length; i++) { v.Add(new Vector2( PhysicsConvert.ToPhysicalUnit(sortedVertices[i].X * scale), PhysicsConvert.ToPhysicalUnit(sortedVertices[i].Y * scale))); } return(v); }