/// <summary>
        /// Sends a ray (definied by start and direction) through the scene (all bodies added).
        /// NOTE: For performance reasons terrain and trianglemeshshape aren't checked
        /// against rays (rays are of infinite length). They are checked against segments
        /// which start at rayOrigin and end in rayOrigin + rayDirection.
        /// </summary>
        #region public override bool Raycast(JVector rayOrigin, JVector rayDirection, out JVector normal,out FP fraction)
        public override bool Raycast(FPVector rayOrigin, FPVector rayDirection, RaycastCallback raycast, out RigidBody body, out FPVector normal, out FP fraction)
        {
            body = null; normal = FPVector.zero; fraction = FP.MaxValue;

            FPVector tempNormal; FP tempFraction;
            bool     result = false;

            // TODO: This can be done better in CollisionSystemPersistenSAP
            foreach (IBroadphaseEntity e in bodyList)
            {
                if (e is SoftBody)
                {
                    SoftBody softBody = e as SoftBody;
                    foreach (RigidBody b in softBody.VertexBodies)
                    {
                        if (this.Raycast(b, rayOrigin, rayDirection, out tempNormal, out tempFraction))
                        {
                            if (tempFraction < fraction && (raycast == null || raycast(b, tempNormal, tempFraction)))
                            {
                                body     = b;
                                normal   = tempNormal;
                                fraction = tempFraction;
                                result   = true;
                            }
                        }
                    }
                }
                else
                {
                    RigidBody b = e as RigidBody;

                    if (this.Raycast(b, rayOrigin, rayDirection, out tempNormal, out tempFraction))
                    {
                        if (tempFraction < fraction && (raycast == null || raycast(b, tempNormal, tempFraction)))
                        {
                            body     = b;
                            normal   = tempNormal;
                            fraction = tempFraction;
                            result   = true;
                        }
                    }
                }
            }

            return(result);
        }
Пример #2
0
        public void Restore(IWorld iWorld)
        {
            World world = (World)iWorld;

            List <RigidBody> bodiesToRemove = new List <RigidBody>();

            foreach (RigidBody rb in world.RigidBodies)
            {
                if (!clonedPhysics.ContainsKey(rb.GetInstance()))
                {
                    bodiesToRemove.Add(rb);
                }
            }

            for (index = 0, length = bodiesToRemove.Count; index < length; index++)
            {
                RigidBody rb = bodiesToRemove[index];

                world.RemoveBody(rb);
            }

            foreach (RigidBody rb in world.RigidBodies)
            {
                if (clonedPhysics.ContainsKey(rb.GetInstance()))
                {
                    RigidBodyClone rbClone = clonedPhysics[rb.GetInstance()];
                    rbClone.Restore(world, rb);

                    rb.island = null;
                    rb.arbiters.Clear();
                    rb.arbitersTrigger.Clear();
                }
            }

            foreach (Arbiter arb in world.ArbiterMap.Arbiters)
            {
                for (index = 0, length = arb.contactList.Count; index < length; index++)
                {
                    Contact c = arb.contactList[index];

                    contactsToGiveBack.Add(c);
                }
                arbiterToGiveBack.Add(arb);
            }
            world.ArbiterMap.Clear();

            foreach (Arbiter arb in world.ArbiterTriggerMap.Arbiters)
            {
                foreach (Contact c in arb.contactList)
                {
                    contactsToGiveBack.Add(c);
                }

                arbiterToGiveBack.Add(arb);
            }
            world.ArbiterTriggerMap.Clear();

            for (index = 0, length = world.islands.islands.Count; index < length; index++)
            {
                CollisionIsland ci = world.islands.islands[index];

                collisionIslandToGiveBack.Add(ci);
            }

            for (index = 0, length = clonedArbiters.Count; index < length; index++)
            {
                ArbiterClone arbC = clonedArbiters[index];

                Arbiter arbiter = Arbiter.Pool.GetNew();
                arbC.Restore(arbiter);

                arbiter.body1.arbiters.Add(arbiter);
                arbiter.body2.arbiters.Add(arbiter);

                world.ArbiterMap.Add(new ArbiterKey(arbiter.body1, arbiter.body2), arbiter);
            }

            for (index = 0, length = clonedArbitersTrigger.Count; index < length; index++)
            {
                ArbiterClone arbC = clonedArbitersTrigger[index];

                Arbiter arbiter = Arbiter.Pool.GetNew();
                arbC.Restore(arbiter);

                arbiter.body1.arbitersTrigger.Add(arbiter);
                arbiter.body2.arbitersTrigger.Add(arbiter);

                world.ArbiterTriggerMap.Add(new ArbiterKey(arbiter.body1, arbiter.body2), arbiter);
            }

            world.islands.islands.Clear();

            for (index = 0, length = collisionIslands.Count; index < length; index++)
            {
                CollisionIslandClone ci = collisionIslands[index];

                CollisionIsland collisionIsland = IslandManager.Pool.GetNew();
                ci.Restore(collisionIsland, world);

                world.islands.islands.Add(collisionIsland);
            }

            cloneCollision.Restore((CollisionSystemPersistentSAP)world.CollisionSystem);

            world.initialCollisions.Clear();
            world.initialCollisions.AddRange(clonedInitialCollisions);

            world.initialTriggers.Clear();
            world.initialTriggers.AddRange(clonedInitialTriggers);

            RigidBody.instanceCount  = rigidBodyInstanceCount;
            Constraint.instanceCount = constraintInstanceCount;

            for (index = 0, length = contactsToGiveBack.Count; index < length; index++)
            {
                Contact obj = contactsToGiveBack[index];

                Contact.Pool.GiveBack(obj);
            }
            contactsToGiveBack.Clear();

            for (index = 0, length = arbiterToGiveBack.Count; index < length; index++)
            {
                Arbiter obj = arbiterToGiveBack[index];

                Arbiter.Pool.GiveBack(obj);
            }
            arbiterToGiveBack.Clear();

            for (index = 0, length = collisionIslandToGiveBack.Count; index < length; index++)
            {
                CollisionIsland obj = collisionIslandToGiveBack[index];

                IslandManager.Pool.GiveBack(obj);
            }
            collisionIslandToGiveBack.Clear();
        }