Example #1
0
        // When the linkset is built, the child shape is added to the compound shape relative to the
        //    root shape. The linkset then moves around but this does not move the actual child
        //    prim. The child prim's location must be recomputed based on the location of the root shape.
        private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime)
        {
            BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo;

            if (lci != null)
            {
                if (inTaintTime)
                {
                    OMV.Vector3 oldPos = child.RawPosition;
                    child.ForcePosition    = LinksetRoot.RawPosition + lci.OffsetPos;
                    child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
                    DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
                              child.LocalID, oldPos, lci, child.RawPosition);
                }
                else
                {
                    // TaintedObject is not used here so the raw position is set now and not at taint-time.
                    child.Position    = LinksetRoot.RawPosition + lci.OffsetPos;
                    child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
                }
            }
            else
            {
                // This happens when children have been added to the linkset but the linkset
                //     has not been constructed yet. So like, at taint time, adding children to a linkset
                //     and then changing properties of the children (makePhysical, for instance)
                //     but the post-print action of actually rebuilding the linkset has not yet happened.
                // PhysicsScene.Logger.WarnFormat("{0} Restoring linkset child position failed because of no relative position computed. ID={1}",
                //                                 LogHeader, child.LocalID);
                DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID);
            }
        }
    // Called before the simulation step to make sure the compound based linkset
    //    is all initialized.
    // Constraint linksets are rebuilt every time.
    // Note that this works for rebuilding just the root after a linkset is taken apart.
    // Called at taint time!!
    private void RecomputeLinksetCompound()
    {
        try
        {
            // Suppress rebuilding while rebuilding
            Rebuilding = true;

            // Cause the root shape to be rebuilt as a compound object with just the root in it
            LinksetRoot.ForceBodyShapeRebuild(true);

            DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
                            LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);

            // Add a shape for each of the other children in the linkset
            ForEachMember(delegate(BSPhysObject cPrim)
            {
                if (!IsRoot(cPrim))
                {
                    // Compute the displacement of the child from the root of the linkset.
                    // This info is saved in the child prim so the relationship does not
                    //    change over time and the new child position can be computed
                    //    when the linkset is being disassembled (the linkset may have moved).
                    BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
                    if (lci == null)
                    {
                        // Each child position and rotation is given relative to the root.
                        OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
                        OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
                        OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;

                        // Save relative position for recomputing child's world position after moving linkset.
                        lci = new BSLinksetCompoundInfo(displacementPos, displacementRot);
                        cPrim.LinksetInfo = lci;
                        DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
                    }

                    DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}",
                        LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);

                    if (cPrim.PhysShape.isNativeShape)
                    {
                        // A native shape is turning into a hull collision shape because native
                        //    shapes are not shared so we have to hullify it so it will be tracked
                        //    and freed at the correct time. This also solves the scaling problem
                        //    (native shapes scaled but hull/meshes are assumed to not be).
                        // TODO: decide of the native shape can just be used in the compound shape.
                        //    Use call to CreateGeomNonSpecial().
                        BulletShape saveShape = cPrim.PhysShape;
                        cPrim.PhysShape.Clear();        // Don't let the create free the child's shape
                        // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null);
                        PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
                        BulletShape newShape = cPrim.PhysShape;
                        cPrim.PhysShape = saveShape;
                        PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot);
                    }
                    else
                    {
                        // For the shared shapes (meshes and hulls), just use the shape in the child.
                        // The reference count added here will be decremented when the compound shape
                        //     is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced).
                        if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
                        {
                            PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
                                                LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
                        }
                        PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
                    }
                }
                return false;   // 'false' says to move onto the next child in the list
            });

            // With all of the linkset packed into the root prim, it has the mass of everyone.
            LinksetMass = ComputeLinksetMass();
            LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
        }
        finally
        {
            Rebuilding = false;
        }

        PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
    }
Example #3
0
        // Called before the simulation step to make sure the compound based linkset
        //    is all initialized.
        // Constraint linksets are rebuilt every time.
        // Note that this works for rebuilding just the root after a linkset is taken apart.
        // Called at taint time!!
        private void RecomputeLinksetCompound()
        {
            try
            {
                // Suppress rebuilding while rebuilding
                Rebuilding = true;

                // Cause the root shape to be rebuilt as a compound object with just the root in it
                LinksetRoot.ForceBodyShapeRebuild(true);

                DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
                          LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);

                // Add a shape for each of the other children in the linkset
                ForEachMember(delegate(BSPhysObject cPrim)
                {
                    if (!IsRoot(cPrim))
                    {
                        // Compute the displacement of the child from the root of the linkset.
                        // This info is saved in the child prim so the relationship does not
                        //    change over time and the new child position can be computed
                        //    when the linkset is being disassembled (the linkset may have moved).
                        BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
                        if (lci == null)
                        {
                            // Each child position and rotation is given relative to the root.
                            OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
                            OMV.Vector3 displacementPos       = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
                            OMV.Quaternion displacementRot    = cPrim.RawOrientation * invRootOrientation;

                            // Save relative position for recomputing child's world position after moving linkset.
                            lci = new BSLinksetCompoundInfo(displacementPos, displacementRot);
                            cPrim.LinksetInfo = lci;
                            DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
                        }

                        DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}",
                                  LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);

                        if (cPrim.PhysShape.isNativeShape)
                        {
                            // A native shape is turning into a hull collision shape because native
                            //    shapes are not shared so we have to hullify it so it will be tracked
                            //    and freed at the correct time. This also solves the scaling problem
                            //    (native shapes scaled but hull/meshes are assumed to not be).
                            // TODO: decide of the native shape can just be used in the compound shape.
                            //    Use call to CreateGeomNonSpecial().
                            BulletShape saveShape = cPrim.PhysShape;
                            cPrim.PhysShape.Clear();    // Don't let the create free the child's shape
                            // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null);
                            PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
                            BulletShape newShape = cPrim.PhysShape;
                            cPrim.PhysShape      = saveShape;
                            PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot);
                        }
                        else
                        {
                            // For the shared shapes (meshes and hulls), just use the shape in the child.
                            // The reference count added here will be decremented when the compound shape
                            //     is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced).
                            if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
                            {
                                PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
                                                                LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
                            }
                            PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
                        }
                    }
                    return(false); // 'false' says to move onto the next child in the list
                });

                // With all of the linkset packed into the root prim, it has the mass of everyone.
                LinksetMass = ComputeLinksetMass();
                LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
            }
            finally
            {
                Rebuilding = false;
            }

            PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
        }