示例#1
0
        // Compound shapes are always built from scratch.
        // This shouldn't be to bad since most of the parts will be meshes that had been built previously.
        private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
        {
            // Remove reference to the old shape
            // Don't need to do this as the shape is freed when the new root shape is created below.
            // DereferenceShape(prim.PhysShape, true, shapeCallback);

            BulletShape cShape = new BulletShape(
                BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), BSPhysicsShapeType.SHAPE_COMPOUND);

            // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
            CreateGeomMeshOrHull(prim, shapeCallback);
            BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity);
            if (DDetail)
            {
                DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}",
                          prim.LocalID, cShape, prim.PhysShape);
            }

            prim.PhysShape = cShape;

            return(true);
        }
        // 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;
                            BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, 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);
                            }
                            BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, 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 = LinksetMass;
                LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
            }
            finally
            {
                Rebuilding = false;
            }

            BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr);

            // DEBUG: see of inter-linkset collisions are causing problems for constraint linksets.
            // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
            //                     (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
        }