[Test] public void SwitchToDuringEnter() { // Set up some objects Scene scene = new Scene(); Scene scene2 = new Scene(); // Switch to the first Scene regularly { Scene.SwitchTo(scene); Assert.AreEqual(Scene.Current, scene); } // Switch to the second while entering { Scene.SwitchTo(null); GameObject obj = new GameObject("SwitchObject"); var switchComponent = new InitSwitchToSceneComponent { Target = scene2 }; obj.AddComponent(switchComponent); scene.AddObject(obj); Scene.SwitchTo(scene); DualityApp.Update(); Assert.False(switchComponent.Switched); Assert.AreEqual(Scene.Current, scene2); } // Clean up scene.Dispose(); scene2.Dispose(); }
void INativeWindow.Run() { while (DualityApp.ExecContext != DualityApp.ExecutionContext.Terminated) { DualityApp.Update(); DualityApp.Render(null, new Rect(DualityApp.UserData.WindowSize), DualityApp.UserData.WindowSize); } }
void INativeWindow.Run() { while (DualityApp.ExecContext != DualityApp.ExecutionContext.Terminated) { DualityApp.Update(); DualityApp.Render(null, new Rect(640, 480), new Vector2(640, 480)); } }
void INativeWindow.Run() { while (DualityApp.ExecContext != DualityApp.ExecutionContext.Terminated) { DualityApp.Update(); DualityApp.Render(new Rect(DualityApp.UserData.GfxWidth, DualityApp.UserData.GfxHeight)); } }
/// <summary> /// This test will determine whether a <see cref="Scene"/> can be activated, updated and deactivated /// in isolation from the global <see cref="Scene.Current"/> setting. /// </summary> [Test] public void IsolatedSimulation() { // Create an isolated new test scene with a ball and a platform Scene scene = new Scene(); GameObject ball = new GameObject("Ball"); Transform ballTransform = ball.AddComponent <Transform>(); RigidBody ballBody = ball.AddComponent <RigidBody>(); ballBody.AddShape(new CircleShapeInfo(32.0f, new Vector2(0.0f, 0.0f), 1.0f)); ball.AddComponent <RigidBodyRenderer>(); scene.AddObject(ball); GameObject platform = new GameObject("Platform"); Transform platformTransform = platform.AddComponent <Transform>(); platformTransform.Pos = new Vector3(0.0f, 128.0f, 0.0f); RigidBody platformBody = platform.AddComponent <RigidBody>(); platformBody.AddShape(new ChainShapeInfo(new[] { new Vector2(-128.0f, 0.0f), new Vector2(128.0f, 0.0f) })); platformBody.BodyType = BodyType.Static; platform.AddComponent <RigidBodyRenderer>(); scene.AddObject(platform); // Do a single, fixed-step Duality update in order to set up // Time.DeltaTime in a predictable way. DualityApp.Update(true); // Assert that the isolated scene remains unaffected Assert.AreEqual(new Vector3(0.0f, 0.0f, 0.0f), ballTransform.Pos); Assert.AreEqual(new Vector3(0.0f, 128.0f, 0.0f), platformTransform.Pos); // Activate the scene to prepare for simulation scene.Activate(); // Run the simulation for a few fixed-step frames for (int i = 0; i < 100; i++) { scene.Update(); } // Deactivate the scene again scene.Deactivate(); // Assert that the balls position is within expected values Assert.IsTrue(ballTransform.Pos.Y > 96.0f); Assert.IsTrue(ballTransform.Pos.Y < 128.0f); Assert.IsTrue(Math.Abs(ballTransform.Pos.X) < 1.00f); Assert.IsTrue(Math.Abs(ballTransform.Pos.Z) < 1.00f); }
[Test] public void FallingBallOnPlatform() { Scene scene = new Scene(); Scene.SwitchTo(scene); // Create the ball GameObject ball = new GameObject("Ball"); Transform ballTransform = ball.AddComponent <Transform>(); RigidBody ballBody = ball.AddComponent <RigidBody>(); ballBody.Restitution = 0f; CollisionEventReceiver listener = ball.AddComponent <CollisionEventReceiver>(); ballBody.AddShape(new CircleShapeInfo(1, new Vector2(0, 0), 1)); scene.AddObject(ball); // Create the platform GameObject platform = new GameObject("Platform"); Transform platformTrans = platform.AddComponent <Transform>(); platformTrans.Pos = new Vector3(0, 5, 0); RigidBody platformBody = platform.AddComponent <RigidBody>(); platformBody.Restitution = 0f; platformBody.AddShape(new ChainShapeInfo(new[] { new Vector2(-1, 0), new Vector2(1, 0), })); platformBody.BodyType = BodyType.Static; scene.AddObject(platform); // Simulate some update steps for (int i = 0; i < 10; i++) { DualityApp.Update(true); } // Check if the position is within expected values Assert.IsTrue(ballTransform.Pos.Y > 3f); Assert.IsTrue(ballTransform.Pos.Y < 5f); Assert.IsTrue(Math.Abs(ballTransform.Pos.X) < 0.01f); Assert.IsTrue(Math.Abs(ballTransform.Pos.Z) < 0.01f); // Check if the collision events were triggered // First one should always be a begin Assert.IsTrue(listener.Collisions[0].Type == CollisionEventReceiver.CollisionType.Begin); // The ones after that should all be of type Solve. There should be no event of type End since there is no bouncing. Assert.IsTrue(listener.Collisions.Skip(1).All(x => x.Type == CollisionEventReceiver.CollisionType.Solve)); }
[Test] public void SwitchReloadDeferredDispose() { // Inject some pseudo loading code for our Scene. const string TestSceneName = "TestScene"; EventHandler <ResourceResolveEventArgs> resolveHandler = delegate(object sender, ResourceResolveEventArgs e) { if (e.RequestedContent == TestSceneName) { e.Resolve(new Scene()); } }; ContentProvider.ResourceResolve += resolveHandler; // Retrieve the Scene and make sure it's always the same Scene scene = ContentProvider.RequestContent <Scene>(TestSceneName).Res; Assert.IsNotNull(scene); { Scene scene2 = ContentProvider.RequestContent <Scene>(TestSceneName).Res; Assert.AreSame(scene, scene2); } // Switch to the Scene regularly { Scene.SwitchTo(scene); Assert.AreSame(Scene.Current, scene); } // Reload the Scene during update while using deferred disposal { GameObject obj = new GameObject("SwitchObject"); obj.AddComponent <UpdateReloadSceneComponent>(); scene.AddObject(obj); Assert.AreSame(Scene.Current, scene); DualityApp.Update(); Assert.AreNotSame(Scene.Current, scene); Assert.AreEqual(TestSceneName, Scene.Current.Path); } // Clean up ContentProvider.ResourceResolve -= resolveHandler; scene.Dispose(); }
private void OnUpdate(double milliseconds) { if (DualityApp.ExecContext == DualityApp.ExecutionContext.Terminated) { return; } DualityApp.Update(); Vector2 imageSize; Rect viewportRect; DualityApp.CalculateGameViewport(this.Size, out viewportRect, out imageSize); DualityApp.Render(null, viewportRect, imageSize); window.Invoke("requestAnimationFrame", updateDelegate); }
protected override void OnUpdateFrame(FrameEventArgs e) { //base.OnUpdateFrame(e); if (DualityApp.ExecContext == DualityApp.ExecutionContext.Terminated) { if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) { (Context as Activity).FinishAndRemoveTask(); } else { (Context as Activity).Finish(); } System.Environment.Exit(0); return; } DualityApp.Update(); }
[Test] public void EnforceOrderSceneUpdate() { EventOrderLog eventLog = new EventOrderLog(); eventLog.EventFilter = EventType.Update; Scene scene = this.GenerateSampleScene(10, typeof(TestComponentA1), typeof(TestComponentA2), typeof(TestComponentA3), typeof(TestComponentA4), typeof(TestComponentA5)); Scene.SwitchTo(scene, true); this.AssignEventLog(scene, eventLog); DualityApp.Update(); this.AssertEventOrder(eventLog, 5 * 10, Component.ExecOrder, false); Scene.SwitchTo(null, true); }
private void OnUpdateFrame(FrameEventArgs e) { if (DualityApp.ExecContext == DualityApp.ExecutionContext.Terminated) { this.internalWindow.Close(); return; } // Give the processor a rest if we have the time, don't use 100% CPU even without VSync if (this.frameLimiterWatch.IsRunning && this.refreshMode == RefreshMode.ManualSync) { while (this.frameLimiterWatch.Elapsed.TotalMilliseconds < Time.MsPFMult) { // Enough leftover time? Risk a millisecond sleep. //if (this.frameLimiterWatch.Elapsed.TotalMilliseconds < Time.MsPFMult * 0.75f) // System.Threading.Thread.Sleep(1); } } this.frameLimiterWatch.Restart(); DualityApp.Update(); }
protected override void OnUpdateFrame(FrameEventArgs e) { if (DualityApp.ExecContext == DualityApp.ExecutionContext.Terminated) { this.Close(); return; } if (!isDebugging && !isProfiling) // Don't limit frame rate when debugging or profiling. { //// Assure we'll at least wait 16 ms until updating again. //if (this.frameLimiterWatch.IsRunning) //{ // while (this.frameLimiterWatch.Elapsed.TotalSeconds < 0.016d) // { // // Go to sleep if we'd have to wait too long // if (this.frameLimiterWatch.Elapsed.TotalSeconds < 0.01d) // System.Threading.Thread.Sleep(1); // } //} // Give the processor a rest if we have the time, don't use 100% CPU even without VSync if (this.frameLimiterWatch.IsRunning && this.VSync == VSyncMode.Off) { while (this.frameLimiterWatch.Elapsed.TotalMilliseconds < Time.MsPFMult) { // Enough leftover time? Risk a millisecond sleep. if (this.frameLimiterWatch.Elapsed.TotalMilliseconds < Time.MsPFMult * 0.75f) { System.Threading.Thread.Sleep(1); } } } this.frameLimiterWatch.Restart(); } this.mainJoystickDriver.Poll(); DualityApp.Update(); }
protected override void OnUpdateFrame(FrameEventArgs e) { base.OnUpdateFrame(e); if (!_isDebugging && !_isProfiling) // Don't limit frame rate when debugging or profiling. { //// Assure we'll at least wait 16 ms until updating again. //if (this.frameLimiterWatch.IsRunning) //{ // while (this.frameLimiterWatch.Elapsed.TotalSeconds < 0.016d) // { // // Go to sleep if we'd have to wait too long // if (this.frameLimiterWatch.Elapsed.TotalSeconds < 0.01d) // System.Threading.Thread.Sleep(1); // } //} // Give the processor a rest if we have the time, don't use 100% CPU even without VSync /* DEBT: waiting for VSync no control for VSync on android */ if (_frameLimiterWatch.IsRunning) // && this.VSync == VSyncMode.Off) { while (_frameLimiterWatch.Elapsed.TotalMilliseconds < Time.MsPFMult) { // Enough leftover time? Risk a millisecond sleep. if (_frameLimiterWatch.Elapsed.TotalMilliseconds < Time.MsPFMult * 0.75f) { System.Threading.Thread.Sleep(1); } } } _frameLimiterWatch.Restart(); } DualityApp.Update(); }
[Test] public void VelocityInHierarchy() { // In this test case, we'll set up a parent and a child transform // to see if changes to the parent affect the child transforms velocity value GameObject parentObj = new GameObject("Parent"); GameObject obj = new GameObject("Child", parentObj); Transform parentTransform = parentObj.AddComponent <Transform>(); Transform transform = obj.AddComponent <Transform>(); VelocityTracker tracker = obj.AddComponent <VelocityTracker>(); // Since velocity values are only updated after the frame ends, we need // a full scene setup to simulate an update cycle using (Scene testScene = new Scene()) { // Setup and enter the scene testScene.AddObject(parentObj); Scene.SwitchTo(testScene, true); DualityApp.Update(true); // Identity parent and a moving child parentTransform.Pos = Vector3.Zero; parentTransform.Angle = 0.0f; parentTransform.Scale = 1.0f; transform.Pos = Vector3.Zero; transform.Angle = 0.0f; transform.Scale = 1.0f; transform.MoveByLocal(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.DegToRad(90.0f)); DualityApp.Update(true); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), tracker.LastMovement, "Absolute child velocity"); AssertEqual(MathF.DegToRad(90.0f), tracker.LastAngleMovement, "Absolute child angle velocity"); // Transformed parent and a moving child parentTransform.Pos = new Vector3(1.0f, 2.0f, 3.0f); parentTransform.Angle = MathF.DegToRad(90.0f); parentTransform.Scale = 2.0f; transform.Pos = Vector3.Zero; transform.Angle = 0.0f; transform.Scale = 1.0f; transform.MoveByLocal(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.DegToRad(90.0f)); DualityApp.Update(true); AssertEqual(new Vector3(0.0f, 2.0f, 0.0f), tracker.LastMovement, "Absolute child velocity"); AssertEqual(MathF.DegToRad(90.0f), tracker.LastAngleMovement, "Absolute child angle velocity"); // Moving parent and a transformed child parentTransform.Pos = Vector3.Zero; parentTransform.Angle = 0.0f; parentTransform.Scale = 1.0f; transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); transform.Angle = 0.0f; transform.Scale = 1.0f; parentTransform.MoveByLocal(new Vector3(1.0f, 0.0f, 0.0f)); DualityApp.Update(true); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), tracker.LastMovement, "Absolute child velocity"); // Moving parent and a transformed, moving child parentTransform.Pos = Vector3.Zero; parentTransform.Angle = 0.0f; parentTransform.Scale = 1.0f; transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); transform.Angle = 0.0f; transform.Scale = 1.0f; transform.MoveByLocal(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.DegToRad(90.0f)); parentTransform.MoveByLocal(new Vector3(1.0f, 0.0f, 0.0f)); DualityApp.Update(true); AssertEqual(new Vector3(2.0f, 0.0f, 0.0f), tracker.LastMovement, "Absolute child velocity"); AssertEqual(MathF.DegToRad(90.0f), tracker.LastAngleMovement, "Absolute child angle velocity"); } }
[Test] public void VelocityTeleportAndMove() { GameObject obj = new GameObject("TestObject"); Transform transform = obj.AddComponent <Transform>(); VelocityTracker tracker = obj.AddComponent <VelocityTracker>(); // Since velocity values are only updated after the frame ends, we need // a full scene setup to simulate an update cycle using (Scene testScene = new Scene()) { // Setup and enter the scene testScene.AddObject(obj); Scene.SwitchTo(testScene, true); DualityApp.Update(true); // The object is at rest transform.Pos = Vector3.Zero; transform.Angle = 0.0f; DualityApp.Update(true); AssertEqual(Vector3.Zero, tracker.LastMovement, "Velocity at rest"); AssertEqual(0.0f, tracker.LastAngleMovement, "Angle velocity at rest"); // The object is teleported transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); transform.Angle = MathF.RadAngle90; DualityApp.Update(true); AssertEqual(Vector3.Zero, tracker.LastMovement, "Velocity after teleport"); AssertEqual(0.0f, tracker.LastAngleMovement, "Angle velocity after teleport"); // The object is moved transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.RadAngle90); DualityApp.Update(true); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), tracker.LastMovement, "Velocity after move"); AssertEqual(MathF.RadAngle90, tracker.LastAngleMovement, "Angle velocity after teleport"); // The object rests for a frame DualityApp.Update(true); AssertEqual(Vector3.Zero, tracker.LastMovement, "Velocity after one frame rest"); AssertEqual(0.0f, tracker.LastAngleMovement, "Angle velocity after one frame rest"); // The object is moved, then teleported transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.RadAngle90); transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); transform.Angle = MathF.RadAngle90; DualityApp.Update(true); AssertEqual(Vector3.Zero, tracker.LastMovement, "Velocity after move, then teleport"); AssertEqual(0.0f, tracker.LastAngleMovement, "Angle velocity after move, then teleport"); // The object is moved, then teleported, then moved again transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.RadAngle90); transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); transform.Angle = MathF.RadAngle90; transform.MoveBy(new Vector3(2.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.RadAngle45); DualityApp.Update(true); AssertEqual(new Vector3(2.0f, 0.0f, 0.0f), tracker.LastMovement, "Velocity after move, then teleport, then move"); AssertEqual(MathF.RadAngle45, tracker.LastAngleMovement, "Angle velocity after move, then teleport, then move"); } }
[Test] public void TransformHierarchyVelocity() { // In this test case, we'll set up a parent and a child transform // to see if changes to the parent affect the child transforms velocity value GameObject parentObj = new GameObject("Parent"); GameObject obj = new GameObject("Child", parentObj); Transform parentTransform = parentObj.AddComponent <Transform>(); Transform transform = obj.AddComponent <Transform>(); // Since velocity values are only updated after the frame ends, we need // a full scene setup to simulate an update cycle using (Scene testScene = new Scene()) { // Setup and enter the scene testScene.AddObject(parentObj); Scene.SwitchTo(testScene, true); DualityApp.Update(true); // Identity parent and a moving child parentTransform.Pos = Vector3.Zero; parentTransform.Angle = 0.0f; parentTransform.Scale = 1.0f; transform.Pos = Vector3.Zero; transform.Angle = 0.0f; transform.Scale = 1.0f; transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.DegToRad(90.0f)); DualityApp.Update(true); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.Vel, "Absolute child velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.RelativeAngleVel, "Relative child angle velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.AngleVel, "Absolute child angle velocity"); // Transformed parent and a moving child parentTransform.Pos = new Vector3(1.0f, 2.0f, 3.0f); parentTransform.Angle = MathF.DegToRad(90.0f); parentTransform.Scale = 2.0f; transform.Pos = Vector3.Zero; transform.Angle = 0.0f; transform.Scale = 1.0f; transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.DegToRad(90.0f)); DualityApp.Update(true); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); AssertEqual(new Vector3(0.0f, 2.0f, 0.0f), transform.Vel, "Absolute child velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.RelativeAngleVel, "Relative child angle velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.AngleVel, "Absolute child angle velocity"); // Moving parent and a transformed child parentTransform.Pos = Vector3.Zero; parentTransform.Angle = 0.0f; parentTransform.Scale = 1.0f; transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); transform.Angle = 0.0f; transform.Scale = 1.0f; parentTransform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); DualityApp.Update(true); AssertEqual(new Vector3(0.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.Vel, "Absolute child velocity"); // Moving parent and a transformed, moving child parentTransform.Pos = Vector3.Zero; parentTransform.Angle = 0.0f; parentTransform.Scale = 1.0f; transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); transform.Angle = 0.0f; transform.Scale = 1.0f; transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.DegToRad(90.0f)); parentTransform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); DualityApp.Update(true); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); AssertEqual(new Vector3(2.0f, 0.0f, 0.0f), transform.Vel, "Absolute child velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.RelativeAngleVel, "Relative child angle velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.AngleVel, "Absolute child angle velocity"); // ToDo: Fix how Transform adds up velocity due to parent transform // rotation in order to make the test cases below work. The current // implementation only works with small per-frame rotations, not big, // sudden ones. // Moving parent and a transformed child //parentTransform.Pos = Vector3.Zero; //parentTransform.Angle = 0.0f; //parentTransform.Scale = 1.0f; //transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); //transform.Angle = 0.0f; //transform.Scale = 1.0f; // //parentTransform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); //parentTransform.TurnBy(MathF.DegToRad(90.0f)); //DualityApp.Update(true); // //AssertEqual(new Vector3(0.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); //AssertEqual(new Vector3(0.0f, 1.0f, 0.0f), transform.Vel, "Absolute child velocity"); //AssertEqual(MathF.DegToRad(0.0f), transform.RelativeAngleVel, "Relative child angle velocity"); //AssertEqual(MathF.DegToRad(90.0f), transform.AngleVel, "Absolute child angle velocity"); // Moving parent and a transformed, moving child //parentTransform.Pos = Vector3.Zero; //parentTransform.Angle = 0.0f; //parentTransform.Scale = 1.0f; //transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); //transform.Angle = 0.0f; //transform.Scale = 1.0f; // //transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); //transform.TurnBy(MathF.DegToRad(90.0f)); //parentTransform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); //parentTransform.TurnBy(MathF.DegToRad(90.0f)); //DualityApp.Update(true); // //AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); //AssertEqual(new Vector3(-1.0f, 3.0f, 0.0f), transform.Vel, "Absolute child velocity"); //AssertEqual(MathF.DegToRad(90.0f), transform.RelativeAngleVel, "Relative child angle velocity"); //AssertEqual(MathF.DegToRad(180.0f), transform.AngleVel, "Absolute child angle velocity"); } }