// Create the correct type of linkset for this child public static BSLinkset Factory(BSScene physScene, BSPrimLinkable parent) { BSLinkset ret = null; switch (parent.LinksetType) { case LinksetImplementation.Constraint: ret = new BSLinksetConstraints(physScene, parent); break; case LinksetImplementation.Compound: ret = new BSLinksetCompound(physScene, parent); break; case LinksetImplementation.Manual: // ret = new BSLinksetManual(physScene, parent); break; default: ret = new BSLinksetCompound(physScene, parent); break; } if (ret == null) { physScene.Logger.ErrorFormat( "[Bulletsim Linkset] Factory could not create linkset. Parent name={1}, ID={2}", parent.Name, parent.LocalID); } return ret; }
// Create the correct type of linkset for this child public static BSLinkset Factory(BSScene physScene, BSPrimLinkable parent) { BSLinkset ret = null; switch (parent.LinksetType) { case LinksetImplementation.Constraint: ret = new BSLinksetConstraints(physScene, parent); break; case LinksetImplementation.Compound: ret = new BSLinksetCompound(physScene, parent); break; case LinksetImplementation.Manual: // ret = new BSLinksetManual(physScene, parent); break; default: ret = new BSLinksetCompound(physScene, parent); break; } if (ret == null) { physScene.Logger.ErrorFormat( "[BULLETSIM LINKSET] Factory could not create linkset. Parent name={1}, ID={2}", parent.Name, parent.LocalID); } return(ret); }
public BSActor(BSScene physicsScene, BSPhysObject pObj, string actorName) { m_physicsScene = physicsScene; m_controllingPrim = pObj; ActorName = actorName; Enabled = true; }
public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) : base(physicsScene, pObj, actorName) { m_velocityMotor = null; m_walkingUpStairs = 0; m_physicsScene.DetailLog("{0},BSActorAvatarMove,constructor", m_controllingPrim.LocalID); }
public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) : base(physicsScene, pObj, actorName) { m_velocityMotor = null; m_walkingUpStairs = 0; m_physicsScene.DetailLog("{0},BSActorAvatarMove,constructor", m_controllingPrim.LocalID); }
public BSActor(BSScene physicsScene, BSPhysObject pObj, string actorName) { m_physicsScene = physicsScene; m_controllingPrim = pObj; ActorName = actorName; Enabled = true; }
public PhysicsScene GetScene() { if (_mScene == null) { _mScene = new BSScene(); } return(_mScene); }
public BSTerrainManager(BSScene physicsScene) { PhysicsScene = physicsScene; // Assume one region of default size m_worldMax = new Vector3(physicsScene.Scene.RegionInfo.RegionSizeX, physicsScene.Scene.RegionInfo.RegionSizeY, physicsScene.Scene.RegionInfo.RegionSizeZ); }
// Apply the specificed collision mask into the physical world public virtual bool ApplyCollisionMask(BSScene physicsScene) { // Should assert the body has been added to the physical world. // (The collision masks are stored in the collision proxy cache which only exists for // a collision body that is in the world.) return(physicsScene.PE.SetCollisionGroupMask(this, BulletSimData.CollisionTypeMasks[collisionType].group, BulletSimData.CollisionTypeMasks[collisionType].mask)); }
public BSShapeCollection(BSScene physScene) { PhysicsScene = physScene; // Set the next to 'true' for very detailed shape update detailed logging (detailed details?) // While detailed debugging is still active, this is better than commenting out all the // DetailLog statements. When debugging slows down, this and the protected logging // statements can be commented/removed. DDetail = true; }
// Apply the specificed collision mask into the physical world public virtual bool ApplyCollisionMask(BSScene physicsScene) { // Should assert the body has been added to the physical world. // (The collision masks are stored in the collision proxy cache which only exists for // a collision body that is in the world.) return physicsScene.PE.SetCollisionGroupMask(this, BulletSimData.CollisionTypeMasks[collisionType].group, BulletSimData.CollisionTypeMasks[collisionType].mask); }
public BSShapeCollection(BSScene physScene) { PhysicsScene = physScene; // Set the next to 'true' for very detailed shape update detailed logging (detailed details?) // While detailed debugging is still active, this is better than commenting out all the // DetailLog statements. When debugging slows down, this and the protected logging // statements can be commented/removed. DDetail = true; }
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) : base(parent_scene, localID, avName, "BSCharacter") { _physicsActorType = (int)ActorTypes.Agent; _isPhysical = true; _position = pos; _flying = isFlying; _orientation = OMV.Quaternion.Identity; RawVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); Friction = BSParam.AvatarStandingFriction; Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. _size = size; if (_size.X == 0f) { _size.X = BSParam.AvatarCapsuleDepth; } if (_size.Y == 0f) { _size.Y = BSParam.AvatarCapsuleWidth; } // The dimensions of the physical capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. Scale = ComputeAvatarScale(_size); // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); // The avatar's movement is controlled by this motor that speeds up and slows down // the avatar seeking to reach the motor's target speed. // This motor runs as a prestep action for the avatar so it will keep the avatar // standing as well as moving. Destruction of the avatar will destroy the pre-step action. m_moveActor = new BSActorAvatarMove(PhysicsScene, this, AvatarMoveActorName); PhysicalActors.Add(AvatarMoveActorName, m_moveActor); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, Density, _avatarVolume, RawMass); // do actual creation in taint time PhysicsScene.TaintedObject(LocalID, "BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); // New body and shape into PhysBody and PhysShape PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); SetPhysicalProperties(); SubscribeEvents(1000); }); return; }
public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical, int material, float friction, float restitution, float gravityMultiplier, float density) : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) { // Default linkset implementation for this prim LinksetType = (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation; Linkset = BSLinkset.Factory(PhysicsScene, this); if (Linkset != null) Linkset.Refresh(this); }
public BSAPIUnman(string paramName, BSScene physScene) { PhysicsScene = physScene; // Do something fancy with the paramName to get the right DLL implementation // like "Bullet-2.80-OpenCL-Intel" loading the version for Intel based OpenCL implementation, etc. if (Util.IsWindows()) Util.LoadArchSpecificWindowsDll("BulletSim.dll"); // If not Windows, loading is performed by the // Mono loader as specified in // "bin/Physics/Universe.Physics.BulletSPlugin.dll.config". BulletEngineVersion = "2.82"; }
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) : base(parent_scene, localID, avName, "BSCharacter") { _physicsActorType = (int)ActorTypes.Agent; _isPhysical = true; _position = pos; _flying = isFlying; _orientation = OMV.Quaternion.Identity; RawVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); Friction = BSParam.AvatarStandingFriction; Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. _size = size; if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; // The dimensions of the physical capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. Scale = ComputeAvatarScale(_size); // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); // The avatar's movement is controlled by this motor that speeds up and slows down // the avatar seeking to reach the motor's target speed. // This motor runs as a prestep action for the avatar so it will keep the avatar // standing as well as moving. Destruction of the avatar will destroy the pre-step action. m_moveActor = new BSActorAvatarMove(PhysicsScene, this, AvatarMoveActorName); PhysicalActors.Add(AvatarMoveActorName, m_moveActor); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, Density, _avatarVolume, RawMass); // do actual creation in taint time PhysicsScene.TaintedObject(LocalID, "BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); // New body and shape into PhysBody and PhysShape PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); SetPhysicalProperties(); SubscribeEvents(1000); }); return; }
// This minCoords and maxCoords passed in give the size of the terrain (min and max Z // are the high and low points of the heightmap). public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, Vector3 minCoords, Vector3 maxCoords) : base(physicsScene, regionBase, id) { m_mapInfo = new BulletHMapInfo(id, initialMap, maxCoords.X - minCoords.X, maxCoords.Y - minCoords.Y); m_mapInfo.minCoords = minCoords; m_mapInfo.maxCoords = maxCoords; m_mapInfo.minZ = minCoords.Z; m_mapInfo.maxZ = maxCoords.Z; m_mapInfo.terrainRegionBase = TerrainBase; // Don't have to free any previous since we just got here. BuildHeightmapTerrain(); }
public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical, int material, float friction, float restitution, float gravityMultiplier, float density) : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) { // Default linkset implementation for this prim LinksetType = (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation; Linkset = BSLinkset.Factory(PhysicsScene, this); if (Linkset != null) { Linkset.Refresh(this); } }
// This minCoords and maxCoords passed in give the size of the terrain (min and max Z // are the high and low points of the heightmap). public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, Vector3 minCoords, Vector3 maxCoords) : base(physicsScene, regionBase, id) { m_mapInfo = new BulletHMapInfo(id, initialMap, maxCoords.X - minCoords.X, maxCoords.Y - minCoords.Y); m_mapInfo.minCoords = minCoords; m_mapInfo.maxCoords = maxCoords; m_mapInfo.minZ = minCoords.Z; m_mapInfo.maxZ = maxCoords.Z; m_mapInfo.terrainRegionBase = TerrainBase; // Don't have to free any previous since we just got here. BuildHeightmapTerrain(); }
protected BSLinkset(BSScene scene, BSPrimLinkable parent) { // A simple linkset of one (no children) LinksetID = m_nextLinksetID++; // We create LOTS of linksets. if (m_nextLinksetID <= 0) m_nextLinksetID = 1; PhysicsScene = scene; LinksetRoot = parent; //m_children = new HashSet<BSPrimLinkable>(); m_children = new Dictionary<BSPrimLinkable, BSLinkInfo>(); LinksetMass = parent.RawMass; Rebuilding = false; RebuildScheduled = false; parent.ClearDisplacement(); }
protected BSLinkset(BSScene scene, BSPrimLinkable parent) { // A simple linkset of one (no children) LinksetID = m_nextLinksetID++; // We create LOTS of linksets. if (m_nextLinksetID <= 0) { m_nextLinksetID = 1; } PhysicsScene = scene; LinksetRoot = parent; //m_children = new HashSet<BSPrimLinkable>(); m_children = new Dictionary <BSPrimLinkable, BSLinkInfo>(); LinksetMass = parent.RawMass; Rebuilding = false; RebuildScheduled = false; parent.ClearDisplacement(); }
// Constructor to build a default, flat heightmap terrain. public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) : base(physicsScene, regionBase, id) { Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; float[] initialMap = new float[totalHeights]; for (int ii = 0; ii < totalHeights; ii++) { initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; } m_mapInfo = new BulletHMapInfo(id, initialMap, regionSize.X, regionSize.Y); m_mapInfo.minCoords = minTerrainCoords; m_mapInfo.maxCoords = maxTerrainCoords; m_mapInfo.terrainRegionBase = TerrainBase; // Don't have to free any previous since we just got here. BuildHeightmapTerrain(); }
// Constructor to build a default, flat heightmap terrain. public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) : base(physicsScene, regionBase, id) { Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; float[] initialMap = new float[totalHeights]; for (int ii = 0; ii < totalHeights; ii++) { initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; } m_mapInfo = new BulletHMapInfo(id, initialMap, regionSize.X, regionSize.Y); m_mapInfo.minCoords = minTerrainCoords; m_mapInfo.maxCoords = maxTerrainCoords; m_mapInfo.terrainRegionBase = TerrainBase; // Don't have to free any previous since we just got here. BuildHeightmapTerrain(); }
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; // Oddity if object is destroyed and recreated very quickly it could still have the old body. if (!PhysBody.HasPhysicalBody) { PhysBody = new BulletBody(localID); } // 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); 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. LockedLinearAxis = LockedAxisFree; LockedAngularAxis = LockedAxisFree; }
public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) : base(parent_scene, localID, primName, "BSPrim") { // MainConsole.Instance.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); _physicsActorType = (int)ActorTypes.Prim; _position = pos; _size = size; Scale = size; // prims are the size the user wants them to be (different for BSCharactes). _orientation = rotation; _buoyancy = 0f; RawVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; BaseShape = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; // Add a dynamic vehicle to our set of actors that can move this prim. VehicleActor = new BSDynamics(PhysicsScene, this, VehicleActorName); PhysicalActors.Add(VehicleActorName, VehicleActor); //PhysicalActors.Add(VehicleActorName, new BSDynamics(PhysicsScene, this, VehicleActorName)); _mass = CalculateMass(); // DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time PhysicsScene.TaintedObject(LocalID, "BSPrim.create", delegate() { // Make sure the object is being created with some sanity. ExtremeSanityCheck(true /* inTaintTime */); CreateGeomAndObject(true); CurrentCollisionFlags = PhysicsScene.PE.GetCollisionFlags(PhysBody); IsInitialized = true; }); }
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; // Oddity if object is destroyed and recreated very quickly it could still have the old body. if (!PhysBody.HasPhysicalBody) PhysBody = new BulletBody(localID); // 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); 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. LockedLinearAxis = LockedAxisFree; LockedAngularAxis = LockedAxisFree; }
public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim) { BSShape ret; // If the underlying shape is native, the actual shape has not been build (waiting for asset) // and we must create a copy of the native shape since they are never shared. if (physShapeInfo.HasPhysicalShape && physShapeInfo.isNativeShape) { // TODO: decide when the native shapes should be freed. Check in Dereference? ret = BSShapeNative.GetReference(pPhysicsScene, pPrim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); } else { // Another reference to this shape is just counted. IncrementReference(); ret = this; } return ret; }
#pragma warning restore 414 public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) : base(scene, parent) { LinksetImpl = LinksetImplementation.Compound; }
public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) { float lod; UInt64 newHullKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); BSShapeHull retHull; bool foundHull = false; lock (Hulls) foundHull = Hulls.TryGetValue (newHullKey, out retHull); if (foundHull) { // The mesh has already been created. Return a new reference to same. retHull.IncrementReference(); } else { retHull = new BSShapeHull(new BulletShape()); // An instance of this mesh has not been created. Build and remember same. BulletShape newShape = retHull.CreatePhysicalHull(physicsScene, prim, newHullKey, prim.BaseShape, prim.Size, lod); // Check to see if hull was created (might require an asset). newShape = VerifyMeshCreated(physicsScene, newShape, prim); if (!newShape.isNativeShape || prim.AssetFailed()) { // If a mesh was what was created, remember the built shape for later sharing. lock(Hulls) Hulls.Add(newHullKey, retHull); } retHull.physShapeInfo = newShape; } physicsScene.DetailLog("{0},BSShapeHull,getReference,hull={1},size={2},lod={3}", prim.LocalID, retHull, prim.Size, lod); return retHull; }
public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id) { PhysicsScene = physicsScene; TerrainBase = regionBase; ID = id; }
public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) { LinksetImpl = LinksetImplementation.Constraint; }
public static BSShape GetReference(BSScene physicsScene) { // Base compound shapes are not shared so this returns a raw shape. // A built compound shape can be reused in linksets. BSShapeCompound ret = new BSShapeCompound(CreatePhysicalCompoundShape(physicsScene)); CompoundShapes.Add(ret.AddrString, ret); return ret; }
public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id) { PhysicsScene = physicsScene; TerrainBase = regionBase; ID = id; }
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(CreatePhysicalNativeShape(physicsScene, prim, shapeType, shapeKey)); }
public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim) { // Native shapes are not shared so we return a new shape. BSShape ret = null; lock (physShapeInfo) { ret = new BSShapeNative(CreatePhysicalNativeShape(pPhysicsScene, pPrim, physShapeInfo.shapeType, (FixedShapeKey) physShapeInfo.shapeKey)); } return ret; }
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) : base(physicsScene, regionBase, id) { }
// Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). // Return 'true' if successfully created. public static bool ConvertHeightmapToMesh(BSScene physicsScene, float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap Vector3 extentBase, // base to be added to all vertices out int indicesCountO, out int[] indicesO, out int verticesCountO, out float[] verticesO) { bool ret = false; int indicesCount = 0; int verticesCount = 0; int[] indices = new int[0]; float[] vertices = new float[0]; // Simple mesh creation which assumes magnification == 1. // TODO: do a more general solution that scales, adds new vertices and smoothes the result. // Create an array of vertices that is sizeX+1 by sizeY+1 (note the loop // from zero to <= sizeX). The triangle indices are then generated as two triangles // per heightmap point. There are sizeX by sizeY of these squares. The extra row and // column of vertices are used to complete the triangles of the last row and column // of the heightmap. try { // One vertice per heightmap value plus the vertices off the side and bottom edge. int totalVertices = (sizeX + 1) * (sizeY + 1); vertices = new float[totalVertices * 3]; int totalIndices = sizeX * sizeY * 6; indices = new int[totalIndices]; if (physicsScene != null) { physicsScene.DetailLog( "{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3}", BSScene.DetailLogZero, totalVertices, totalIndices, extentBase); } float minHeight = float.MaxValue; // Note that sizeX+1 vertices are created since there is land between this and the next region. for (int yy = 0; yy <= sizeY; yy++) { for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we go around sizeX + 1 times { int offset = yy * sizeX + xx; // Extend the height with the height from the last row or column if (yy == sizeY) { offset -= sizeX; } if (xx == sizeX) { offset -= 1; } float height = heightMap[offset]; minHeight = Math.Min(minHeight, height); vertices[verticesCount + 0] = (float)xx + extentBase.X; vertices[verticesCount + 1] = (float)yy + extentBase.Y; vertices[verticesCount + 2] = height + extentBase.Z; verticesCount += 3; } } verticesCount = verticesCount / 3; for (int yy = 0; yy < sizeY; yy++) { for (int xx = 0; xx < sizeX; xx++) { int offset = yy * (sizeX + 1) + xx; // Each vertices is presumed to be the upper left corner of a box of two triangles indices[indicesCount + 0] = offset; indices[indicesCount + 1] = offset + 1; indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column indices[indicesCount + 3] = offset + 1; indices[indicesCount + 4] = offset + sizeX + 2; indices[indicesCount + 5] = offset + sizeX + 1; indicesCount += 6; } } ret = true; } catch (Exception e) { if (physicsScene != null) { physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", LogHeader, physicsScene.RegionName, extentBase, e); } } indicesCountO = indicesCount; indicesO = indices; verticesCountO = verticesCount; verticesO = vertices; return(ret); }
public BSActorCollection(BSScene physicsScene) { m_physicsScene = physicsScene; m_actors = new Dictionary <string, BSActor>(); }
public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, Vector3 pos, Vector3 size, Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) { ClearDisplacement(); }
// Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). // Version that handles magnification. // Return 'true' if successfully created. public static bool ConvertHeightmapToMesh2(BSScene physicsScene, float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap int magnification, // number of vertices per heighmap step Vector3 extent, // dimensions of the output mesh Vector3 extentBase, // base to be added to all vertices out int indicesCountO, out int[] indicesO, out int verticesCountO, out float[] verticesO) { bool ret = false; int indicesCount = 0; int verticesCount = 0; int[] indices = new int[0]; float[] vertices = new float[0]; HeightMapGetter hmap = new HeightMapGetter(heightMap, sizeX, sizeY); // The vertices dimension of the output mesh int meshX = sizeX * magnification; int meshY = sizeY * magnification; // The output size of one mesh step float meshXStep = extent.X / meshX; float meshYStep = extent.Y / meshY; // Create an array of vertices that is meshX+1 by meshY+1 (note the loop // from zero to <= meshX). The triangle indices are then generated as two triangles // per heightmap point. There are meshX by meshY of these squares. The extra row and // column of vertices are used to complete the triangles of the last row and column // of the heightmap. try { // Vertices for the output heightmap plus one on the side and bottom to complete triangles int totalVertices = (meshX + 1) * (meshY + 1); vertices = new float[totalVertices * 3]; int totalIndices = meshX * meshY * 6; indices = new int[totalIndices]; if (physicsScene != null) { physicsScene.DetailLog( "{0},BSTerrainMesh.ConvertHeightMapToMesh2,inSize={1},outSize={2},totVert={3},totInd={4},extentBase={5}", BSScene.DetailLogZero, new Vector2(sizeX, sizeY), new Vector2(meshX, meshY), totalVertices, totalIndices, extentBase); } float minHeight = float.MaxValue; // Note that sizeX+1 vertices are created since there is land between this and the next region. // Loop through the output vertices and compute the mediun height in between the input vertices for (int yy = 0; yy <= meshY; yy++) { for (int xx = 0; xx <= meshX; xx++) // Hint: the "<=" means we go around sizeX + 1 times { float offsetY = (float)yy * (float)sizeY / (float)meshY; // The Y that is closest to the mesh point int stepY = (int)offsetY; float fractionalY = offsetY - (float)stepY; float offsetX = (float)xx * (float)sizeX / (float)meshX; // The X that is closest to the mesh point int stepX = (int)offsetX; float fractionalX = offsetX - (float)stepX; // physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh2,xx={1},yy={2},offX={3},stepX={4},fractX={5},offY={6},stepY={7},fractY={8}", // BSScene.DetailLogZero, xx, yy, offsetX, stepX, fractionalX, offsetY, stepY, fractionalY); // get the four corners of the heightmap square the mesh point is in float heightUL = hmap.GetHeight(stepX, stepY); float heightUR = hmap.GetHeight(stepX + 1, stepY); float heightLL = hmap.GetHeight(stepX, stepY + 1); float heightLR = hmap.GetHeight(stepX + 1, stepY + 1); // bilinear interplolation float height = heightUL * (1 - fractionalX) * (1 - fractionalY) + heightUR * fractionalX * (1 - fractionalY) + heightLL * (1 - fractionalX) * fractionalY + heightLR * fractionalX * fractionalY; // physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh2,heightUL={1},heightUR={2},heightLL={3},heightLR={4},heightMap={5}", // BSScene.DetailLogZero, heightUL, heightUR, heightLL, heightLR, height); minHeight = Math.Min(minHeight, height); vertices[verticesCount + 0] = (float)xx * meshXStep + extentBase.X; vertices[verticesCount + 1] = (float)yy * meshYStep + extentBase.Y; vertices[verticesCount + 2] = height + extentBase.Z; verticesCount += 3; } } // The number of vertices generated verticesCount /= 3; // Loop through all the heightmap squares and create indices for the two triangles for that square for (int yy = 0; yy < meshY; yy++) { for (int xx = 0; xx < meshX; xx++) { int offset = yy * (meshX + 1) + xx; // Each vertices is presumed to be the upper left corner of a box of two triangles indices[indicesCount + 0] = offset; indices[indicesCount + 1] = offset + 1; indices[indicesCount + 2] = offset + meshX + 1; // accounting for the extra column indices[indicesCount + 3] = offset + 1; indices[indicesCount + 4] = offset + meshX + 2; indices[indicesCount + 5] = offset + meshX + 1; indicesCount += 6; } } ret = true; } catch (Exception e) { if (physicsScene != null) { physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", LogHeader, physicsScene.RegionName, extentBase, e); } } indicesCountO = indicesCount; indicesO = indices; verticesCountO = verticesCount; verticesO = vertices; return(ret); }
public override void Dereference(BSScene physicsScene) { lock (Hulls) { DecrementReference(); physicsScene.DetailLog("{0},BSShapeHull.Dereference,shape={1}", BSScene.DetailLogZero, this); // TODO: schedule aging and destruction of unused meshes. } }
// Make this reference to the physical shape go away since native shapes are not shared. public override void Dereference(BSScene physicsScene) { // Native shapes are not tracked and are released immediately lock (physShapeInfo) { if (physShapeInfo.HasPhysicalShape) { physicsScene.DetailLog("{0},BSShapeNative.Dereference.deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo); } physShapeInfo.Clear(); // Garbage collection will free up this instance. } }
BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { BulletShape newShape = new BulletShape(); IMesh meshData; List<List<OMV.Vector3>> allHulls = null; lock (physicsScene.mesher) { // Pass true for physicalness as this prevents the creation of bounding box which is not needed meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); // If we should use the asset's hull info, fetch it out of the locked mesher if (meshData != null && BSParam.ShouldUseAssetHulls) { Meshmerizer realMesher = physicsScene.mesher as Meshmerizer; if (realMesher != null) { allHulls = realMesher.GetConvexHulls(size); } if (allHulls == null) { physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,noAssetHull", prim.LocalID); } } } // If there is hull data in the mesh asset, build the hull from that if (allHulls != null && BSParam.ShouldUseAssetHulls) { int hullCount = allHulls.Count; shapeInfo.HullCount = hullCount; int totalVertices = 1; // include one for the count of the hulls // Using the structure described for HACD hulls, create the memory structure // to pass the hull data to the creater. foreach (List<OMV.Vector3> hullVerts in allHulls) { totalVertices += 4; // add four for the vertex count and centroid totalVertices += hullVerts.Count*3; // one vertex is three dimensions } float[] convHulls = new float[totalVertices]; convHulls[0] = (float) hullCount; int jj = 1; int hullIndex = 0; foreach (List<OMV.Vector3> hullVerts in allHulls) { convHulls[jj + 0] = hullVerts.Count; convHulls[jj + 1] = 0f; // centroid x,y,z convHulls[jj + 2] = 0f; convHulls[jj + 3] = 0f; jj += 4; foreach (OMV.Vector3 oneVert in hullVerts) { convHulls[jj + 0] = oneVert.X; convHulls[jj + 1] = oneVert.Y; convHulls[jj + 2] = oneVert.Z; jj += 3; } shapeInfo.SetVerticesPerHull(hullIndex, hullVerts.Count); hullIndex++; } // create the hull data structure in Bullet newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,AssetHulls,hulls={1},totVert={2},shape={3}", prim.LocalID, hullCount, totalVertices, newShape); } // If no hull specified in the asset and we should use Bullet's HACD approximation... if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD) { // Build the hull shape from an existing mesh shape. // The mesh should have already been created in Bullet. physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,entry", prim.LocalID); var meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); if (meshShape.physShapeInfo.HasPhysicalShape) { HACDParams parms = new HACDParams(); parms.maxVerticesPerHull = BSParam.BHullMaxVerticesPerHull; parms.minClusters = BSParam.BHullMinClusters; parms.compacityWeight = BSParam.BHullCompacityWeight; parms.volumeWeight = BSParam.BHullVolumeWeight; parms.concavity = BSParam.BHullConcavity; parms.addExtraDistPoints = BSParam.NumericBool(BSParam.BHullAddExtraDistPoints); parms.addNeighboursDistPoints = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints); parms.addFacesPoints = BSParam.NumericBool(BSParam.BHullAddFacesPoints); parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin); parms.whichHACD = 0; // Use the HACD routine that comes with Bullet physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape); // Now done with the mesh shape. shapeInfo.HullCount = 1; BSShapeMesh maybeMesh = meshShape as BSShapeMesh; if (maybeMesh != null) shapeInfo.SetVerticesPerHull(0, maybeMesh.shapeInfo.Vertices); meshShape.Dereference(physicsScene); } physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); } // If no other hull specifications, use our HACD hull approximation. if (!newShape.HasPhysicalShape && meshData != null) { if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) { // Release the fetched asset data once it has been used. pbs.SculptData = new byte[0]; prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; } int[] indices = meshData.getIndexListAsInt(); //format conversion from IMesh format to DecompDesc format List<int> convIndices = new List<int>(); List<float3> convVertices = new List<float3>(); for (int ii = 0; ii < indices.GetLength(0); ii++) { convIndices.Add(indices[ii]); } // greythane - use the integer array instead of OS type vertex list // List<OMV.Vector3> vertices = meshData.getVertexList(); // foreach (OMV.Vector3 vv in vertices) // { // convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); // } var vertices = meshData.getVertexListAsFloat(); var vertexCount = vertices.Length / 3; for (int i = 0; i < vertexCount; i++) { convVertices.Add(new float3(vertices[3 * i + 0], vertices[3 * i + 1], vertices[3 * i + 2])); } uint maxDepthSplit = (uint) BSParam.CSHullMaxDepthSplit; if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) { // Simple primitive shapes we know are convex so they are better implemented with // fewer hulls. // Check for simple shape (prim without cuts) and reduce split parameter if so. if (BSShapeCollection.PrimHasNoCuts(pbs)) { maxDepthSplit = (uint) BSParam.CSHullMaxDepthSplitForSimpleShapes; } } // setup and do convex hull conversion m_hulls = new List<ConvexResult>(); DecompDesc dcomp = new DecompDesc(); dcomp.mIndices = convIndices; dcomp.mVertices = convVertices; dcomp.mDepth = maxDepthSplit; dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; dcomp.mMaxVertices = (uint) BSParam.CSHullMaxVertices; dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); // create the hull into the _hulls variable convexBuilder.process(dcomp); physicsScene.DetailLog( "{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Length, maxDepthSplit, m_hulls.Count); // Convert the vertices and indices for passing to unmanaged. // The hull information is passed as a large floating point array. // The format is: // convHulls[0] = number of hulls // convHulls[1] = number of vertices in first hull // convHulls[2] = hull centroid X coordinate // convHulls[3] = hull centroid Y coordinate // convHulls[4] = hull centroid Z coordinate // convHulls[5] = first hull vertex X // convHulls[6] = first hull vertex Y // convHulls[7] = first hull vertex Z // convHulls[8] = second hull vertex X // ... // convHulls[n] = number of vertices in second hull // convHulls[n+1] = second hull centroid X coordinate // ... // // TODO: is is very inefficient. Someday change the convex hull generator to return // data structures that do not need to be converted in order to pass to Bullet. // And maybe put the values directly into pinned memory rather than marshaling. int hullCount = m_hulls.Count; int totalVertices = 1; // include one for the count of the hulls foreach (ConvexResult cr in m_hulls) { totalVertices += 4; // add four for the vertex count and centroid totalVertices += cr.HullIndices.Count*3; // we pass just triangles } float[] convHulls = new float[totalVertices]; convHulls[0] = (float) hullCount; int jj = 1; foreach (ConvexResult cr in m_hulls) { // copy vertices for index access float3[] verts = new float3[cr.HullVertices.Count]; int kk = 0; foreach (float3 ff in cr.HullVertices) { verts[kk++] = ff; } // add to the array one hull's worth of data convHulls[jj++] = cr.HullIndices.Count; convHulls[jj++] = 0f; // centroid x,y,z convHulls[jj++] = 0f; convHulls[jj++] = 0f; foreach (int ind in cr.HullIndices) { convHulls[jj++] = verts[ind].x; convHulls[jj++] = verts[ind].y; convHulls[jj++] = verts[ind].z; } } // create the hull data structure in Bullet newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); } newShape.shapeKey = newHullKey; return newShape; }
public BSActorSetForce(BSScene physicsScene, BSPhysObject pObj, string actorName) : base(physicsScene, pObj, actorName) { m_forceMotor = null; m_physicsScene.DetailLog("{0},BSActorSetForce,constructor", m_controllingPrim.LocalID); }
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) : base(physicsScene, regionBase, id) { }
public BSConstraint(BulletWorld world) { m_world = world; PhysicsScene = m_world.physicsScene; }
public BSTerrainManager(BSScene physicsScene) { PhysicsScene = physicsScene; // Assume one region of default size m_worldMax = new Vector3(physicsScene.Scene.RegionInfo.RegionSizeX, physicsScene.Scene.RegionInfo.RegionSizeY, physicsScene.Scene.RegionInfo.RegionSizeZ); }
#pragma warning restore 414 public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName) : base(myScene, myPrim, actorName) { ControllingPrim = myPrim; // as BSPrimLinkable;; Type = Vehicle.TYPE_NONE; m_haveRegisteredForSceneEvents = false; // SetupVehicleDebugging(); }
// 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, 0.1f, 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 BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) : base(physicsScene, pObj, actorName) { m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); LockAxisConstraint = null; }
public static BulletShape CreatePhysicalNativeShape(BSScene physicsScene, BSPhysObject prim, BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) { BulletShape newShape; 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) { newShape = physicsScene.PE.BuildCapsuleShape(physicsScene.World, 1f, 1f, prim.Scale); physicsScene.DetailLog("{0},BSShapeNative,capsule,scale={1}", prim.LocalID, prim.Scale); } else { 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.shapeType = shapeType; newShape.isNativeShape = true; newShape.shapeKey = (UInt64) shapeKey; return newShape; }
public BSActorMoveToTarget(BSScene physicsScene, BSPhysObject pObj, string actorName) : base(physicsScene, pObj, actorName) { m_targetMotor = null; m_physicsScene.DetailLog("{0},BSActorMoveToTarget,constructor", m_controllingPrim.LocalID); }
public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) { float lod; UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); BSShapeMesh retMesh; lock (Meshes) { if (Meshes.TryGetValue(newMeshKey, out retMesh)) { // The mesh has already been created. Return a new reference to same. retMesh.IncrementReference(); } else { retMesh = new BSShapeMesh(new BulletShape()); // An instance of this mesh has not been created. Build and remember same. BulletShape newShape = retMesh.CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); // Check to see if mesh was created (might require an asset). newShape = VerifyMeshCreated(physicsScene, newShape, prim); if (!newShape.isNativeShape || prim.AssetFailed()) { // If a mesh was what was created, remember the built shape for later sharing. // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh. Meshes.Add(newMeshKey, retMesh); } retMesh.physShapeInfo = newShape; } } physicsScene.DetailLog("{0},BSShapeMesh,getReference,mesh={1},size={2},lod={3}", prim.LocalID, retMesh, prim.Size, lod); return retMesh; }
BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, (w, iC, i, vC, v) => { shapeInfo.Vertices = vC; return physicsScene.PE.CreateMeshShape(w, iC, i, vC, v); }); }
public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, Vector3 pos, Vector3 size, Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) { ClearDisplacement(); }
// Code that uses the mesher to create the index/vertices info for a trimesh shape. // This is used by the passed 'makeShape' call to create the Bullet mesh shape. // The actual build call is passed so this logic can be used by several of the shapes that use a // simple mesh as their base shape. public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape) { BulletShape newShape = new BulletShape(); IMesh meshData; lock (physicsScene.mesher) { meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, false, // say it is not physical so a bounding box is not built false // do not cache the mesh and do not use previously built versions ); } if (meshData != null) { if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) { // Release the fetched asset data once it has been used. pbs.SculptData = new byte[0]; prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; } 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; } } } physicsScene.DetailLog( "{0},BSShapeMesh.CreatePhysicalMesh,key={1},origTri={2},realTri={3},numVerts={4}", BSScene.DetailLogZero, newMeshKey.ToString("X"), indices.Length/3, realIndicesIndex/3, verticesAsFloats.Length/3); if (realIndicesIndex != 0) { newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length/3, verticesAsFloats); } else { // Force the asset condition to 'failed' so we won't try to keep fetching and processing this mesh. prim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedMeshing; physicsScene.Logger.DebugFormat("{0} All mesh triangles degenerate. Prim={1}", LogHeader, UsefulPrimInfo(physicsScene, prim)); physicsScene.DetailLog("{0},BSShapeMesh.CreatePhysicalMesh,allDegenerate,key={1}", prim.LocalID, newMeshKey); } } newShape.shapeKey = newMeshKey; return newShape; }
public BSConstraint(BulletWorld world) { m_world = world; PhysicsScene = m_world.physicsScene; }
public BulletWorld(uint worldId, BSScene bss) { worldID = worldId; physicsScene = bss; }