Exemplo n.º 1
0
        private void Run()
        {
#if XBOX
            this.thread.SetProcessorAffinity(processor);
#endif
            try
            {
                while (true)
                {
                    startEvent.WaitOne();

                    double startTime = Now;

                    if (lastFrame > 0)
                    {
                        double targetFps = 60;
                        double waitTime  = startTime - lastFrame;
                        double newTarget = ((1000d / targetFps) - waitTime);
                        targetMilliseconds = System.Math.Max(2, targetMilliseconds * 0.9 + newTarget * 0.1);
                    }

                    //Console.WriteLine("{0}", targetMilliseconds);

                    Contact            lastContact = null;
                    TestList.TestEntry entry       = testList.GetNextCollisionEntry();
                    while (entry != null && (Now - startTime) < targetMilliseconds) // todo: extract constant
                    {
                        // do collision detection with this entry!
                        ContactTest test = CollisionManager.ContactTests[
                            BoundingVolumeTypeUtil.ToNumber(entry.EntityA.VolumeType),
                            BoundingVolumeTypeUtil.ToNumber(entry.EntityB.VolumeType)
                                           ];


                        Vector3    scale1, position1, scale2, position2;
                        Quaternion rotation1, rotation2;
                        Matrix     worldTransform1, worldTransform2;
                        OrientationHelper.GetTranslation(entry.EntityA.Entity, out position1);
                        OrientationHelper.GetRotation(entry.EntityA.Entity, out rotation1);
                        OrientationHelper.GetScale(entry.EntityA.Entity, out scale1);
                        OrientationHelper.CalculateWorldTransform(ref position1, ref rotation1, ref scale1, out worldTransform1);

                        OrientationHelper.GetTranslation(entry.EntityB.Entity, out position2);
                        OrientationHelper.GetRotation(entry.EntityB.Entity, out rotation2);
                        OrientationHelper.GetScale(entry.EntityB.Entity, out scale2);
                        OrientationHelper.CalculateWorldTransform(ref position2, ref rotation2, ref scale2, out worldTransform2);

                        // the xbox does not like too many allocations. so if possible we recycle the last contact
                        // that we allocated but did not need because there was no collision...
                        Contact contact = null;
                        if (lastContact == null || lastContact.Count > 0)
                        {
                            contact = AllocateContact(entry.EntityA.Entity, entry.EntityB.Entity);
                        }
                        else
                        {
                            lastContact.Recycle(entry.EntityA.Entity, entry.EntityB.Entity);
                        }

                        test(
                            entry.EntityA.Entity, entry.EntityA.Volumes, ref worldTransform1, ref position1, ref rotation1, ref scale1,
                            entry.EntityB.Entity, entry.EntityB.Volumes, ref worldTransform2, ref position2, ref rotation2, ref scale2,
                            entry.EntityA.NeedAllContacts || entry.EntityB.NeedAllContacts, ref contact
                            );
                        if (contact.Count > 0)
                        {
                            Debug.Assert(contact.EntityA == entry.EntityA.Entity && contact.EntityB == entry.EntityB.Entity);
                            contacts.Add(contact);
                        }

                        // get next entry
                        entry = testList.GetNextCollisionEntry();
                    }

                    lastFrame = Now;

                    finishedEvent.Set();
                }
            }
            catch (Exception ex)
            {
                if (!this.aborted)
                {
                    System.Console.WriteLine("unexpected Exception {0}\n{1}\n{2}", ex.GetType().Name, ex.Message, ex.StackTrace);
                    Game.Instance.CrashDebugger.Crash(ex);
                    finishedEvent.Set(); // => the simulationthread should be able to proceed!
                }
            }
        }