public override BulletBody CreateBodyWithDefaultMotionState(BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) { IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, pRawOrientation.Z, pRawOrientation.W)); mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); CollisionShape shape = (pShape as BulletShapeXNA).shape; // TODO: Feed Update array into null RigidBody body = new RigidBody(0, new DefaultMotionState(mat, IndexedMatrix.Identity), shape, IndexedVector3.Zero); body.SetWorldTransform(mat); body.SetUserPointer(pLocalID); return new BulletBodyXNA(pLocalID, body); }
public override bool DeleteCollisionShape(BulletWorld pWorld, BulletShape pShape) { //TODO: return false; }
public override bool ReferenceSame(BulletShape other) { BulletShapeXNA otheru = other as BulletShapeXNA; return (otheru != null) && (this.shape == otheru.shape); }
public override Vector3 CalculateLocalInertia(BulletShape pShape, float pphysMass) { CollisionShape shape = (pShape as BulletShapeXNA).shape; IndexedVector3 inertia = IndexedVector3.Zero; shape.CalculateLocalInertia(pphysMass, out inertia); return new Vector3(inertia.X, inertia.Y, inertia.Z); }
//LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot public override void AddChildShapeToCompoundShape(BulletShape pCShape, BulletShape paddShape, Vector3 displacementPos, Quaternion displacementRot) { IndexedMatrix relativeTransform = new IndexedMatrix(); CompoundShape compoundshape = (pCShape as BulletShapeXNA).shape as CompoundShape; CollisionShape addshape = (paddShape as BulletShapeXNA).shape; relativeTransform._origin = new IndexedVector3(displacementPos.X, displacementPos.Y, displacementPos.Z); relativeTransform.SetRotation(new IndexedQuaternion(displacementRot.X, displacementRot.Y, displacementRot.Z, displacementRot.W)); compoundshape.AddChildShape(ref relativeTransform, addshape); }
public override void SetShapeCollisionMargin(BulletShape pShape, float pMargin) { CollisionShape shape = (pShape as BulletShapeXNA).shape; shape.SetMargin(pMargin); }
public override int GetNumberOfCompoundChildren(BulletShape pCompoundShape) { CompoundShape compoundshape = (pCompoundShape as BulletShapeXNA).shape as CompoundShape; return compoundshape.GetNumChildShapes(); }
public override BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape pCShape, int pii) { CompoundShape compoundshape = (pCShape as BulletShapeXNA).shape as CompoundShape; CollisionShape ret = null; ret = compoundshape.GetChildShape(pii); compoundshape.RemoveChildShapeByIndex(pii); return new BulletShapeXNA(ret, BSShapeTypeFromBroadPhaseNativeType(ret.GetShapeType())); }
public override Vector3 GetLocalScaling(BulletShape pShape) { CollisionShape shape = (pShape as BulletShapeXNA).shape; IndexedVector3 scale = shape.GetLocalScaling(); return new Vector3(scale.X, scale.Y, scale.Z); }
public override float GetMargin(BulletShape pShape) { CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.GetMargin(); }
public override float GetContactBreakingThreshold(BulletShape pShape, float defaultFactor) { CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.GetContactBreakingThreshold(defaultFactor); }
public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { if (cShape == null) return null; CompoundShape compoundShape = (cShape as BulletShapeXNA).shape as CompoundShape; CollisionShape shape = compoundShape.GetChildShape(indx); BulletShape retShape = new BulletShapeXNA(shape, BSShapeTypeFromBroadPhaseNativeType(shape.GetShapeType())); return retShape; }
private void RecomputeLinksetCompound() { try { // Suppress rebuilding while rebuilding. (We know rebuilding is on only one thread.) Rebuilding = true; if (LinksetRoot.IsPhysical) { // Cause the root shape to be rebuilt as a compound object with just the root in it LinksetRoot.ForceBodyShapeRebuild(true /* inTaintTime */); // 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) { // 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; //Set the COM in bullet PhysicsScene.PE.SetCenterOfMassByPosRot(LinksetRoot.PhysBody, centerDisplacement, OMV.Quaternion.Identity); // 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 //Not necessary, as the COM is set in bullet now, and this was always Vector3.Zero beforehand, which is of no use //PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0 /* childIndex */, // -centerDisplacement, // OMV.Quaternion.Identity, // LinksetRoot.RawOrientation, // false /* shouldRecalculateLocalAabb (is done later after linkset built) */); LinksetRoot.LinksetChildIndex = 0; 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; lock (m_linksetActivityLock) { foreach (BSPrimLinkable cPrim in m_children) { cPrim.LinksetChildIndex = memberIndex; if (cPrim.PhysBody.AddrString == "unknown") { if (!PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, cPrim)) { } } 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; 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; 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); } PhysicsScene.PE.AddToCollisionFlags(cPrim.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); PhysicsScene.PE.ForceActivationState(cPrim.PhysBody, ActivationState.DISABLE_SIMULATION); // We don't want collisions from the old linkset children. PhysicsScene.PE.RemoveFromCollisionFlags(cPrim.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); cPrim.PhysBody.collisionType = CollisionType.LinksetChild; memberIndex++; } } // 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); // See that the Aabb surrounds the new shape PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape); } else { // Cause the root shape to be rebuilt as a compound object with just the root in it LinksetRoot.ForceBodyShapeRebuild(true /* inTaintTime */); //Update the AABB so that things will collide properly PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, LinksetRoot.PhysBody); // 20131224 not used OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); // This causes the physical position of the root prim to be offset to accomodate for the displacements LinksetRoot.ForcePosition = LinksetRoot.RawPosition; int memberIndex = 0; LinksetRoot.LinksetChildIndex = memberIndex++; lock (m_linksetActivityLock) { foreach (BSPrimLinkable cPrim in m_children) { // 20131224 not used OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; // 20131224 not used OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; // Build a simple shape for this child prim (given that we aren't allowing it to be dynamic cPrim.ForceBodyShapeRebuild(true); // This causes the physical position of the root prim to be offset to accomodate for the displacements cPrim.ForcePosition = cPrim.RawPosition; cPrim.LinksetChildIndex = memberIndex++; //Update AABB for collisions PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, cPrim.PhysBody); } } } } finally { Rebuilding = false; } }
// 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,meshid,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); }
public override int GetShapeType(BulletShape pShape) { CollisionShape shape = (pShape as BulletShapeXNA).shape; return (int)shape.GetShapeType(); }
// '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.IsPhysical) { 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) && 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 /* 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); updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed. ScheduleRebuild(updated); } } } }
public override bool IsConvex2d(BulletShape pShape) { CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsConvex2d(); }
public override void SetCollisionShape(BulletWorld pWorld, BulletBody pCollisionObject, BulletShape pShape) { // 20131224 not used DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; if (pShape == null) { collisionObject.SetCollisionShape(new EmptyShape()); } else { CollisionShape shape = (pShape as BulletShapeXNA).shape; collisionObject.SetCollisionShape(shape); } }
public override bool IsInfinite(BulletShape pShape) { CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsInfinite(); }
public override void SetLocalScaling(BulletShape pShape, Vector3 pScale) { CollisionShape shape = (pShape as BulletShapeXNA).shape; IndexedVector3 vec = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); shape.SetLocalScaling(ref vec); }
public override bool IsNativeShape(BulletShape pShape) { CollisionShape shape = (pShape as BulletShapeXNA).shape; bool ret; switch (shape.GetShapeType()) { case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE: case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE: case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE: case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: ret = true; break; default: ret = false; break; } return ret; }
public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ }
public override bool IsNonMoving(BulletShape pShape) { CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsNonMoving(); }
public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape, HACDParams parms) { /* TODO */ return null; }
public override bool IsPolyhedral(BulletShape pShape) { CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsPolyhedral(); }
//(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); public override BulletBody CreateBodyFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) { // 20131224 not used CollisionWorld world = (pWorld as BulletWorldXNA).world; IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, pRawOrientation.Z, pRawOrientation.W)); mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); CollisionShape shape = (pShape as BulletShapeXNA).shape; //UpdateSingleAabb(world, shape); // TODO: Feed Update array into null SimMotionState motionState = new SimMotionState(this, pLocalID, mat, null); RigidBody body = new RigidBody(0, motionState, shape, IndexedVector3.Zero); // 20131224 not used RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, motionState, shape, IndexedVector3.Zero) // 20131224 not used { // 20131224 not used m_mass = 0 // 20131224 not used }; /* m_mass = mass; m_motionState =motionState; m_collisionShape = collisionShape; m_localInertia = localInertia; m_linearDamping = 0f; m_angularDamping = 0f; m_friction = 0.5f; m_restitution = 0f; m_linearSleepingThreshold = 0.8f; m_angularSleepingThreshold = 1f; m_additionalDamping = false; m_additionalDampingFactor = 0.005f; m_additionalLinearDampingThresholdSqr = 0.01f; m_additionalAngularDampingThresholdSqr = 0.01f; m_additionalAngularDampingFactor = 0.01f; m_startWorldTransform = IndexedMatrix.Identity; */ body.SetUserPointer(pLocalID); return new BulletBodyXNA(pLocalID, body); }
public override bool IsSoftBody(BulletShape pShape) { CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsSoftBody(); }
//sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation public override BulletBody CreateGhostFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) { // 20131224 not used DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; IndexedMatrix bodyTransform = new IndexedMatrix(); bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, pRawOrientation.Z, pRawOrientation.W)); GhostObject gObj = new PairCachingGhostObject(); gObj.SetWorldTransform(bodyTransform); CollisionShape shape = (pShape as BulletShapeXNA).shape; gObj.SetCollisionShape(shape); gObj.SetUserPointer(pLocalID); if (specialCollisionObjects.ContainsKey(pLocalID)) specialCollisionObjects[pLocalID] = gObj; else specialCollisionObjects.Add(pLocalID, gObj); // TODO: Add to Special CollisionObjects! return new BulletBodyXNA(pLocalID, gObj); }
public override void RecalculateCompoundShapeLocalAabb(BulletShape pCompoundShape) { CompoundShape shape = (pCompoundShape as BulletShapeXNA).shape as CompoundShape; shape.RecalculateLocalAabb(); }
public override BulletShape DuplicateCollisionShape(BulletWorld pWorld, BulletShape pShape, uint id) { CollisionShape shape1 = (pShape as BulletShapeXNA).shape; // TODO: Turn this from a reference copy to a Value Copy. BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSShapeTypeFromBroadPhaseNativeType(shape1.GetShapeType())); return shape2; }
public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ }
protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { PhysicsScene = parentScene; LocalID = localID; PhysObjectName = name; Name = name; // PhysicsActor also has the name of the object. Someday consolidate. TypeName = typeName; // The collection of things that push me around PhysicalActors = new BSActorCollection(PhysicsScene); // Initialize variables kept in base. GravityMultiplier = 1.0f; Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); //HoverActive = false; // We don't have any physical representation yet. PhysBody = new BulletBody(localID); PhysShape = new BulletShape(); PrimAssetState = PrimAssetCondition.Unknown; // Default material type. Also sets Friction, Restitution and Density. SetMaterial((int)MaterialAttributes.Material.Wood); CollisionCollection = new CollisionEventUpdate(); CollisionsLastTick = CollisionCollection; SubscribedEventsMs = 0; CollidingStep = 0; TrueCollidingStep = 0; CollisionAccumulation = 0; ColliderIsMoving = false; CollisionScore = 0; // All axis free. LockedAxis = LockedAxisFree; }
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 /* inTaintTime */); // 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 /* shouldRecalculateLocalAabb (is done later after linkset built) */); 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); }