protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { PhysicsScene = parentScene; LocalID = localID; PhysObjectName = name; TypeName = typeName; // We don't have any physical representation yet. PhysBody = new BulletBody(localID); PhysShape = new BulletShape(); // A linkset of just me Linkset = BSLinkset.Factory(PhysicsScene, this); LastAssetBuildFailed = false; // Default material type Material = MaterialAttributes.Material.Wood; CollisionCollection = new CollisionEventUpdate(); SubscribedEventsMs = 0; CollidingStep = 0; CollidingGroundStep = 0; }
public abstract int GetNumberOfCompoundChildren(BulletShape cShape);
public abstract void SetLocalScaling(BulletShape shape, Vector3 scale);
public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
public abstract bool IsNativeShape(BulletShape shape);
public abstract bool IsCompound(BulletShape shape);
public abstract Vector3 GetLocalScaling(BulletShape shape);
public virtual void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape) { }
public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape);
public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, UInt32 id);
public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb);
public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape);
public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx);
public abstract void AddChildShapeToCompoundShape(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot);
public abstract Vector3 CalculateLocalInertia(BulletShape shape, float mass);
public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
// ===================================================================================== // btCollisionShape entries public abstract float GetAngularMotionDisc(BulletShape shape);
public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
public abstract int GetNumberOfCompoundChildren(BulletShape cShape);
public abstract void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletShape shape);
public abstract bool IsConvex2d(BulletShape shape);
// ===================================================================================== // btCollisionShape entries public abstract float GetAngularMotionDisc(BulletShape shape);
public abstract bool IsPolyhedral(BulletShape shape);
public abstract float GetContactBreakingThreshold(BulletShape shape, float defaultFactor);
public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx);
public abstract bool IsPolyhedral(BulletShape shape);
public abstract void SetShapeCollisionMargin(BulletShape shape, float margin);
public abstract bool IsConvex(BulletShape shape);
public abstract BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape, HACDParams parms);
public abstract bool IsNonMoving(BulletShape shape);
public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
public abstract bool IsConcave(BulletShape shape);
public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape);
public abstract bool IsCompound(BulletShape shape);
public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, UInt32 id);
public abstract bool IsSoftBody(BulletShape shape);
public abstract float GetContactBreakingThreshold(BulletShape shape, float defaultFactor);
public abstract bool IsInfinite(BulletShape shape);
public abstract float GetMargin(BulletShape shape);
public abstract void SetLocalScaling(BulletShape shape, Vector3 scale);
public abstract int GetShapeType(BulletShape shape);
public abstract Vector3 GetLocalScaling(BulletShape shape);
public abstract bool IsConcave(BulletShape shape);
public abstract Vector3 CalculateLocalInertia(BulletShape shape, float mass);
public abstract bool IsInfinite(BulletShape shape);
public abstract int GetShapeType(BulletShape shape);
public abstract bool IsNonMoving(BulletShape shape);
public abstract void SetMargin(BulletShape shape, float val);
public abstract bool IsSoftBody(BulletShape shape);
public abstract float GetMargin(BulletShape shape);
public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape);
public virtual void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape) { }
public abstract void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletShape shape);
// '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) { if (!LinksetRoot.IsPhysicallyActive) { // No reason to do this physical stuff for static linksets. DetailLog("{0},BSLinksetCompound.UpdateProperties,notPhysical", LinksetRoot.LocalID); return; } // 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) && m_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 && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo)) { // 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 = m_physicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape.physShapeInfo); if (updated.LinksetChildIndex < numLinksetChildren) { BulletShape linksetChildShape = m_physicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape.physShapeInfo, updated.LinksetChildIndex); if (linksetChildShape.HasPhysicalShape) { // Found the child shape within the compound shape m_physicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape.physShapeInfo, updated.LinksetChildIndex, updated.RawPosition - LinksetRoot.RawPosition, updated.RawOrientation * OMV.Quaternion.Inverse(LinksetRoot.RawOrientation), true /* shouldRecalculateLocalAabb */); 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); Refresh(updated); } } } }
public abstract void SetMargin(BulletShape shape, float val);
// 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(m_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(m_physicsScene, initialMap, m_sizeX, m_sizeY, // input size BSParam.TerrainMeshMagnification, physicsScene.TerrainManager.DefaultRegionSize, Vector3.Zero, // base for mesh out indicesCount, out indices, out verticesCount, out vertices); } if (!meshCreationSuccess) { // DISASTER!! m_physicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap,id={1}", BSScene.DetailLogZero, ID); m_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; } m_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 = m_physicsScene.PE.CreateMeshShape(m_physicsScene.World, indicesCount, indices, verticesCount, vertices); if (!m_terrainShape.HasPhysicalShape) { // DISASTER!! m_physicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape,id={1}", BSScene.DetailLogZero, ID); m_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 = m_physicsScene.PE.CreateBodyWithDefaultMotionState(m_terrainShape, ID, pos, rot); if (!m_terrainBody.HasPhysicalBody) { // DISASTER!! m_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 m_physicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction); m_physicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction); m_physicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution); m_physicsScene.PE.SetContactProcessingThreshold(m_terrainBody, BSParam.TerrainContactProcessingThreshold); m_physicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT); // Static objects are not very massive. m_physicsScene.PE.SetMassProps(m_terrainBody, 0f, Vector3.Zero); // Put the new terrain to the world of physical objects m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, m_terrainBody); // Redo its bounding box now that it is in the world m_physicsScene.PE.UpdateSingleAabb(m_physicsScene.World, m_terrainBody); m_terrainBody.collisionType = CollisionType.Terrain; m_terrainBody.ApplyCollisionMask(m_physicsScene); if (BSParam.UseSingleSidedMeshes) { m_physicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial,id={1}", BSScene.DetailLogZero, id); m_physicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK); } // Make it so the terrain will not move or be considered for movement. m_physicsScene.PE.ForceActivationState(m_terrainBody, ActivationState.DISABLE_SIMULATION); }
public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb);
public abstract void SetShapeCollisionMargin(BulletShape shape, float margin);