public void AddJoint(Joint joint) { if (!_jointList.Contains(joint)) { _jointList.Add(joint); } }
private void ProcessAddedItems() { //Add any new geometries for (int i = 0; i < geomAddList.Count; i++) { if (!geomList.Contains(geomAddList[i])) { geomAddList[i].isRemoved = false; geomList.Add(geomAddList[i]); //Add the new geometry to the broad phase collider. _broadPhaseCollider.Add(geomAddList[i]); } } geomAddList.Clear(); //Add any new bodies for (int i = 0; i < bodyAddList.Count; i++) { if (!bodyList.Contains(bodyAddList[i])) { bodyList.Add(bodyAddList[i]); } } bodyAddList.Clear(); //Add any new controllers for (int i = 0; i < controllerAddList.Count; i++) { if (!controllerList.Contains(controllerAddList[i])) { controllerList.Add(controllerAddList[i]); } } controllerAddList.Clear(); //Add any new joints for (int i = 0; i < jointAddList.Count; i++) { if (!jointList.Contains(jointAddList[i])) { jointList.Add(jointAddList[i]); } } jointAddList.Clear(); //Add any new springs for (int i = 0; i < springAddList.Count; i++) { if (!springList.Contains(springAddList[i])) { springList.Add(springAddList[i]); } } springAddList.Clear(); }
private void ProcessAddedJoints() { if (_jointAddList.Count > 0) { foreach (Joint joint in _jointAddList) { // Connect to the world list. JointList.Add(joint); // Connect to the bodies' doubly linked lists. joint.BodyA.JointList.Add(joint); // WIP David if (!joint.IsFixedType()) { joint.BodyB.JointList.Add(joint); Body bodyA = joint.BodyA; Body bodyB = joint.BodyB; // If the joint prevents collisions, then flag any contacts for filtering. if (joint.CollideConnected == false) { ContactEdge edge = bodyB.ContactList; while (edge != null) { if (edge.Other == bodyA) { // Flag the contact for filtering at the next time step (where either // body is awake). edge.Contact.FlagForFiltering(); } edge = edge.Next; } } } if (JointAdded != null) { JointAdded(joint); } // Note: creating a joint doesn't wake the bodies. } _jointAddList.Clear(); } }
private void ProcessAddedJoints() { if (_jointAddList.Count > 0) { foreach (var joint in _jointAddList) { // Connect to the world list. JointList.Add(joint); // Connect to the bodies' doubly linked lists. joint.EdgeA.Joint = joint; joint.EdgeA.Other = joint.BodyB; joint.EdgeA.Prev = null; joint.EdgeA.Next = joint.BodyA.JointList; if (joint.BodyA.JointList != null) { joint.BodyA.JointList.Prev = joint.EdgeA; } joint.BodyA.JointList = joint.EdgeA; // WIP David if (!joint.IsFixedType()) { joint.EdgeB.Joint = joint; joint.EdgeB.Other = joint.BodyA; joint.EdgeB.Prev = null; joint.EdgeB.Next = joint.BodyB.JointList; if (joint.BodyB.JointList != null) { joint.BodyB.JointList.Prev = joint.EdgeB; } joint.BodyB.JointList = joint.EdgeB; var bodyA = joint.BodyA; var bodyB = joint.BodyB; // If the joint prevents collisions, then flag any contacts for filtering. if (joint.CollideConnected == false) { var edge = bodyB.ContactList; while (edge != null) { if (edge.Other == bodyA) { // Flag the contact for filtering at the next time step (where either // body is awake). edge.Contact._flags |= ContactFlags.FilterFlag; } edge = edge.Next; } } } JointAdded?.Invoke(joint); // Note: creating a joint doesn't wake the bodies. } _jointAddList.Clear(); } }
public virtual void FromStream(Stream s, bool id) { Action <Action> action = delegate(Action a) { try { a(); } catch (Exception) { LoadErrCount++; } }; PmxHeader head = new PmxHeader(); head.FromStreamEx(s); Header.FromHeader(head); head.ElementFormat.WithID = id; action(delegate { ModelInfo.FromStreamEx(s, head.ElementFormat); }); int count = 0; action(delegate { count = PmxStreamHelper.ReadElement_Int32(s); }); VertexList.Clear(); VertexList.Capacity = count; for (int k = 0; k < count; k++) { PmxVertex v = new PmxVertex(); action(delegate { v.FromStreamEx(s, head.ElementFormat); }); VertexList.Add(v); } action(delegate { count = PmxStreamHelper.ReadElement_Int32(s); }); FaceList.Clear(); FaceList.Capacity = count; for (int l = 0; l < count; l++) { int ix = 0; action(delegate { ix = PmxStreamHelper.ReadElement_Int32(s, head.ElementFormat.VertexSize, signed: false); }); FaceList.Add(ix); } PmxTextureTable tx = new PmxTextureTable(); action(delegate { tx.FromStreamEx(s, head.ElementFormat); }); action(delegate { count = PmxStreamHelper.ReadElement_Int32(s); }); MaterialList.Clear(); MaterialList.Capacity = count; for (int m = 0; m < count; m++) { PmxMaterial j = new PmxMaterial(); action(delegate { j.FromStreamEx_TexTable(s, tx, head.ElementFormat); }); MaterialList.Add(j); } action(delegate { count = PmxStreamHelper.ReadElement_Int32(s); }); BoneList.Clear(); BoneList.Capacity = count; for (int n = 0; n < count; n++) { PmxBone b = new PmxBone(); action(delegate { b.FromStreamEx(s, head.ElementFormat); }); BoneList.Add(b); } action(delegate { count = PmxStreamHelper.ReadElement_Int32(s); }); MorphList.Clear(); MorphList.Capacity = count; for (int num = 0; num < count; num++) { PmxMorph morph = new PmxMorph(); action(delegate { morph.FromStreamEx(s, head.ElementFormat); }); MorphList.Add(morph); } action(delegate { count = PmxStreamHelper.ReadElement_Int32(s); }); NodeList.Clear(); NodeList.Capacity = count; for (int num2 = 0; num2 < count; num2++) { PmxNode node = new PmxNode(); action(delegate { node.FromStreamEx(s, head.ElementFormat); }); NodeList.Add(node); if (NodeList[num2].SystemNode) { if (NodeList[num2].Name == "Root") { RootNode = NodeList[num2]; } else if (NodeList[num2].Name == "表情") { ExpNode = NodeList[num2]; } } } action(delegate { count = PmxStreamHelper.ReadElement_Int32(s); }); BodyList.Clear(); BodyList.Capacity = count; for (int num3 = 0; num3 < count; num3++) { PmxBody b2 = new PmxBody(); action(delegate { b2.FromStreamEx(s, head.ElementFormat); }); BodyList.Add(b2); } action(delegate { count = PmxStreamHelper.ReadElement_Int32(s); }); JointList.Clear(); JointList.Capacity = count; for (int num4 = 0; num4 < count; num4++) { PmxJoint i = new PmxJoint(); action(delegate { i.FromStreamEx(s, head.ElementFormat); }); JointList.Add(i); } if (head.Ver >= 2.1f) { action(delegate { count = PmxStreamHelper.ReadElement_Int32(s); }); SoftBodyList.Clear(); SoftBodyList.Capacity = count; for (int num5 = 0; num5 < count; num5++) { PmxSoftBody b3 = new PmxSoftBody(); action(delegate { b3.FromStreamEx(s, head.ElementFormat); }); SoftBodyList.Add(b3); } } if (id) { action(delegate { FilePath = PmxStreamHelper.ReadString(s, head.ElementFormat); }); } head.ElementFormat.WithID = false; }
public void FromPmx(Pmx pmx) { Clear(); FilePath = pmx.FilePath; LoadErrCount = pmx.LoadErrCount; Header = pmx.Header.Clone(); ModelInfo = pmx.ModelInfo.Clone(); int count = pmx.VertexList.Count; VertexList.Capacity = count; for (int i = 0; i < count; i++) { VertexList.Add(pmx.VertexList[i].Clone()); } count = pmx.FaceList.Count; FaceList.Capacity = count; for (int j = 0; j < count; j++) { FaceList.Add(pmx.FaceList[j]); } count = pmx.MaterialList.Count; MaterialList.Capacity = count; for (int k = 0; k < count; k++) { MaterialList.Add(pmx.MaterialList[k].Clone()); } count = pmx.BoneList.Count; BoneList.Capacity = count; for (int l = 0; l < count; l++) { BoneList.Add(pmx.BoneList[l].Clone()); } count = pmx.MorphList.Count; MorphList.Capacity = count; for (int m = 0; m < count; m++) { MorphList.Add(pmx.MorphList[m].Clone()); } count = pmx.NodeList.Count; NodeList.Clear(); NodeList.Capacity = count; for (int n = 0; n < count; n++) { NodeList.Add(pmx.NodeList[n].Clone()); if (NodeList[n].SystemNode) { if (NodeList[n].Name == "Root") { RootNode = NodeList[n]; } else if (NodeList[n].Name == "表情") { ExpNode = NodeList[n]; } } } count = pmx.BodyList.Count; BodyList.Capacity = count; for (int num = 0; num < count; num++) { BodyList.Add(pmx.BodyList[num].Clone()); } count = pmx.JointList.Count; JointList.Capacity = count; for (int num2 = 0; num2 < count; num2++) { JointList.Add(pmx.JointList[num2].Clone()); } count = pmx.SoftBodyList.Count; SoftBodyList.Capacity = count; for (int num3 = 0; num3 < count; num3++) { SoftBodyList.Add(pmx.SoftBodyList[num3].Clone()); } }
/// <summary> /// Create a joint to constrain bodies together. This may cause the connected bodies to cease colliding. /// Warning: This function is locked during callbacks. /// </summary> /// <param name="joint">The joint.</param> public void AddJoint(Joint joint) { Debug.Assert(!IsLocked); if (IsLocked) { return; } // Connect to the world list. JointList.Add(joint); // Connect to the bodies' doubly linked lists. joint.EdgeA.Joint = joint; joint.EdgeA.Other = joint.BodyB; joint.EdgeA.Prev = null; joint.EdgeA.Next = joint.BodyA.JointList; if (joint.BodyA.JointList != null) { joint.BodyA.JointList.Prev = joint.EdgeA; } joint.BodyA.JointList = joint.EdgeA; // WIP David if (!joint.IsFixedType()) { joint.EdgeB.Joint = joint; joint.EdgeB.Other = joint.BodyA; joint.EdgeB.Prev = null; joint.EdgeB.Next = joint.BodyB.JointList; if (joint.BodyB.JointList != null) { joint.BodyB.JointList.Prev = joint.EdgeB; } joint.BodyB.JointList = joint.EdgeB; } // WIP David if (!joint.IsFixedType()) { Body bodyA = joint.BodyA; Body bodyB = joint.BodyB; // If the joint prevents collisions, then flag any contacts for filtering. if (joint.CollideConnected == false) { ContactEdge edge = bodyB.ContactList; while (edge != null) { if (edge.Other == bodyA) { // Flag the contact for filtering at the next time step (where either // body is awake). edge.Contact.FlagForFiltering(); } edge = edge.Next; } } } if (JointAdded != null) { JointAdded(joint); } // Note: creating a joint doesn't wake the bodies. }
/// <summary> /// Links the bodies. /// </summary> /// <param name="type">The type of Joint to link with.</param> public void LinkBodies(LinkType type, float min, float max, float springConstant, float dampingConstant) { RevoluteJoint revoluteJoint; PinJoint pinJoint, d; SliderJoint sliderJoint; LinearSpring linearSpring, a; Vector2 midPoint; float midDeltaX; float midDeltaY; for (int i = 0; i < _bodies.Count; i++) { if (i < _bodies.Count - 1) { if (_bodies[i].Position.X < _bodies[i + 1].Position.X) { midDeltaX = Math.Abs(_bodies[i].Position.X - _bodies[i + 1].Position.X) * 0.5f; // find x axis midpoint } else { midDeltaX = (_bodies[i + 1].Position.X - _bodies[i].Position.X) * 0.5f; // find x axis midpoint } if (_bodies[i].Position.Y < _bodies[i + 1].Position.Y) { midDeltaY = Math.Abs(_bodies[i].Position.Y - _bodies[i + 1].Position.Y) * 0.5f; // find x axis midpoint } else { midDeltaY = (_bodies[i + 1].Position.Y - _bodies[i].Position.Y) * 0.5f; // find x axis midpoint } midPoint = new Vector2(_bodies[i].Position.X + midDeltaX, _bodies[i].Position.Y + midDeltaY); // set midPoint switch (type) { case LinkType.RevoluteJoint: revoluteJoint = JointFactory.Instance.CreateRevoluteJoint(_bodies[i], _bodies[i + 1], midPoint); revoluteJoint.BiasFactor = 0.2f; revoluteJoint.Softness = 0.01f; _joints.Add(revoluteJoint); break; case LinkType.LinearSpring: linearSpring = SpringFactory.Instance.CreateLinearSpring(_bodies[i], new Vector2(-_width / 2.0f, 0), _bodies[i + 1], new Vector2(_width / 2.0f, 0), springConstant, dampingConstant); if (i >= 1) { a = (LinearSpring)_springs[i - 1]; linearSpring.RestLength = Vector2.Distance(a.AttachPoint2, linearSpring.AttachPoint1); } _springs.Add(linearSpring); break; case LinkType.PinJoint: pinJoint = JointFactory.Instance.CreatePinJoint(_bodies[i], new Vector2(-_width / 2.0f, 0), _bodies[i + 1], new Vector2(_width / 2.0f, 0)); pinJoint.BiasFactor = 0.2f; pinJoint.Softness = 0.01f; if (i >= 1) { d = (PinJoint)_joints[i - 1]; pinJoint.TargetDistance = Vector2.Distance(d.Anchor2, pinJoint.Anchor1); } _joints.Add(pinJoint); break; case LinkType.SliderJoint: sliderJoint = JointFactory.Instance.CreateSliderJoint(_bodies[i], new Vector2(-_width / 2.0f, 0), _bodies[i + 1], new Vector2(_width / 2.0f, 0), min, max); sliderJoint.BiasFactor = 0.2f; sliderJoint.Softness = 0.01f; _joints.Add(sliderJoint); break; default: //should never get here break; } } } if (_loop) { if (_bodies[0].Position.X < _bodies[_bodies.Count - 1].Position.X) { midDeltaX = Math.Abs(_bodies[0].Position.X - _bodies[_bodies.Count - 1].Position.X) * 0.5f; // find x axis midpoint } else { midDeltaX = (_bodies[_bodies.Count - 1].Position.X - _bodies[0].Position.X) * 0.5f; // find x axis midpoint } if (_bodies[0].Position.Y < _bodies[_bodies.Count - 1].Position.Y) { midDeltaY = Math.Abs(_bodies[0].Position.Y - _bodies[_bodies.Count - 1].Position.Y) * 0.5f; // find x axis midpoint } else { midDeltaY = (_bodies[_bodies.Count - 1].Position.Y - _bodies[0].Position.Y) * 0.5f; // find x axis midpoint } midPoint = new Vector2(_bodies[0].Position.X + midDeltaX, _bodies[0].Position.Y + midDeltaY); // set midPoint switch (type) { case LinkType.RevoluteJoint: revoluteJoint = JointFactory.Instance.CreateRevoluteJoint(_bodies[0], _bodies[_bodies.Count - 1], midPoint); revoluteJoint.BiasFactor = 0.2f; revoluteJoint.Softness = 0.01f; _joints.Add(revoluteJoint); break; case LinkType.LinearSpring: linearSpring = SpringFactory.Instance.CreateLinearSpring(_bodies[0], new Vector2(-_width / 2.0f, 0), _bodies[_bodies.Count - 1], new Vector2(_width / 2.0f, 0), springConstant, dampingConstant); linearSpring.RestLength = _width; _springs.Add(linearSpring); break; case LinkType.PinJoint: pinJoint = JointFactory.Instance.CreatePinJoint(_bodies[0], new Vector2(-_width / 2.0f, 0), _bodies[_bodies.Count - 1], new Vector2(_width / 2.0f, 0)); pinJoint.BiasFactor = 0.2f; pinJoint.Softness = 0.01f; pinJoint.TargetDistance = _width; _joints.Add(pinJoint); break; case LinkType.SliderJoint: sliderJoint = JointFactory.Instance.CreateSliderJoint(_bodies[0], new Vector2(-_width / 2.0f, 0), _bodies[_bodies.Count - 1], new Vector2(_width / 2.0f, 0), min, max); sliderJoint.BiasFactor = 0.2f; sliderJoint.Softness = 0.01f; _joints.Add(sliderJoint); break; default: //should never get here break; } } }
/// <summary> /// Processes the added geometries, springs, joints, bodies and controllers. /// </summary> private void ProcessAddedItems() { //Add any new geometries _tempCount = _geomAddList.Count; for (int i = 0; i < _tempCount; i++) { if (!GeomList.Contains(_geomAddList[i])) { _geomAddList[i].InSimulation = true; GeomList.Add(_geomAddList[i]); //Add the new geometry to the broad phase collider. _broadPhaseCollider.Add(_geomAddList[i]); } } _geomAddList.Clear(); //Add any new bodies _tempCount = _bodyAddList.Count; for (int i = 0; i < _tempCount; i++) { if (!BodyList.Contains(_bodyAddList[i])) { BodyList.Add(_bodyAddList[i]); } } _bodyAddList.Clear(); //Add any new controllers _tempCount = _controllerAddList.Count; for (int i = 0; i < _tempCount; i++) { if (!ControllerList.Contains(_controllerAddList[i])) { ControllerList.Add(_controllerAddList[i]); } } _controllerAddList.Clear(); //Add any new joints _tempCount = _jointAddList.Count; for (int i = 0; i < _tempCount; i++) { if (!JointList.Contains(_jointAddList[i])) { JointList.Add(_jointAddList[i]); } } _jointAddList.Clear(); //Add any new springs _tempCount = _springAddList.Count; for (int i = 0; i < _tempCount; i++) { if (!SpringList.Contains(_springAddList[i])) { SpringList.Add(_springAddList[i]); } } _springAddList.Clear(); }