public static SoftBody CreateFromConvexHull(SoftBodyWorldInfo worldInfo, Vector3[] vertices, int nVertices, bool randomizeConstraints = true) { SoftBody body = new SoftBody(btSoftBodyHelpers_CreateFromConvexHull2( worldInfo._native, vertices, nVertices, randomizeConstraints)); body.WorldInfo = worldInfo; return body; }
public void RemoveSoftBody(BulletSharp.SoftBody.SoftBody softBody) { if (!_isDisposed && m_world is BulletSharp.SoftBody.SoftRigidDynamicsWorld) { ((BulletSharp.SoftBody.SoftRigidDynamicsWorld)m_world).RemoveSoftBody(softBody); if (softBody.UserObject is BCollisionObject) { ((BCollisionObject)softBody.UserObject).isInWorld = false; } } }
public void RemoveSoftBody(BulletSharp.SoftBody.SoftBody softBody) { if (!_isDisposed && m_world is BulletSharp.SoftBody.SoftRigidDynamicsWorld) { BDebug.Log(debugType, "Removing softbody {0} from world", softBody.UserObject); ((BulletSharp.SoftBody.SoftRigidDynamicsWorld)m_world).RemoveSoftBody(softBody); if (softBody.UserObject is BCollisionObject) { ((BCollisionObject)softBody.UserObject).isInWorld = false; } } }
public void SetUp() { conf = new SoftBodyRigidBodyCollisionConfiguration(); dispatcher = new CollisionDispatcher(conf); broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)); solver = new DefaultSoftBodySolver(); world = new SoftRigidDynamicsWorld(dispatcher, broadphase, null, conf, solver); softBodyWorldInfo = new SoftBodyWorldInfo(); softBody = new SoftBody(softBodyWorldInfo); world.AddSoftBody(softBody); }
public override void Run() { var softBodyWorldInfo = new SoftBodyWorldInfo(); var softBody = new SoftBody(softBodyWorldInfo); var softBodyCollisionConf = new SoftBodyRigidBodyCollisionConfiguration(); var softBodySolver = new DefaultSoftBodySolver(); var dispatcher = new CollisionDispatcher(softBodyCollisionConf); var broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)); var softBodyWorld = new SoftRigidDynamicsWorld(dispatcher, broadphase, null, softBodyCollisionConf, softBodySolver); softBodyWorld.AddSoftBody(softBody); if (!object.ReferenceEquals(softBody.SoftBodySolver, softBodySolver)) { Console.WriteLine("SoftBody: body and world SoftBodySolvers don't match!"); } AddToDisposeQueue(softBodyWorldInfo); AddToDisposeQueue(softBody); AddToDisposeQueue(softBodyCollisionConf); AddToDisposeQueue(softBodySolver); AddToDisposeQueue(dispatcher); AddToDisposeQueue(broadphase); AddToDisposeQueue(softBodyWorld); softBodyWorldInfo = null; softBody = null; softBodyCollisionConf = null; softBodySolver = null; dispatcher = null; broadphase = null; softBodyWorld.Dispose(); softBodyWorld = null; ForceGC(); TestWeakRefs(); ClearRefs(); }
void InitSoftBodyInstance(SoftBody softBody, CollisionShape shape) { var shapeData = InitShapeData(shape); shapeData.Instances.Add(new InstanceData() { WorldTransform = Matrix.Identity, Color = softBodyColor }); UpdateSoftBody(softBody, shapeData); }
public void Register(SoftBody body) { this.World.AddSoftBody(body); this.softbodies.Add(body); }
public static void SolveCommonConstraints(SoftBody bodies, int count, int iterations) { btSoftBody_solveCommonConstraints(bodies._native, count, iterations); }
public static void PSolveRContacts(SoftBody psb, float kst, float ti) { btSoftBody_PSolve_RContacts(psb._native, kst, ti); }
public static void PSolveAnchors(SoftBody psb, float kst, float ti) { btSoftBody_PSolve_Anchors(psb._native, kst, ti); }
public void AppendLinearJoint(LinearJoint.Specs specs, SoftBody body) { btSoftBody_appendLinearJoint(_native, specs._native, body._native); }
public void RenderSoftBodyTextured(SoftBody softBody) { if (!(softBody.UserObject is Array)) return; object[] userObjArr = softBody.UserObject as object[]; FloatArray vertexBuffer = userObjArr[0] as FloatArray; IntArray indexBuffer = userObjArr[1] as IntArray; int vertexCount = (vertexBuffer.Count / 8); if (vertexCount > 0) { int faceCount = indexBuffer.Count / 2; bool index32 = vertexCount > 65536; Mesh mesh = new Mesh(device, faceCount, vertexCount, MeshFlags.SystemMemory | (index32 ? MeshFlags.Use32Bit : 0), VertexFormat.Position | VertexFormat.Normal | VertexFormat.Texture1); DataStream indices = mesh.LockIndexBuffer(LockFlags.Discard); if (index32) { foreach (int i in indexBuffer) indices.Write(i); } else { foreach (int i in indexBuffer) indices.Write((short)i); } mesh.UnlockIndexBuffer(); DataStream verts = mesh.LockVertexBuffer(LockFlags.Discard); foreach (float f in vertexBuffer) verts.Write(f); mesh.UnlockVertexBuffer(); mesh.ComputeNormals(); mesh.DrawSubset(0); mesh.Dispose(); } }
public void RenderSoftBody(SoftBody softBody) { Cull cullMode = device.GetRenderState<Cull>(RenderState.CullMode); device.SetRenderState(RenderState.CullMode, Cull.None); AlignedFaceArray faces = softBody.Faces; int faceCount = faces.Count; if (faceCount > 0) { PositionedNormal[] vectors = new PositionedNormal[faceCount * 6]; int v = 0; int i; for (i = 0; i < faceCount; i++) { NodePtrArray nodes = faces[i].N; Node n0 = nodes[0]; Node n1 = nodes[1]; Node n2 = nodes[2]; n0.GetX(out vectors[v].Position); n0.GetNormal(out vectors[v].Normal); n1.GetX(out vectors[v + 1].Position); n1.GetNormal(out vectors[v + 1].Normal); n2.GetX(out vectors[v + 2].Position); n2.GetNormal(out vectors[v + 2].Normal); v += 3; } device.VertexFormat = VertexFormat.PositionNormal; device.DrawUserPrimitives(PrimitiveType.TriangleList, faces.Count, vectors); } else { AlignedTetraArray tetras = softBody.Tetras; int tetraCount = tetras.Count; if (tetraCount > 0) { PositionedNormal[] vectors = new PositionedNormal[tetraCount * 12]; int v = 0; for (int i = 0; i < tetraCount; i++) { NodePtrArray nodes = tetras[i].Nodes; BulletSharp.Vector3 v0 = nodes[0].X; BulletSharp.Vector3 v1 = nodes[1].X; BulletSharp.Vector3 v2 = nodes[2].X; BulletSharp.Vector3 v3 = nodes[3].X; BulletSharp.Vector3 v10 = v1 - v0; BulletSharp.Vector3 v02 = v0 - v2; BulletSharp.Vector3 normal = BulletSharp.Vector3.Cross(v10, v02); normal.Normalize(); vectors[v].Position = v0; vectors[v].Normal = normal; vectors[v + 1].Position = v1; vectors[v + 1].Normal = normal; vectors[v + 2].Position = v2; vectors[v + 2].Normal = normal; normal = BulletSharp.Vector3.Cross(v10, v3 - v0); normal.Normalize(); vectors[v + 3].Position = v0; vectors[v + 3].Normal = normal; vectors[v + 4].Position = v1; vectors[v + 4].Normal = normal; vectors[v + 5].Position = v3; vectors[v + 5].Normal = normal; normal = BulletSharp.Vector3.Cross(v2 - v1, v3 - v1); normal.Normalize(); vectors[v + 6].Position = v1; vectors[v + 6].Normal = normal; vectors[v + 7].Position = v2; vectors[v + 7].Normal = normal; vectors[v + 8].Position = v3; vectors[v + 8].Normal = normal; normal = BulletSharp.Vector3.Cross(v02, v3 - v2); normal.Normalize(); vectors[v + 9].Position = v2; vectors[v + 9].Normal = normal; vectors[v + 10].Position = v0; vectors[v + 10].Normal = normal; vectors[v + 11].Position = v3; vectors[v + 11].Normal = normal; v += 12; } device.VertexFormat = VertexFormat.PositionNormal; device.DrawUserPrimitives(PrimitiveType.TriangleList, tetraCount * 4, vectors); } else if (softBody.Links.Count > 0) { AlignedLinkArray links = softBody.Links; int linkCount = links.Count; int linkColor = System.Drawing.Color.Black.ToArgb(); device.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse; PositionColored[] linkArray = new PositionColored[linkCount * 2]; for (int i = 0; i < linkCount; i++) { Link link = links[i]; linkArray[i * 2].Position = link.Nodes[0].X; linkArray[i * 2].Color = linkColor; linkArray[i * 2 + 1].Position = link.Nodes[1].X; linkArray[i * 2 + 1].Color = linkColor; } device.DrawUserPrimitives(PrimitiveType.LineList, links.Count, linkArray); } } device.SetRenderState(RenderState.CullMode, cullMode); }
public static SoftBody CreateFromTetGenData(SoftBodyWorldInfo worldInfo, string ele, string face, string node, bool faceLinks, bool tetraLinks, bool facesFromTetras) { CultureInfo culture = CultureInfo.InvariantCulture; char[] separator = new[] { ' ' }; Vector3[] pos; using (StringReader nodeReader = new StringReader(node)) { string[] nodeHeader = nodeReader.ReadLine().Split(separator, StringSplitOptions.RemoveEmptyEntries); int numNodes = int.Parse(nodeHeader[0]); //int numDims = int.Parse(nodeHeader[1]); //int numAttrs = int.Parse(nodeHeader[2]); //bool hasBounds = !nodeHeader[3].Equals("0"); pos = new Vector3[numNodes]; for (int n = 0; n < numNodes; n++) { string[] nodeLine = nodeReader.ReadLine().Split(separator, StringSplitOptions.RemoveEmptyEntries); pos[int.Parse(nodeLine[0])] = new Vector3( float.Parse(nodeLine[1], culture), float.Parse(nodeLine[2], culture), float.Parse(nodeLine[3], culture)); } } SoftBody psb = new SoftBody(worldInfo, pos.Length, pos, null); /* if (!string.IsNullOrEmpty(face)) { throw new NotImplementedException(); } */ if (!string.IsNullOrEmpty(ele)) { using (StringReader eleReader = new StringReader(ele)) { string[] eleHeader = eleReader.ReadLine().Split(separator, StringSplitOptions.RemoveEmptyEntries); int numTetras = int.Parse(eleHeader[0]); //int numCorners = int.Parse(eleHeader[1]); //int numAttrs = int.Parse(eleHeader[2]); for (int n = 0; n < numTetras; n++) { string[] eleLine = eleReader.ReadLine().Split(separator, StringSplitOptions.RemoveEmptyEntries); //int index = int.Parse(eleLine[0], culture); int ni0 = int.Parse(eleLine[1], culture); int ni1 = int.Parse(eleLine[2], culture); int ni2 = int.Parse(eleLine[3], culture); int ni3 = int.Parse(eleLine[4], culture); psb.AppendTetra(ni0, ni1, ni2, ni3); if (tetraLinks) { psb.AppendLink(ni0, ni1, null, true); psb.AppendLink(ni1, ni2, null, true); psb.AppendLink(ni2, ni0, null, true); psb.AppendLink(ni0, ni3, null, true); psb.AppendLink(ni1, ni3, null, true); psb.AppendLink(ni2, ni3, null, true); } } } } //Console.WriteLine("Nodes: {0}", psb.Nodes.Count); //Console.WriteLine("Links: {0}", psb.Links.Count); //Console.WriteLine("Faces: {0}", psb.Faces.Count); //Console.WriteLine("Tetras: {0}", psb.Tetras.Count); return psb; }
// ReoptimizeLinkOrder minimizes the cases where links L and L+1 share a common node. public static void ReoptimizeLinkOrder(SoftBody psb) { AlignedLinkArray links = psb.Links; AlignedNodeArray nodes = psb.Nodes; int nLinks = links.Count; int nNodes = nodes.Count; List<Link> readyList = new List<Link>(); Dictionary<Link, Link> linkBuffer = new Dictionary<Link, Link>(); Dictionary<Link, LinkDep> linkDeps = new Dictionary<Link, LinkDep>(); Dictionary<Node, Link> nodeWrittenAt = new Dictionary<Node, Link>(); Dictionary<Link, Link> linkDepA = new Dictionary<Link, Link>(); // Link calculation input is dependent upon prior calculation #N Dictionary<Link, Link> linkDepB = new Dictionary<Link, Link>(); foreach (Link link in links) { Node ar = link.Nodes[0]; Node br = link.Nodes[1]; linkBuffer.Add(link, new Link(btSoftBody_Link_new2(link._native))); LinkDep linkDep; if (nodeWrittenAt.ContainsKey(ar)) { linkDepA[link] = nodeWrittenAt[ar]; linkDeps.TryGetValue(nodeWrittenAt[ar], out linkDep); linkDeps[nodeWrittenAt[ar]] = new LinkDep() { Next = linkDep, Value = link}; } if (nodeWrittenAt.ContainsKey(br)) { linkDepB[link] = nodeWrittenAt[br]; linkDeps.TryGetValue(nodeWrittenAt[br], out linkDep); linkDeps[nodeWrittenAt[br]] = new LinkDep() { Next = linkDep, Value = link, LinkB = true }; } if (!linkDepA.ContainsKey(link) && !linkDepB.ContainsKey(link)) { readyList.Add(link); } // Update the nodes to mark which ones are calculated by this link nodeWrittenAt[ar] = link; nodeWrittenAt[br] = link; } int i = 0; while (readyList.Count != 0) { Link link = readyList[0]; links[i++] = linkBuffer[link]; readyList.RemoveAt(0); LinkDep linkDep; linkDeps.TryGetValue(link, out linkDep); while (linkDep != null) { link = linkDep.Value; if (linkDep.LinkB) { linkDepB.Remove(link); } else { linkDepA.Remove(link); } // Add this dependent link calculation to the ready list if *both* inputs are clear if (!linkDepA.ContainsKey(link) && !linkDepB.ContainsKey(link)) { readyList.Add(link); } linkDep = linkDep.Next; } } foreach (Link link in linkBuffer.Values) { btSoftBody_Element_delete(link._native); } }
public static void DrawNodeTree(SoftBody psb, IDebugDraw iDraw, int minDepth, int maxDepth) { btSoftBodyHelpers_DrawNodeTree3(psb._native, DebugDraw.GetUnmanaged(iDraw), minDepth, maxDepth); }
static void TestSoftBody() { var softBodyWorldInfo = new SoftBodyWorldInfo(); var softBody = new SoftBody(softBodyWorldInfo); var softBodyCollisionConf = new SoftBodyRigidBodyCollisionConfiguration(); var softBodySolver = new DefaultSoftBodySolver(); var dispatcher = new CollisionDispatcher(softBodyCollisionConf); var broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)); var softBodyWorld = new SoftRigidDynamicsWorld(dispatcher, broadphase, null, softBodyCollisionConf, softBodySolver); softBodyWorld.AddSoftBody(softBody); if (!object.ReferenceEquals(softBody.SoftBodySolver, softBodySolver)) { Console.WriteLine("SoftBody: body and world SoftBodySolvers don't match!"); } AddToDisposeQueue(softBodyWorldInfo); AddToDisposeQueue(softBody); AddToDisposeQueue(softBodyCollisionConf); AddToDisposeQueue(softBodySolver); AddToDisposeQueue(dispatcher); AddToDisposeQueue(broadphase); AddToDisposeQueue(softBodyWorld); softBodyWorldInfo = null; softBody = null; softBodyCollisionConf = null; softBodySolver = null; dispatcher = null; broadphase = null; softBodyWorld.Dispose(); softBodyWorld = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); TestWeakRefs(); disposeQueue.Clear(); }
void Init_Bending() { const float s = 4; Vector3[] x = new Vector3[]{new Vector3(-s,0,-s), new Vector3(+s,0,-s), new Vector3(+s,0,+s), new Vector3(-s,0,+s)}; float[] m = new float[] { 0, 0, 0, 1 }; SoftBody psb = new SoftBody(softBodyWorldInfo, x, m); psb.AppendLink(0, 1); psb.AppendLink(1, 2); psb.AppendLink(2, 3); psb.AppendLink(3, 0); psb.AppendLink(0, 2); SoftWorld.AddSoftBody(psb); }
public void AppendAngularJoint(AngularJoint.Specs specs, SoftBody body) { StoreAngularJointControlRef(specs); btSoftBody_appendAngularJoint3(_native, specs._native, body._native); }
void Init_ClusterCombine() { Vector3 sz = new Vector3(2, 4, 2); SoftBody psb0 = Create_ClusterTorus(new Vector3(0, 8, 0), new Vector3((float)Math.PI / 2, 0, (float)Math.PI / 2), sz); SoftBody psb1 = Create_ClusterTorus(new Vector3(0, 8, 10), new Vector3((float)Math.PI / 2, 0, (float)Math.PI / 2), sz); SoftBody[] psbs = new SoftBody[] { psb0, psb1 }; for (int j = 0; j < 2; ++j) { psbs[j].Cfg.DF = 1; psbs[j].Cfg.DP = 0; psbs[j].Cfg.PIterations = 1; psbs[j].Clusters[0].Matching = 0.05f; psbs[j].Clusters[0].NodeDamping = 0.05f; } AJoint.Specs aj = new AJoint.Specs(); aj.Axis = new Vector3(0, 0, 1); aj.Control = motorControl; psb0.AppendAngularJoint(aj, psb1); LJoint.Specs lj = new LJoint.Specs(); lj.Position = new Vector3(0, 8, 5); psb0.AppendLinearJoint(lj, psb1); }
public void DefaultCollisionHandler(SoftBody psb) { btSoftBody_defaultCollisionHandler2(_native, psb._native); }
public void AddSoftBody(SoftBody body, short collisionFilterGroup, short collisionFilterMask) { body.SoftBodySolver = _softBodySolver; _collisionObjectArray.Add(body, collisionFilterGroup, collisionFilterMask); }
public static void PSolveLinks(SoftBody psb, float kst, float ti) { btSoftBody_PSolve_Links(psb._native, kst, ti); }
public void RemoveSoftBody(SoftBody body) { _collisionObjectArray.Remove(body); }
public static void PSolveSContacts(SoftBody psb, float __unnamed1, float ti) { btSoftBody_PSolve_SContacts(psb._native, __unnamed1, ti); }
public void AddSoftBody(SoftBody body) { body.SoftBodySolver = _softBodySolver; _collisionObjectArray.Add(body); }
public static void VSolveLinks(SoftBody psb, float kst) { btSoftBody_VSolve_Links(psb._native, kst); }
public void ProcessCollision(SoftBody __unnamed0, CollisionObjectWrapper __unnamed1) { btSoftBodySolver_processCollision(_native, __unnamed0._native, __unnamed1._native); }
public void Unregister(SoftBody body) { this.softbodies.Remove(body); this.World.RemoveCollisionObject(body); }
public void ProcessCollision(SoftBody __unnamed0, SoftBody __unnamed1) { btSoftBodySolver_processCollision2(_native, __unnamed0._native, __unnamed1._native); }
public void UpdateSoftBody(SoftBody softBody, ShapeData shapeData) { // Could just allocate a Vector3 array here at each frame, but reusing shapeData.SoftBodyData is faster. // Probably uses more memory though. shapeData.VertexCount = softBody.GetVertexNormalData(out shapeData.SoftBodyData); shapeData.SetDynamicVertexBuffer(device, shapeData.SoftBodyData); if (softBody.Faces.Count == 0 && softBody.Tetras.Count == 0) { shapeData.PrimitiveTopology = PrimitiveTopology.LineList; } }
public override float[] GetUV(SoftBody sb) { return this.uvs; }