public bool RemoveBody(SoftBody body) { if (!this.softbodies.Remove(body)) return false; this.CollisionSystem.RemoveEntity(body); events.RaiseRemovedSoftBody(body); foreach (Constraint constraint in body.EdgeSprings) RemoveConstraint(constraint); foreach (SoftBody.MassPoint massPoint in body.VertexBodies) RemoveBody(massPoint, true); return true; }
internal void RaiseRemovedSoftBody(SoftBody body) { if (RemovedSoftBody != null) RemovedSoftBody(body); }
public void AddBody(SoftBody body) { if (body == null) throw new ArgumentNullException("body", "body can't be null."); if (softbodies.Contains(body)) throw new ArgumentException("The body was already added to the world.", "body"); this.softbodies.Add(body); this.CollisionSystem.AddEntity(body); events.RaiseAddedSoftBody(body); foreach (Constraint constraint in body.EdgeSprings) AddConstraint(constraint); foreach (SoftBody.MassPoint massPoint in body.VertexBodies) { events.RaiseAddedRigidBody(massPoint); rigidBodies.Add(massPoint); } }
public Triangle(SoftBody owner) { this.owner = owner; }
internal void RaiseAddedSoftBody(SoftBody body) { if (AddedSoftBody != null) AddedSoftBody(body); }
public static int FindNearestTrianglePoint(SoftBody sb, int id, ref JVector point) { SoftBody.Triangle triangle = sb.dynamicTree.GetUserData(id); JVector p; p = sb.VertexBodies[triangle.indices.I0].position; JVector.Subtract(ref p, ref point, out p); float length0 = p.LengthSquared(); p = sb.VertexBodies[triangle.indices.I1].position; JVector.Subtract(ref p, ref point, out p); float length1 = p.LengthSquared(); p = sb.VertexBodies[triangle.indices.I2].position; JVector.Subtract(ref p, ref point, out p); float length2 = p.LengthSquared(); if (length0 < length1) { if (length0 < length2) return triangle.indices.I0; else return triangle.indices.I2; } else { if (length1 < length2) return triangle.indices.I1; else return triangle.indices.I2; } }
public MassPoint(Shape shape, SoftBody owner, Material material) : base(shape, material, true) { this.SoftBody = owner; }
private void DetectSoftSoft(SoftBody body1, SoftBody body2) { List<int> my = potentialTriangleLists.GetNew(); List<int> other = potentialTriangleLists.GetNew(); body1.dynamicTree.Query(other, my, body2.dynamicTree); for (int i = 0; i < other.Count; i++) { SoftBody.Triangle myTriangle = body1.dynamicTree.GetUserData(my[i]); SoftBody.Triangle otherTriangle = body2.dynamicTree.GetUserData(other[i]); JVector point, normal; float penetration; bool result; result = XenoCollide.Detect(myTriangle, otherTriangle, ref JMatrix.InternalIdentity, ref JMatrix.InternalIdentity, ref JVector.InternalZero, ref JVector.InternalZero, out point, out normal, out penetration); if (result) { int minIndexMy = FindNearestTrianglePoint(body1, my[i], ref point); int minIndexOther = FindNearestTrianglePoint(body2, other[i], ref point); RaiseCollisionDetected(body1.VertexBodies[minIndexMy], body2.VertexBodies[minIndexOther], ref point, ref point, ref normal, penetration); } } my.Clear(); other.Clear(); potentialTriangleLists.GiveBack(my); potentialTriangleLists.GiveBack(other); }
private void DetectSoftRigid(RigidBody rigidBody, SoftBody softBody) { if (rigidBody.Shape is Multishape) { Multishape ms = (rigidBody.Shape as Multishape); ms = ms.RequestWorkingClone(); JBBox transformedBoundingBox = softBody.BoundingBox; transformedBoundingBox.InverseTransform(ref rigidBody.position, ref rigidBody.orientation); int msLength = ms.Prepare(ref transformedBoundingBox); List<int> detected = potentialTriangleLists.GetNew(); softBody.dynamicTree.Query(detected, ref rigidBody.boundingBox); foreach (int i in detected) { SoftBody.Triangle t = softBody.dynamicTree.GetUserData(i); JVector point, normal; float penetration; bool result; for (int e = 0; e < msLength; e++) { ms.SetCurrentShape(e); result = XenoCollide.Detect(ms, t, ref rigidBody.orientation, ref JMatrix.InternalIdentity, ref rigidBody.position, ref JVector.InternalZero, out point, out normal, out penetration); if (result) { int minIndex = FindNearestTrianglePoint(softBody, i, ref point); RaiseCollisionDetected(rigidBody, softBody.VertexBodies[minIndex], ref point, ref point, ref normal, penetration); } } } detected.Clear(); potentialTriangleLists.GiveBack(detected); ms.ReturnWorkingClone(); } else { List<int> detected = potentialTriangleLists.GetNew(); softBody.dynamicTree.Query(detected, ref rigidBody.boundingBox); foreach (int i in detected) { SoftBody.Triangle t = softBody.dynamicTree.GetUserData(i); JVector point, normal; float penetration; bool result; result = XenoCollide.Detect(rigidBody.Shape, t, ref rigidBody.orientation, ref JMatrix.InternalIdentity, ref rigidBody.position, ref JVector.InternalZero, out point, out normal, out penetration); if (result) { int minIndex = FindNearestTrianglePoint(softBody, i, ref point); RaiseCollisionDetected(rigidBody, softBody.VertexBodies[minIndex], ref point, ref point, ref normal, penetration); } } detected.Clear(); potentialTriangleLists.GiveBack(detected); } }
public MassPoint(Shape shape, SoftBody owner, Material material) : base(shape, material) { this.isMassPoint = true; this.SoftBody = owner; useShapeMassProperties = false; }
public ClothObject(Game game, SoftBody cloth) : base(game) { this.cloth = cloth; }
private void DrawDynamicTree(SoftBody cloth) { if(!debugDraw) return; Walk(cloth.DynamicTree,cloth.DynamicTree.Root); }
private void DrawDynamicTree(SoftBody cloth) { Walk(cloth.DynamicTree,cloth.DynamicTree.Root); }
public override void Build() { AddGround(); for (int i = 0; i < 15; i++) { bool even = (i % 2 == 0); for (int e = 0; e < 3; e++) { JVector size = (even) ? new JVector(1, 1, 3) : new JVector(3, 1, 1); RigidBody body = new RigidBody(new BoxShape(size)); body.Position = new JVector(3.0f + (even ? e : 1.0f), i + 0.5f, -5.0f + (even ? 1.0f : e)); Demo.World.AddBody(body); } } Model model = this.Demo.Content.Load<Model>("torus"); List<TriangleVertexIndices> indices = new List<TriangleVertexIndices>(); List<JVector> vertices = new List<JVector>(); ConvexHullObject.ExtractData(vertices, indices, model); RemoveDuplicateVertices(indices, vertices); SoftBody softBody = new SoftBody(indices, vertices); softBody.Translate(new JVector(10, 5, 0)); softBody.Pressure = 1000.0f; softBody.SetSpringValues(0.2f, 0.005f); //softBody.SelfCollision = true; ; Demo.World.AddBody(softBody); SoftBody cloth = new SoftBody(20,20,0.4f); // ##### Uncomment for selfcollision, all 3 lines //cloth.SelfCollision = true; //cloth.TriangleExpansion = 0.05f; //cloth.VertexExpansion = 0.05f; cloth.Translate(new JVector(0, 10, 10)); cloth.Material.KineticFriction = 0.9f; cloth.Material.StaticFriction = 0.95f; cloth.VertexBodies[0].IsStatic = true; cloth.VertexBodies[380].IsStatic = true; cloth.VertexBodies[19].IsStatic = true; cloth.VertexBodies[399].IsStatic = true; cloth.SetSpringValues(SoftBody.SpringType.EdgeSpring, 0.1f, 0.01f); cloth.SetSpringValues(SoftBody.SpringType.ShearSpring, 0.1f, 0.03f); cloth.SetSpringValues(SoftBody.SpringType.BendSpring, 0.1f, 0.03f); // ###### Uncomment here for a better visualization // Demo.Components.Add(new ClothObject(Demo, cloth)); Demo.World.AddBody(cloth); }