public BSActor(BSScene physicsScene, BSPhysObject pObj, string actorName) { m_physicsScene = physicsScene; m_controllingPrim = pObj; ActorName = actorName; Enabled = true; }
// Get a reference to a physical shape. Create if it doesn't exist public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) { BSShape ret = null; if (prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) { // an avatar capsule is close to a native shape (it is not shared) ret = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE); physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret); } // Compound shapes are handled special as they are rebuilt from scratch. // This isn't too great a hardship since most of the child shapes will have already been created. if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) { // Getting a reference to a compound shape gets you the compound shape with the root prim shape added ret = BSShapeCompound.GetReference(prim); physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); } // Avatars have their own unique shape if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_AVATAR) { // Getting a reference to a compound shape gets you the compound shape with the root prim shape added ret = BSShapeAvatar.GetReference(prim); physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,avatarShape,shape={1}", prim.LocalID, ret); } if (ret == null) ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); return ret; }
// Create the geometry information in Bullet for later use. // The objects needs a hull if it's physical otherwise a mesh is enough. // if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls, // shared geometries will be used. If the parameters of the existing shape are the same // as this request, the shape is not rebuilt. // Info in prim.BSShape is updated to the new shape. // Returns 'true' if the geometry was rebuilt. // Called at taint-time! private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) { bool ret = false; bool haveShape = false; if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) { // an avatar capsule is close to a native shape (it is not shared) GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE, shapeCallback); if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; haveShape = true; } // Compound shapes are handled special as they are rebuilt from scratch. // This isn't too great a hardship since most of the child shapes will have already been created. if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) { ret = GetReferenceToCompoundShape(prim, shapeCallback); if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); haveShape = true; } if (!haveShape) { ret = CreateGeomNonSpecial(forceRebuild, prim, shapeCallback); } return ret; }
// Create a body object in Bullet. // Updates prim.BSBody with the information about the new body if one is created. // Returns 'true' if an object was actually created. // Called at taint-time. private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim, BodyDestructionCallback bodyCallback) { bool ret = false; // the mesh, hull or native shape must have already been created in Bullet bool mustRebuild = !prim.PhysBody.HasPhysicalBody; // If there is an existing body, verify it's of an acceptable type. // If not a solid object, body is a GhostObject. Otherwise a RigidBody. if (!mustRebuild) { CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(prim.PhysBody); if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) { // If the collisionObject is not the correct type for solidness, rebuild what's there mustRebuild = true; if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,forceRebuildBecauseChangingBodyType,bodyType={1}", prim.LocalID, bodyType); } } if (mustRebuild || forceRebuild) { // Free any old body DereferenceBody(prim.PhysBody, bodyCallback); BulletBody aBody; if (prim.IsSolid) { aBody = PhysicsScene.PE.CreateBodyFromShape(sim, prim.PhysShape, prim.LocalID, prim.RawPosition, prim.RawOrientation); if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody); } else { aBody = PhysicsScene.PE.CreateGhostFromShape(sim, prim.PhysShape, prim.LocalID, prim.RawPosition, prim.RawOrientation); if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody); } ReferenceBody(aBody); prim.PhysBody = aBody; ret = true; } return ret; }
private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) { BulletShape newShape; // Need to make sure the passed shape information is for the native type. ShapeData nativeShapeData = new ShapeData(); nativeShapeData.Type = shapeType; nativeShapeData.ID = prim.LocalID; nativeShapeData.Scale = prim.Scale; nativeShapeData.Size = prim.Scale; // unneeded, I think. nativeShapeData.MeshKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey; if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) { newShape = PhysicsScene.PE.BuildCapsuleShape(PhysicsScene.World, 1f, 1f, prim.Scale); if (DDetail) DetailLog("{0},BSShapeCollection.BuildPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); } else { // Native shapes are scaled in Bullet so set the scaling to the size newShape = PhysicsScene.PE.BuildNativeShape(PhysicsScene.World, nativeShapeData); } if (!newShape.HasPhysicalShape) { PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", LogHeader, prim.LocalID, shapeType); } newShape.shapeKey = (System.UInt64)shapeKey; newShape.isNativeShape = true; return newShape; }
public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim) { return GetBodyAndShape(forceRebuild, sim, prim, null, null); }
public static BSShape GetReference(BSPhysObject prim) { return new BSShapeNull(); }
// Creates a native shape and assignes it to prim.BSShape. // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape(). private bool GetReferenceToNativeShape(BSPhysObject prim, BSPhysicsShapeType shapeType, FixedShapeKey shapeKey, ShapeDestructionCallback shapeCallback) { // release any previous shape DereferenceShape(prim.PhysShape, shapeCallback); BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", prim.LocalID, newShape, prim.Scale); // native shapes are scaled by Bullet prim.PhysShape = newShape; return true; }
// See that hull shape exists in the physical world and update prim.BSShape. // We could be creating the hull because scale changed or whatever. // Return 'true' if a new hull was built. Otherwise, returning a shared hull instance. private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { BulletShape newShape; float lod; System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); // if the hull hasn't changed, don't rebuild it if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL) return false; if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); // Remove usage of the previous shape. DereferenceShape(prim.PhysShape, shapeCallback); newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); // It might not have been created if we're waiting for an asset. newShape = VerifyMeshCreated(newShape, prim); ReferenceShape(newShape); prim.PhysShape = newShape; return true; // 'true' means a new shape has been added to this prim }
// return 'true' if the prim's shape was changed. public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { bool ret = false; // Note that if it's a native shape, the check for physical/non-physical is not // made. Native shapes work in either case. if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) { // Update prim.BSShape to reference a hull of this shape. ret = GetReferenceToHull(prim, shapeCallback); if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } else { ret = GetReferenceToMesh(prim, shapeCallback); if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } return ret; }
// The simulation step is telling this object about a collision. // Return 'true' if a collision was processed and should be sent up. // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision. // Called at taint time from within the Step() function public virtual bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { bool ret = false; bool p2col = true; // We only need to test p2 for 'jump crouch purposes' if (this.TypeName == "BSCharacter" && collidee is BSPrim) { // Testing if the collision is at the feet of the avatar if ((this.Position.Z - contactPoint.Z) < (this.Size.Z * 0.5f)) p2col = false; } // The following lines make IsColliding(), CollidingGround() and CollidingObj work if (p2col) CollidingStep = PhysicsScene.SimulationStep; TrueCollidingStep = PhysicsScene.SimulationStep; CollisionAccumulation++; // For movement tests, remember if we are colliding with an object that is moving. ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; // If someone has subscribed for collision events log the collision so it will be reported up if (SubscribedEvents()) { CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth, (ActorTypes)PhysicsActorType)); DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}", LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); ret = true; } return ret; }
public override bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { // prims in the same linkset cannot collide with each other BSPrimLinkable convCollidee = collidee as BSPrimLinkable; if (convCollidee != null && (this.Linkset.LinksetID == convCollidee.Linkset.LinksetID)) { return false; } return base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth); }
public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) { // Native shapes are not shared and are always built anew. //return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); return null; }
private BSShapeNative(BSScene physicsScene, BSPhysObject prim, BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) { ShapeData nativeShapeData = new ShapeData(); nativeShapeData.Type = shapeType; nativeShapeData.ID = prim.LocalID; nativeShapeData.Scale = prim.Scale; nativeShapeData.Size = prim.Scale; nativeShapeData.MeshKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey; /* if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) { ptr = PhysicsScene.PE.BuildCapsuleShape(physicsScene.World, 1f, 1f, prim.Scale); physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); } else { ptr = PhysicsScene.PE.BuildNativeShape(physicsScene.World, nativeShapeData); } if (ptr == IntPtr.Zero) { physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", LogHeader, prim.LocalID, shapeType); } type = shapeType; key = (UInt64)shapeKey; */ }
private BulletShape CreatePhysicalMesh(BSPhysObject prim, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { BulletShape newShape = new BulletShape(); MeshDesc meshDesc; if (Meshes.TryGetValue(newMeshKey, out meshDesc)) { // If the mesh has already been built just use it. newShape = meshDesc.shape.Clone(); } else { IMesh meshData = PhysicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, false // say it is not physical so a bounding box is not built ); if (meshData != null) { int[] indices = meshData.getIndexListAsInt(); int realIndicesIndex = indices.Length; float[] verticesAsFloats = meshData.getVertexListAsFloat(); if (BSParam.ShouldRemoveZeroWidthTriangles) { // Remove degenerate triangles. These are triangles with two of the vertices // are the same. This is complicated by the problem that vertices are not // made unique in sculpties so we have to compare the values in the vertex. realIndicesIndex = 0; for (int tri = 0; tri < indices.Length; tri += 3) { // Compute displacements into vertex array for each vertex of the triangle int v1 = indices[tri + 0] * 3; int v2 = indices[tri + 1] * 3; int v3 = indices[tri + 2] * 3; // Check to see if any two of the vertices are the same if (!( ( verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2]) || ( verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2]) || ( verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2]) ) ) { // None of the vertices of the triangles are the same. This is a good triangle; indices[realIndicesIndex + 0] = indices[tri + 0]; indices[realIndicesIndex + 1] = indices[tri + 1]; indices[realIndicesIndex + 2] = indices[tri + 2]; realIndicesIndex += 3; } } } DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}", BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3); if (realIndicesIndex != 0) { newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); } else { PhysicsScene.Logger.DebugFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}", LogHeader, prim.PhysObjectName, prim.RawPosition, PhysicsScene.Scene.RegionInfo.RegionName); } } } newShape.shapeKey = newMeshKey; return newShape; }
// The creation of a mesh or hull can fail if an underlying asset is not available. // There are two cases: 1) the asset is not in the cache and it needs to be fetched; // and 2) the asset cannot be converted (like failed decompression of JPEG2000s). // The first case causes the asset to be fetched. The second case requires // us to not loop forever. // Called after creating a physical mesh or hull. If the physical shape was created, // just return. private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) { // If the shape was successfully created, nothing more to do if (newShape.HasPhysicalShape) return newShape; // VerifyMeshCreated is called after trying to create the mesh. If we think the asset had been // fetched but we end up here again, the meshing of the asset must have failed. // Prevent trying to keep fetching the mesh by declaring failure. if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) { prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; PhysicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}", LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); } else { // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset if (prim.BaseShape.SculptEntry && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting && prim.BaseShape.SculptTexture != OMV.UUID.Zero ) { DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID); // Multiple requestors will know we're waiting for this asset prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; BSPhysObject xprim = prim; Util.FireAndForget(delegate { BSPhysObject yprim = xprim; // probably not necessary, but, just in case. PhysicsScene.Scene.AssetService.Get(yprim.BaseShape.SculptTexture.ToString(), null, delegate(string id, Object sender, AssetBase asset) { bool assetFound = false; string mismatchIDs = String.Empty; // DEBUG DEBUG if (asset != null && yprim.BaseShape.SculptEntry) { if (yprim.BaseShape.SculptTexture == asset.ID) { yprim.BaseShape.SculptData = asset.Data; // This will cause the prim to see that the filler shape is not the right // one and try again to build the object. // No race condition with the normal shape setting since the rebuild is at taint time. yprim.ForceBodyShapeRebuild(false /* inTaintTime */); assetFound = true; } else { mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; } } if (assetFound) yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; else yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); }); }); } else { if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) { PhysicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}", LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); } } } // While we wait for the mesh defining asset to be loaded, stick in a simple box for the object. BulletShape fillinShape = BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); DetailLog("{0},BSShapeCollection.VerifyMeshCreated,boxTempShape", prim.LocalID); return fillinShape; }
// 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 = PhysicsScene.PE.CreateCompoundShape(PhysicsScene.World, false); // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. CreateGeomMeshOrHull(prim, shapeCallback); PhysicsScene.PE.AddChildShapeToCompoundShape(cShape, prim.PhysShape, 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; }
// Create a mesh, hull or native shape. // Return 'true' if the prim's shape was changed. public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) { bool ret = false; bool haveShape = false; bool nativeShapePossible = true; PrimitiveBaseShape pbs = prim.BaseShape; // If the prim attributes are simple, this could be a simple Bullet native shape if (!haveShape && nativeShapePossible && pbs != null && !pbs.SculptEntry && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) || PrimHasNoCuts(pbs)) ) { // Get the scale of any existing shape so we can see if the new shape is same native type and same size. OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; if (prim.PhysShape.HasPhysicalShape) scaleOfExistingShape = PhysicsScene.PE.GetLocalScaling(prim.PhysShape); if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}", prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type); // It doesn't look like Bullet scales native spheres so make sure the scales are all equal if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z) { haveShape = true; if (forceRebuild || prim.Scale != scaleOfExistingShape || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_SPHERE ) { ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE, FixedShapeKey.KEY_SPHERE, shapeCallback); } if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},rebuilt={2},shape={3}", prim.LocalID, forceRebuild, ret, prim.PhysShape); } if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) { haveShape = true; if (forceRebuild || prim.Scale != scaleOfExistingShape || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_BOX ) { ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX, shapeCallback); } if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},rebuilt={2},shape={3}", prim.LocalID, forceRebuild, ret, prim.PhysShape); } } // If a simple shape is not happening, create a mesh and possibly a hull. if (!haveShape && pbs != null) { ret = CreateGeomMeshOrHull(prim, shapeCallback); } return ret; }
// Builds a mesh shape in the physical world and updates prim.BSShape. // Dereferences previous shape in BSShape and adds a reference for this new shape. // Returns 'true' of a mesh was actually built. Otherwise . // Called at taint-time! private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { BulletShape newShape = new BulletShape(); float lod; System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); // if this new shape is the same as last time, don't recreate the mesh if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) return false; if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2},size={3},lod={4}", prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod); // Since we're recreating new, get rid of the reference to the previous shape DereferenceShape(prim.PhysShape, shapeCallback); newShape = CreatePhysicalMesh(prim, newMeshKey, prim.BaseShape, prim.Size, lod); // Take evasive action if the mesh was not constructed. newShape = VerifyMeshCreated(newShape, prim); ReferenceShape(newShape); prim.PhysShape = newShape; return true; // 'true' means a new shape has been added to this prim }
// Called to update/change the body and shape for an object. // First checks the shape and updates that if necessary then makes // sure the body is of the right type. // Return 'true' if either the body or the shape changed. // 'shapeCallback' and 'bodyCallback' are, if non-null, functions called just before // the current shape or body is destroyed. This allows the caller to remove any // higher level dependencies on the shape or body. Mostly used for LinkSets to // remove the physical constraints before the body is destroyed. // Called at taint-time!! public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) { PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); bool ret = false; // This lock could probably be pushed down lower but building shouldn't take long lock (m_collectionActivityLock) { // Do we have the correct geometry for this type of object? // Updates prim.BSShape with information/pointers to shape. // Returns 'true' of BSShape is changed to a new shape. bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback); // If we had to select a new shape geometry for the object, // rebuild the body around it. // Updates prim.BSBody with information/pointers to requested body // Returns 'true' if BSBody was changed. bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, bodyCallback); ret = newGeom || newBody; } DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}", prim.LocalID, forceRebuild, ret, prim.PhysBody, prim.PhysShape); return ret; }
public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) : base(physicsScene, pObj, actorName) { m_velocityMotor = null; m_physicsScene.DetailLog("{0},BSActorAvatarMove,constructor", m_controllingPrim.LocalID); }
public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) { return null; }