public abstract void AddChildShapeToCompoundShape(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot);
 public virtual void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape)
 {
 }
        // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
        // Called at taint-time.
        public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable updated)
        {
            // The user moving a child around requires the rebuilding of the linkset compound shape
            // One problem is this happens when a border is crossed -- the simulator implementation
            //    stores the position into the group which causes the move of the object
            //    but it also means all the child positions get updated.
            //    What would cause an unnecessary rebuild so we make sure the linkset is in a
            //    region before bothering to do a rebuild.
            if (!IsRoot(updated) && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
            {
                // If a child of the linkset is updating only the position or rotation, that can be done
                //    without rebuilding the linkset.
                // If a handle for the child can be fetch, we update the child here. If a rebuild was
                //    scheduled by someone else, the rebuild will just replace this setting.

                bool updatedChild = false;
                // Anything other than updating position or orientation usually means a physical update
                //     and that is caused by us updating the object.
                if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
                {
                    // Find the physical instance of the child
                    if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape))
                    {
                        // It is possible that the linkset is still under construction and the child is not yet
                        //    inserted into the compound shape. A rebuild of the linkset in a pre-step action will
                        //    build the whole thing with the new position or rotation.
                        // The index must be checked because Bullet references the child array but does no validity
                        //    checking of the child index passed.
                        int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape);
                        if (updated.LinksetChildIndex < numLinksetChildren)
                        {
                            BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, updated.LinksetChildIndex);
                            if (linksetChildShape.HasPhysicalShape)
                            {
                                // Found the child shape within the compound shape
                                PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, updated.LinksetChildIndex,
                                                                     updated.RawPosition - LinksetRoot.RawPosition,
                                                                     updated.RawOrientation * OMV.Quaternion.Inverse(LinksetRoot.RawOrientation),
                                                                     true);
                                updatedChild = true;
                                DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},pos={2},rot={3}",
                                          updated.LocalID, whichUpdated, updated.RawPosition, updated.RawOrientation);
                            }
                            else    // DEBUG DEBUG
                            {       // DEBUG DEBUG
                                DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}",
                                          updated.LocalID, linksetChildShape);
                            }   // DEBUG DEBUG
                        }
                        else    // DEBUG DEBUG
                        {       // DEBUG DEBUG
                            // the child is not yet in the compound shape. This is non-fatal.
                            DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}",
                                      updated.LocalID, numLinksetChildren, updated.LinksetChildIndex);
                        }   // DEBUG DEBUG
                    }
                    else    // DEBUG DEBUG
                    {       // DEBUG DEBUG
                        DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID);
                    }       // DEBUG DEBUG

                    if (!updatedChild)
                    {
                        // If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info.
                        // Note: there are several ways through this code that will not update the child if
                        //    the linkset is being rebuilt. In this case, scheduling a rebuild is a NOOP since
                        //    there will already be a rebuild scheduled.
                        DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}",
                                  updated.LocalID, whichUpdated);
                        updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed.
                        ScheduleRebuild(updated);
                    }
                }
            }
        }
 public abstract Vector3 CalculateLocalInertia(BulletShape shape, float mass);
 public abstract void SetMargin(BulletShape shape, float val);
 public abstract bool IsSoftBody(BulletShape shape);
 public abstract void SetLocalScaling(BulletShape shape, Vector3 scale);
 public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape);
 public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
Exemple #10
0
 public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
Exemple #11
0
 public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, UInt32 id);
Exemple #12
0
 public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb);
Exemple #13
0
 public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape);
Exemple #14
0
 public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx);
Exemple #15
0
 public abstract bool IsConcave(BulletShape shape);
Exemple #16
0
 public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
Exemple #17
0
 public abstract bool IsCompound(BulletShape shape);
Exemple #18
0
 public abstract void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletShape shape);
Exemple #19
0
 public abstract bool IsInfinite(BulletShape shape);
Exemple #20
0
        // =====================================================================================
        // btCollisionShape entries

        public abstract float GetAngularMotionDisc(BulletShape shape);
Exemple #21
0
 public abstract Vector3 GetLocalScaling(BulletShape shape);
Exemple #22
0
 public abstract float GetContactBreakingThreshold(BulletShape shape, float defaultFactor);
Exemple #23
0
 public abstract int GetShapeType(BulletShape shape);
Exemple #24
0
 public abstract bool IsPolyhedral(BulletShape shape);
Exemple #25
0
 public abstract float GetMargin(BulletShape shape);
Exemple #26
0
 public abstract bool IsConvex(BulletShape shape);
Exemple #27
0
        // Create terrain mesh from a heightmap.
        public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
                             Vector3 minCoords, Vector3 maxCoords)
            : base(physicsScene, regionBase, id)
        {
            int indicesCount;

            int[] indices;
            int   verticesCount;

            float[] vertices;

            m_savedHeightMap = initialMap;

            m_sizeX = (int)(maxCoords.X - minCoords.X);
            m_sizeY = (int)(maxCoords.Y - minCoords.Y);

            bool meshCreationSuccess = false;

            if (BSParam.TerrainMeshMagnification == 1)
            {
                // If a magnification of one, use the old routine that is tried and true.
                meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene,
                                                                           initialMap, m_sizeX, m_sizeY, // input size
                                                                           Vector3.Zero,                 // base for mesh
                                                                           out indicesCount, out indices, out verticesCount, out vertices);
            }
            else
            {
                // Other magnifications use the newer routine
                meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh2(PhysicsScene,
                                                                            initialMap, m_sizeX, m_sizeY, // input size
                                                                            BSParam.TerrainMeshMagnification,
                                                                            physicsScene.TerrainManager.WorldMax,
                                                                            Vector3.Zero, // base for mesh
                                                                            out indicesCount, out indices, out verticesCount, out vertices);
            }
            if (!meshCreationSuccess)
            {
                // DISASTER!!
                PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap,id={1}", BSScene.DetailLogZero, ID);
                PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase);
                // Something is very messed up and a crash is in our future.
                return;
            }

            PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,id={1},indices={2},indSz={3},vertices={4},vertSz={5}",
                                   BSScene.DetailLogZero, ID, indicesCount, indices.Length, verticesCount, vertices.Length);

            m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices);
            if (!m_terrainShape.HasPhysicalShape)
            {
                // DISASTER!!
                PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape,id={1}", BSScene.DetailLogZero, ID);
                PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase);
                // Something is very messed up and a crash is in our future.
                return;
            }

            Vector3    pos = regionBase;
            Quaternion rot = Quaternion.Identity;

            m_terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_terrainShape, ID, pos, rot);
            if (!m_terrainBody.HasPhysicalBody)
            {
                // DISASTER!!
                PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase);
                // Something is very messed up and a crash is in our future.
                return;
            }
            physicsScene.PE.SetShapeCollisionMargin(m_terrainShape, BSParam.TerrainCollisionMargin);

            // Set current terrain attributes
            PhysicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction);
            PhysicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction);
            PhysicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution);
            PhysicsScene.PE.SetContactProcessingThreshold(m_terrainBody, BSParam.TerrainContactProcessingThreshold);
            PhysicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT);

            // Static objects are not very massive.
            PhysicsScene.PE.SetMassProps(m_terrainBody, 0f, Vector3.Zero);

            // Put the new terrain to the world of physical objects
            PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_terrainBody);

            // Redo its bounding box now that it is in the world
            PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_terrainBody);

            m_terrainBody.collisionType = CollisionType.Terrain;
            m_terrainBody.ApplyCollisionMask(PhysicsScene);

            if (BSParam.UseSingleSidedMeshes)
            {
                PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial,id={1}", BSScene.DetailLogZero, id);
                PhysicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
            }

            // Make it so the terrain will not move or be considered for movement.
            PhysicsScene.PE.ForceActivationState(m_terrainBody, ActivationState.DISABLE_SIMULATION);
        }
Exemple #28
0
 public abstract bool IsNonMoving(BulletShape shape);
        private bool disableCOM = true;     // DEBUG DEBUG: disable until we get this debugged
        private void RecomputeLinksetCompound()
        {
            try
            {
                // Suppress rebuilding while rebuilding. (We know rebuilding is on only one thread.)
                Rebuilding = true;

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

                // The center of mass for the linkset is the geometric center of the group.
                // Compute a displacement for each component so it is relative to the center-of-mass.
                // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
                OMV.Vector3 centerOfMassW = LinksetRoot.RawPosition;
                if (!disableCOM)                             // DEBUG DEBUG
                {
                    // Compute a center-of-mass in world coordinates.
                    centerOfMassW = ComputeLinksetCenterOfMass();
                }

                OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);

                // 'centerDisplacement' is the value to subtract from children to give physical offset position
                OMV.Vector3 centerDisplacement = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation;
                LinksetRoot.SetEffectiveCenterOfMassW(centerDisplacement);

                // This causes the physical position of the root prim to be offset to accomodate for the displacements
                LinksetRoot.ForcePosition = LinksetRoot.RawPosition;

                // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM
                PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0 /* childIndex */,
                                                     -centerDisplacement,
                                                     OMV.Quaternion.Identity, // LinksetRoot.RawOrientation,
                                                     false);

                DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
                          LinksetRoot.LocalID, centerOfMassW, LinksetRoot.RawPosition, centerDisplacement);

                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
                int memberIndex = 1;
                ForEachMember(delegate(BSPrimLinkable cPrim)
                {
                    if (IsRoot(cPrim))
                    {
                        cPrim.LinksetChildIndex = 0;
                    }
                    else
                    {
                        cPrim.LinksetChildIndex = memberIndex;

                        if (cPrim.PhysShape.isNativeShape)
                        {
                            // A native shape is turned 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 scale 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.CreateGeomMeshOrHull(cPrim, null);
                            BulletShape newShape = cPrim.PhysShape;
                            cPrim.PhysShape      = saveShape;

                            OMV.Vector3 offsetPos    = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement;
                            OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation;
                            PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, offsetPos, offsetRot);
                            DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}",
                                      LinksetRoot.LocalID, memberIndex, LinksetRoot.PhysShape, newShape, offsetPos, 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);
                            }
                            OMV.Vector3 offsetPos    = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement;
                            OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation;
                            PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot);
                            DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNonNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}",
                                      LinksetRoot.LocalID, memberIndex, LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot);
                        }
                        memberIndex++;
                    }
                    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);

                // Enable the physical position updator to return the position and rotation of the root shape
                PhysicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE);
            }
            finally
            {
                Rebuilding = false;
            }

            // See that the Aabb surrounds the new shape
            PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
        }
Exemple #30
0
 public abstract int GetNumberOfCompoundChildren(BulletShape cShape);