Universe.Region.SceneObjectGroup.RebuildPhysicalRepresentation C# (CSharp) Метод

RebuildPhysicalRepresentation() публичный Метод

Rebuild the physical representation of all the prims. This is used after copying the prim so that all of the object is readded to the physics scene.
public RebuildPhysicalRepresentation ( bool keepSelectedStatuses, System.Action actionWhileNoPhysActor ) : void
keepSelectedStatuses bool
actionWhileNoPhysActor System.Action
Результат void
        public void RebuildPhysicalRepresentation(bool keepSelectedStatuses, Action actionWhileNoPhysActor)
        {
            // long lock or array copy?  in this case lets try array
            SceneObjectPart[] parts;
            SceneObjectPart part;
            int i;

            lock (m_partsLock)//Force the root to be deleted last
                parts = m_partsList.OrderBy((sop)=>-sop.LinkNum).ToArray();

            if (RootPart.PhysActor != null)
                RootPart.PhysActor.BlockPhysicalReconstruction = true;

            for (i = 0; i < parts.Length; i++)
            {
                part = parts[i];
                //                PhysicsObject oldActor = part.PhysActor;
                //                PrimitiveBaseShape pbs = part.Shape;
                if (part.PhysActor != null)
                {
                    part.PhysActor.RotationalVelocity = Vector3.Zero;
                    part.m_hasSubscribedToCollisionEvent = false;
                    part.PhysActor.OnRequestTerseUpdate -= part.PhysicsRequestingTerseUpdate;
                    part.PhysActor.OnSignificantMovement -= part.ParentGroup.CheckForSignificantMovement;
                    part.PhysActor.OnOutOfBounds -= part.PhysicsOutOfBounds;

                    //part.PhysActor.delink ();
                    //Remove the old one so that we don't have more than we should,
                    //  as when we copy, it readds it to the PhysicsScene somehow
                    //if (part.IsRoot)//The root removes all children
                    m_scene.PhysicsScene.RemovePrim(part.PhysActor);
                    part.FireOnRemovedPhysics();
                    part.PhysActor = null;
                }
                //Reset any old data that we have
                part.Velocity = Vector3.Zero;
                part.AngularVelocity = Vector3.Zero;
                part.Acceleration = Vector3.Zero;
                part.GenerateRotationalVelocityFromOmega();
            }

            if(actionWhileNoPhysActor != null)
                actionWhileNoPhysActor();

            //Check for meshes and stuff
            CheckSculptAndLoad();

            // check root part setting that make the entire object not having physics rep

            if (RootPart.PhysicsType == (byte)PhysicsShapeType.None ||
                ((RootPart.Flags & PrimFlags.Phantom) == PrimFlags.Phantom && !RootPart.VolumeDetectActive))
            {
                Scene.UniverseEventManager.FireGenericEventHandler("ObjectChangedPhysicalStatus", this);
                if (OnFinishedPhysicalRepresentationBuilding != null)
                    OnFinishedPhysicalRepresentationBuilding();
                OnFinishedPhysicalRepresentationBuilding = null;
                return;
            }

            // create the root part
            bool isPhysical = ((RootPart.Flags & PrimFlags.Physics) != 0);
            bool isPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
            bool physical = isPhysical & !isPhantom;

            RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape(RootPart.UUID, RootPart.LocalId, RootPart.Name, RootPart.PhysicsType,
                RootPart.Shape, RootPart.AbsolutePosition, RootPart.Scale, RootPart.GetWorldRotation(), physical, RootPart.Material,
                RootPart.Friction, RootPart.Restitution, RootPart.GravityMultiplier, RootPart.Density);
            if (RootPart.PhysActor == null)
                return;
            //Don't let it rebuild it until we have all the links done

            RootPart.PhysActor.VolumeDetect = RootPart.VolumeDetectActive;

            //Add collision updates
            //part.PhysActor.OnCollisionUpdate += RootPart.PhysicsCollision;
            RootPart.PhysActor.OnRequestTerseUpdate += RootPart.PhysicsRequestingTerseUpdate;
            RootPart.PhysActor.OnSignificantMovement += RootPart.ParentGroup.CheckForSignificantMovement;
            RootPart.PhysActor.OnOutOfBounds += RootPart.PhysicsOutOfBounds;

            RootPart.FireOnAddedPhysics();
            RootPart.aggregateScriptEvents();
            
            PhysicsActor[] actors = new PhysicsActor[parts.Length - 1];
            for (i = 0; i < parts.Length; i++)
            {
                part = parts[i];
                if (part == RootPart ||
                    part.PhysicsType == (byte)PhysicsShapeType.None ||
                    ((part.Flags & PrimFlags.Phantom) == PrimFlags.Phantom && !part.VolumeDetectActive))
                {
                    continue; // ignore phantom prims
                }

                //Now read the physics actor to the physics scene
                isPhysical = ((part.ParentEntity.RootChild.Flags & PrimFlags.Physics) != 0);
                isPhantom = ((part.ParentEntity.RootChild.Flags & PrimFlags.Phantom) != 0);
                physical = isPhysical & !isPhantom;

                part.PhysActor = m_scene.PhysicsScene.AddPrimShape(part.UUID, part.LocalId, part.Name, RootPart.PhysicsType,
                    part.Shape, part.AbsolutePosition, part.Scale, part.GetWorldRotation(), physical, part.Material,
                    part.Friction, part.Restitution, part.GravityMultiplier, part.Density);
                if (part.PhysActor == null)
                    continue;
                //                    part.PhysActor.BuildingRepresentation = true;
                //                    if(part.IsRoot)
                //Don't let it rebuild it until we have all the links done

                part.PhysActor.VolumeDetect = part.VolumeDetectActive;

                //Add collision updates
                part.PhysActor.OnRequestTerseUpdate += part.PhysicsRequestingTerseUpdate;
                part.PhysActor.OnSignificantMovement += part.ParentGroup.CheckForSignificantMovement;
                part.PhysActor.OnOutOfBounds += part.PhysicsOutOfBounds;

                part.FireOnAddedPhysics();
                part.aggregateScriptEvents();
                actors[i] = part.PhysActor;
                
                if(!m_scene.PhysicsScene.AllowGroupLink)
                    part.PhysActor.Link(RootPart.PhysActor);
            }
            if (m_scene.PhysicsScene.AllowGroupLink)
                RootPart.PhysActor.LinkGroupToThis(actors);

            Scene.UniverseEventManager.FireGenericEventHandler("ObjectChangedPhysicalStatus", this);

            FixVehicleParams(RootPart);

            /*if (physical != RootPart.PhysActor.IsPhysical)
            {
                RootPart.PhysActor.IsPhysical = physical;
                foreach (SceneObjectPart p in parts)
                {
                    if(!p.IsRoot)
                        p.PhysActor.IsPhysical = physical;
                }
            }*/

            //Force deselection here so that it isn't stuck forever
            IsSelected = keepSelectedStatuses && IsSelected;

            if (OnFinishedPhysicalRepresentationBuilding != null)
                OnFinishedPhysicalRepresentationBuilding();
            OnFinishedPhysicalRepresentationBuilding = null;
        }
SceneObjectGroup