protected Joint(JointDef def) { Debug.Assert(def.bodyA != def.bodyB); _type = def.type; _bodyA = def.bodyA; _bodyB = def.bodyB; _collideConnected = def.collideConnected; _userData = def.userData; _edgeA = new JointEdge(); _edgeB = new JointEdge(); }
internal static Joint Create(JointDef def) { Joint joint = null; switch (def.type) { case JointType.Distance: { joint = new DistanceJoint((DistanceJointDef)def); } break; case JointType.Mouse: { joint = new MouseJoint((MouseJointDef)def); } break; case JointType.Prismatic: { joint = new PrismaticJoint((PrismaticJointDef)def); } break; case JointType.Revolute: { joint = new RevoluteJoint((RevoluteJointDef)def); } break; case JointType.Pulley: { joint = new PulleyJoint((PulleyJointDef)def); } break; case JointType.Gear: { joint = new GearJoint((GearJointDef)def); } break; case JointType.Line: { joint = new LineJoint((LineJointDef)def); } break; case JointType.Weld: { joint = new WeldJoint((WeldJointDef)def); } break; case JointType.Friction: { joint = new FrictionJoint((FrictionJointDef)def); } break; case JointType.MaxDistance: { joint = new MaxDistanceJoint((MaxDistanceJointDef)def); } break; default: Debug.Assert(false); break; } return joint; }
/// Create a joint to rain bodies together. No reference to the definition /// is retained. This may cause the connected bodies to cease colliding. /// @warning This function is locked during callbacks. public Joint CreateJoint(JointDef def) { Debug.Assert(!IsLocked); if (IsLocked) { return(null); } Joint j = Joint.Create(def); // Connect to the world list. j._prev = null; j._next = _jointList; if (_jointList != null) { _jointList._prev = j; } _jointList = j; ++_jointCount; // Connect to the bodies' doubly linked lists. j._edgeA.Joint = j; j._edgeA.Other = j._bodyB; j._edgeA.Prev = null; j._edgeA.Next = j._bodyA._jointList; if (j._bodyA._jointList != null) { j._bodyA._jointList.Prev = j._edgeA; } j._bodyA._jointList = j._edgeA; j._edgeB.Joint = j; j._edgeB.Other = j._bodyA; j._edgeB.Prev = null; j._edgeB.Next = j._bodyB._jointList; if (j._bodyB._jointList != null) { j._bodyB._jointList.Prev = j._edgeB; } j._bodyB._jointList = j._edgeB; Body bodyA = def.bodyA; Body bodyB = def.bodyB; bool staticA = bodyA.GetType() == BodyType.Static; bool staticB = bodyB.GetType() == BodyType.Static; // If the joint prevents collisions, then flag any contacts for filtering. if (def.collideConnected == false) { ContactEdge edge = bodyB.GetContactList(); 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; } } // Note: creating a joint doesn't wake the bodies. return(j); }
/// <summary> /// Create a joint to rain bodies together. No reference to the definition /// is retained. This may cause the connected bodies to cease colliding. /// @warning This function is locked during callbacks. /// </summary> /// <param name="def"></param> /// <returns></returns> public Joint CreateJoint(JointDef def) { Debug.Assert(!IsLocked); if (IsLocked) { return null; } Joint j = Joint.Create(def); // Connect to the world list. j._prev = null; j._next = _jointList; if (_jointList != null) { _jointList._prev = j; } _jointList = j; ++_jointCount; // Connect to the bodies' doubly linked lists. j._edgeA.Joint = j; j._edgeA.Other = j._bodyB; j._edgeA.Prev = null; j._edgeA.Next = j._bodyA._jointList; if (j._bodyA._jointList != null) j._bodyA._jointList.Prev = j._edgeA; j._bodyA._jointList = j._edgeA; j._edgeB.Joint = j; j._edgeB.Other = j._bodyA; j._edgeB.Prev = null; j._edgeB.Next = j._bodyB._jointList; if (j._bodyB._jointList != null) j._bodyB._jointList.Prev = j._edgeB; j._bodyB._jointList = j._edgeB; Body bodyA = def.bodyA; Body bodyB = def.bodyB; bool staticA = bodyA.GetType() == BodyType.Static; bool staticB = bodyB.GetType() == BodyType.Static; // If the joint prevents collisions, then flag any contacts for filtering. if (def.collideConnected == false) { ContactEdge edge = bodyB.GetContactList(); 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; } } // Note: creating a joint doesn't wake the bodies. return j; }
public static Joint SetJointWithReflection(this IJointable ithis, string instName, JointDef jointDef) { Joint result = null; Type t = ithis.GetType(); int index = -1; FieldInfo fi = t.GetField(instName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (fi == null) { Match m = lastDigits.Match(instName); if (m.Groups.Count > 2 && t.GetField(instName) == null) { instName = m.Groups[1].Value; index = int.Parse(m.Groups[2].Value, System.Globalization.NumberStyles.None); fi = t.GetField(instName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); } } if (fi != null) { Type ft = fi.FieldType; // apply attributes System.Attribute[] attrs = System.Attribute.GetCustomAttributes(fi); // reflection foreach (System.Attribute attr in attrs) { if (jointDef is DistanceJointDef && attr is DistanceJointAttribute) { ((DistanceJointAttribute)attr).ApplyAttribtues((DistanceJointDef)jointDef); } else if (jointDef is GearJointDef && attr is GearJointAttribute) { ((GearJointAttribute)attr).ApplyAttribtues((GearJointDef)jointDef); } else if (jointDef is LineJointDef && attr is LineJointAttribute) { ((LineJointAttribute)attr).ApplyAttribtues((LineJointDef)jointDef); } else if (jointDef is PrismaticJointDef && attr is PrismaticJointAttribute) { ((PrismaticJointAttribute)attr).ApplyAttribtues((PrismaticJointDef)jointDef); } else if (jointDef is PulleyJointDef && attr is PulleyJointAttribute) { ((PulleyJointAttribute)attr).ApplyAttribtues((PulleyJointDef)jointDef); } else if (jointDef is RevoluteJointDef && attr is RevoluteJointAttribute) { ((RevoluteJointAttribute)attr).ApplyAttribtues((RevoluteJointDef)jointDef); } } result = ithis.VScreen.world.CreateJoint(jointDef); if (ft.IsArray) { object array = fi.GetValue(ithis); Type elementType = ft.GetElementType(); if (array == null) { int arrayLength = GetJointArrayLength(ithis, instName); array = Array.CreateInstance(elementType, arrayLength); fi.SetValue(ithis, array); } MethodInfo mi = array.GetType().GetMethod("SetValue", new Type[] { elementType, index.GetType() }); mi.Invoke(array, new object[] { result, index }); } else if (typeof(System.Collections.ICollection).IsAssignableFrom(ft)) { Type[] genTypes = ft.GetGenericArguments(); if (genTypes.Length == 1) // only support single type generics (eg List<>) for now { Type gt = genTypes[0]; object collection = fi.GetValue(ithis); if (collection == null) // ensure list created { ConstructorInfo ci = ft.GetConstructor(new Type[] { }); collection = ci.Invoke(new object[] { }); fi.SetValue(ithis, collection); } PropertyInfo cm = collection.GetType().GetProperty("Count"); int cnt = (int)cm.GetValue(collection, new object[] { }); // pad with nulls if needs to skip indexes (order is based on flash depth, not index) while (index > cnt) { MethodInfo mia = collection.GetType().GetMethod("Add"); mia.Invoke(collection, new object[] { null }); cnt = (int)cm.GetValue(collection, new object[] { }); } if (index < cnt) { MethodInfo mia = collection.GetType().GetMethod("RemoveAt"); mia.Invoke(collection, new object[] { index }); } MethodInfo mi = collection.GetType().GetMethod("Insert"); mi.Invoke(collection, new object[] { index, result }); } } else if (ft.Equals(typeof(Joint)) || ft.IsSubclassOf(typeof(Joint))) { fi.SetValue(ithis, result); } else { throw new ArgumentException("Not supported field type. " + ft.ToString() + " " + instName); } } else { result = ithis.VScreen.world.CreateJoint(jointDef); } return result; }
internal static Joint Create(JointDef def) { Joint joint = null; switch (def.type) { case JointType.Distance: { joint = new DistanceJoint((DistanceJointDef)def); } break; case JointType.Mouse: { joint = new MouseJoint((MouseJointDef)def); } break; case JointType.Prismatic: { joint = new PrismaticJoint((PrismaticJointDef)def); } break; case JointType.Revolute: { joint = new RevoluteJoint((RevoluteJointDef)def); } break; case JointType.Pulley: { joint = new PulleyJoint((PulleyJointDef)def); } break; case JointType.Gear: { joint = new GearJoint((GearJointDef)def); } break; case JointType.Line: { joint = new LineJoint((LineJointDef)def); } break; case JointType.Weld: { joint = new WeldJoint((WeldJointDef)def); } break; case JointType.Friction: { joint = new FrictionJoint((FrictionJointDef)def); } break; case JointType.MaxDistance: { joint = new MaxDistanceJoint((MaxDistanceJointDef)def); } break; default: Debug.Assert(false); break; } return(joint); }