// 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 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); } if (ret == null) { ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); } return(ret); }
// 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 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); } if (ret == null) ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); return ret; }
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; _position = pos; // 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; } // A motor to control the acceleration and deceleration of the avatar movement. // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); // Infinite decay and timescale values so motor only changes current to target values. _velocityMotor = new BSVMotor("BSCharacter.Velocity", 0.2f, // time scale BSMotor.Infinite, // decay time scale BSMotor.InfiniteVector, // friction timescale 1f // efficiency ); _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. _flying = isFlying; _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; _appliedVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); _currentFriction = BSParam.AvatarStandingFriction; _avatarDensity = BSParam.AvatarDensity; // The dimensions of the avatar capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. ComputeAvatarScale(_size); // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); // do actual creation in taint time PhysicsScene.TaintedObject("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(); }); return; }
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 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 BSTerrainManager(BSScene physicsScene) { PhysicsScene = physicsScene; m_terrains = new Dictionary <Vector3, BSTerrainPhys>(); // Assume one region of default size m_worldOffset = Vector3.Zero; m_worldMax = new Vector3(DefaultRegionSize); MegaRegionParentPhysicsScene = null; }
public PhysicsScene GetScene(String sceneIdentifier) { if (_mScene == null) { // If not Windows, loading is performed by the // Mono loader as specified in // "bin/Physics/OpenSim.Region.Physics.BulletSNPlugin.dll.config". _mScene = new BSScene(sceneIdentifier); } return(_mScene); }
public PhysicsScene GetScene(String sceneIdentifier) { if (_mScene == null) { // If not Windows, loading is performed by the // Mono loader as specified in // "bin/Physics/OpenSim.Region.Physics.BulletSNPlugin.dll.config". _mScene = new BSScene(sceneIdentifier); } return (_mScene); }
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; _position = pos; // 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; // A motor to control the acceleration and deceleration of the avatar movement. // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); // Infinite decay and timescale values so motor only changes current to target values. _velocityMotor = new BSVMotor("BSCharacter.Velocity", 0.2f, // time scale BSMotor.Infinite, // decay time scale BSMotor.InfiniteVector, // friction timescale 1f // efficiency ); _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. _flying = isFlying; _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; _appliedVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); _currentFriction = BSParam.AvatarStandingFriction; _avatarDensity = BSParam.AvatarDensity; // The dimensions of the avatar capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. ComputeAvatarScale(_size); // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); // do actual creation in taint time PhysicsScene.TaintedObject("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(); }); 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 BulletHeightMapInfo(id, initialMap, null); 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(); }
// 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 BulletHeightMapInfo(id, initialMap, null); 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, BSPhysObject 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 <BSPhysObject>(); LinksetMass = parent.RawMass; Rebuilding = false; }
// 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 BulletHeightMapInfo(id, initialMap, null); 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; TypeName = typeName; Linkset = BSLinkset.Factory(PhysicsScene, this); LastAssetBuildFailed = false; // Default material type Material = MaterialAttributes.Material.Wood; CollisionCollection = new CollisionEventUpdate(); SubscribedEventsMs = 0; CollidingStep = 0; CollidingGroundStep = 0; }
protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { PhysicsScene = parentScene; LocalID = localID; PhysObjectName = name; TypeName = typeName; Linkset = BSLinkset.Factory(PhysicsScene, this); LastAssetBuildFailed = false; // Default material type Material = MaterialAttributes.Material.Wood; CollisionCollection = new CollisionEventUpdate(); SubscribedEventsMs = 0; CollidingStep = 0; CollidingGroundStep = 0; }
// 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 BulletHeightMapInfo(id, initialMap, null); 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(); }
// Create the correct type of linkset for this child public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) { BSLinkset ret = null; switch ((int)BSParam.LinksetImplementation) { case (int)LinksetImplementation.Constraint: ret = new BSLinksetConstraints(physScene, parent); break; case (int)LinksetImplementation.Compound: ret = new BSLinksetCompound(physScene, parent); break; case (int)LinksetImplementation.Manual: // ret = new BSLinksetManual(physScene, parent); break; default: ret = new BSLinksetCompound(physScene, parent); break; } return ret; }
// Create the correct type of linkset for this child public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) { BSLinkset ret = null; switch ((int)BSParam.LinksetImplementation) { case (int)LinksetImplementation.Constraint: ret = new BSLinksetConstraints(physScene, parent); break; case (int)LinksetImplementation.Compound: ret = new BSLinksetCompound(physScene, parent); break; case (int)LinksetImplementation.Manual: // ret = new BSLinksetManual(physScene, parent); break; default: ret = new BSLinksetCompound(physScene, parent); break; } return(ret); }
public BSDynamics(BSScene myScene, BSPrim myPrim) { PhysicsScene = myScene; Prim = myPrim; Type = Vehicle.TYPE_NONE; }
public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ }
public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id) { PhysicsScene = physicsScene; TerrainBase = regionBase; ID = id; }
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") { // m_log.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 = 1f; _velocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; BaseShape = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; // Someday set default attributes based on the material but, for now, we don't know the prim material yet. // MaterialAttributes primMat = BSMaterials.GetAttributes(Material, pisPhysical); _density = PhysicsScene.Params.defaultDensity; _friction = PhysicsScene.Params.defaultFriction; _restitution = PhysicsScene.Params.defaultRestitution; _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness _mass = CalculateMass(); Linkset.Refresh(this); DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time PhysicsScene.TaintedObject("BSPrim.create", delegate() { CreateGeomAndObject(true); CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(PhysBody.ptr); }); }
protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn) { string identifier = op + "-" + id.ToString(); RegisteredActions[identifier] = actn; PhysicsScene.BeforeStep += actn; DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); }
// Release the use of a physical shape. public abstract void Dereference(BSScene physicsScene);
public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent) { }
// 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 physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr); ptr = null; // Garbage collection will free up this instance. }
// Get user set values out of the ini file. internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg) { foreach (ParameterDefn parm in ParameterDefinitions) { parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue); } }
// private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent) { }
public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id) { PhysicsScene = physicsScene; TerrainBase = regionBase; ID = id; }
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 float extentX, float extentY, // zero based range for output vertices Vector3 extentBase, // base to be added to all vertices float magnification, // number of vertices to create between heightMap coords 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 top and bottom edge. int totalVertices = (sizeX + 1) * (sizeY + 1); vertices = new float[totalVertices * 3]; int totalIndices = sizeX * sizeY * 6; indices = new int[totalIndices]; float magX = (float)sizeX / extentX; float magY = (float)sizeY / extentY; physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); 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 * magX + extentBase.X; vertices[verticesCount + 1] = (float)yy * magY + 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) { 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 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); }
protected BSLinkset(BSScene scene, BSPhysObject 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<BSPhysObject>(); LinksetMass = parent.RawMass; Rebuilding = false; }
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 = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); } else { ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData); } if (ptr == null) { physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", LogHeader, prim.LocalID, shapeType); } type = shapeType; key = (UInt64)shapeKey; }
public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) { return(null); }
public override void Dereference(BSScene physicsScene) { }
// 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 float extentX, float extentY, // zero based range for output vertices Vector3 extentBase, // base to be added to all vertices float magnification, // number of vertices to create between heightMap coords 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 top and bottom edge. int totalVertices = (sizeX + 1) * (sizeY + 1); vertices = new float[totalVertices * 3]; int totalIndices = sizeX * sizeY * 6; indices = new int[totalIndices]; float magX = (float)sizeX / extentX; float magY = (float)sizeY / extentY; physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); 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 * magX + extentBase.X; vertices[verticesCount + 1] = (float)yy * magY + 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) { 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 static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) { return null; }
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) : base(physicsScene, regionBase, id) { }
public BSTerrainManager(BSScene physicsScene) { PhysicsScene = physicsScene; m_terrains = new Dictionary<Vector3,BSTerrainPhys>(); // Assume one region of default size m_worldOffset = Vector3.Zero; m_worldMax = new Vector3(DefaultRegionSize); MegaRegionParentPhysicsScene = null; }
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) : base(physicsScene, regionBase, id) { }
public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent) { }
// 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); if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY, (float)m_sizeX, (float)m_sizeY, Vector3.Zero, 1.0f, out indicesCount, out indices, out verticesCount, out vertices)) { // DISASTER!! PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); // Something is very messed up and a crash is in our future. return; } PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", ID, indicesCount, indices.Length, verticesCount, vertices.Length); m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, indicesCount, indices, verticesCount, vertices), BSPhysicsShapeType.SHAPE_MESH); if (!m_terrainShape.HasPhysicalShape) { // DISASTER!! PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", 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 = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, 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; } // Set current terrain attributes BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction); BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction); BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution); BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Static objects are not very massive. BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); // Put the new terrain to the world of physical objects BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr, pos, rot); // Redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); m_terrainBody.collisionType = CollisionType.Terrain; m_terrainBody.ApplyCollisionMask(); // Make it so the terrain will not move or be considered for movement. BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); }
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) : base(physicsScene, regionBase, id) { }
public BulletWorld(uint worldId, BSScene bss, object xx) { ptr = xx; worldID = worldId; physicsScene = bss; }
// Pass through the settable parameters and set the default values internal static void SetParameterDefaultValues(BSScene physicsScene) { foreach (ParameterDefn parm in ParameterDefinitions) { parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue); } }
// 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); if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY, (float)m_sizeX, (float)m_sizeY, Vector3.Zero, 1.0f, out indicesCount, out indices, out verticesCount, out vertices)) { // DISASTER!! PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); // Something is very messed up and a crash is in our future. return; } PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", ID, indicesCount, indices.Length, verticesCount, vertices.Length); m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, indicesCount, indices, verticesCount, vertices), BSPhysicsShapeType.SHAPE_MESH); if (!m_terrainShape.HasPhysicalShape) { // DISASTER!! PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", 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 = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2(m_terrainShape.ptr, 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; } // Set current terrain attributes BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction); BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction); BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution); BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Static objects are not very massive. BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); // Put the new terrain to the world of physical objects BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr, pos, rot); // Redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); m_terrainBody.collisionType = CollisionType.Terrain; m_terrainBody.ApplyCollisionMask(); // Make it so the terrain will not move or be considered for movement. BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); }
// private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent) { }
// Release the use of a physical shape. public abstract void Dereference(BSScene physicsScene);
public BulletWorld(uint worldId, BSScene bss, object xx) { ptr = xx; worldID = worldId; physicsScene = bss; }
public override void Dereference(BSScene physicsScene) /* The magic of garbage collection will make this go away */ }