/// <summary> /// Get the first anchor point. /// Point will be in local space if a JelloJoint.TransformA is not null, otherwise it will be in global space. /// </summary> /// <returns>The first anchor point.</returns> /// <param name="useBaseShape">Whether to use JelloBody.Shape instead of its JelloPointMass objects. Has no effect if JelloJoint.bodyA is null</param> public Vector2 GetAnchorPointA(bool useBaseShape) { Vector2 point = globalAnchorA; if(mTransformA != null) { if(bodyA != null) { point = Vector2.zero; if(affectedIndicesA != null && affectedIndicesA.Length > 0) { if(useBaseShape) { for(int i = 0; i < affectedIndicesA.Length; i++) point += bodyA.Shape.getVertex(affectedIndicesA[i]) * scalarsA[i]; } else { for(int i = 0; i < affectedIndicesA.Length; i++) point += bodyA.getPointMass(affectedIndicesA[i]).Position * scalarsA[i]; point = TransformA.InverseTransformPoint(point); } } } else { point = localAnchorA; } } return point; }
public void Write(TProtocol oprot) { oprot.IncrementRecursionDepth(); try { TStruct struc = new TStruct("CausesCollision_args"); oprot.WriteStructBegin(struc); TField field = new TField(); if (ColliderA != null && __isset.colliderA) { field.Name = "colliderA"; field.Type = TType.Struct; field.ID = 1; oprot.WriteFieldBegin(field); ColliderA.Write(oprot); oprot.WriteFieldEnd(); } if (TransformA != null && __isset.transformA) { field.Name = "transformA"; field.Type = TType.Struct; field.ID = 2; oprot.WriteFieldBegin(field); TransformA.Write(oprot); oprot.WriteFieldEnd(); } if (ColliderB != null && __isset.colliderB) { field.Name = "colliderB"; field.Type = TType.Struct; field.ID = 3; oprot.WriteFieldBegin(field); ColliderB.Write(oprot); oprot.WriteFieldEnd(); } if (TransformB != null && __isset.transformB) { field.Name = "transformB"; field.Type = TType.Struct; field.ID = 4; oprot.WriteFieldBegin(field); TransformB.Write(oprot); oprot.WriteFieldEnd(); } oprot.WriteFieldStop(); oprot.WriteStructEnd(); } finally { oprot.DecrementRecursionDepth(); } }
public override string ToString() { StringBuilder __sb = new StringBuilder("CausesCollision_args("); bool __first = true; if (ColliderA != null && __isset.colliderA) { if (!__first) { __sb.Append(", "); } __first = false; __sb.Append("ColliderA: "); __sb.Append(ColliderA == null ? "<null>" : ColliderA.ToString()); } if (TransformA != null && __isset.transformA) { if (!__first) { __sb.Append(", "); } __first = false; __sb.Append("TransformA: "); __sb.Append(TransformA == null ? "<null>" : TransformA.ToString()); } if (ColliderB != null && __isset.colliderB) { if (!__first) { __sb.Append(", "); } __first = false; __sb.Append("ColliderB: "); __sb.Append(ColliderB == null ? "<null>" : ColliderB.ToString()); } if (TransformB != null && __isset.transformB) { if (!__first) { __sb.Append(", "); } __first = false; __sb.Append("TransformB: "); __sb.Append(TransformB == null ? "<null>" : TransformB.ToString()); } __sb.Append(")"); return(__sb.ToString()); }
/// <summary> /// Set up the anchor. /// </summary> /// <returns>The anchor's position.</returns> /// <param name="xform">The Transform of the anchor.</param> /// <param name="anchor">The anchor point, local to the given Transform.</param> /// <param name="isAnchorA">Whether to set up the first anchor instead of the second.</param> /// <param name="useBaseShape">Whether to use JelloBody.Shape instead of its JelloPointMass objects. Has no effect if no JelloBody is attached to the Transform.</param> /// <param name="numPointsAffected">The number of PointMasses affected / affecting this anchor. Has no effect if no JelloBody is attached to the Transform.</param> public Vector2 SetupAnchor(Transform xform, Vector2 anchor, bool isAnchorA, bool useBaseShape, int numPointsAffected = 0) { if(isAnchorA) TransformA = xform; else TransformB = xform; if(xform == null) { if(isAnchorA) { affectedIndicesA = null; scalarsA = null; if(TransformB != null) { globalAnchorA = TransformB.TransformPoint(GetAnchorPointB(useBaseShape)); return globalAnchorA; } else { return Vector2.zero; } } else { affectedIndicesB = null; scalarsB = null; if(TransformA != null) { globalAnchorB = TransformA.TransformPoint(GetAnchorPointA(useBaseShape)); return globalAnchorB; } else { return Vector2.zero; } } //return Vector2.zero; } Vector2 returnPosition = anchor; if(numPointsAffected < 1) numPointsAffected = 2; else if(numPointsAffected > 3) numPointsAffected = 3; if(isAnchorA) { localAnchorA = anchor; if(bodyA != null) { Vector2[] shape = new Vector2[bodyA.Shape.VertexCount]; if(useBaseShape) //TODO tighten this up a bit { for(int i = 0; i < shape.Length; i++) shape[i] = bodyA.Shape.getVertex(i); } else { for(int i = 0; i < bodyA.PointMassCount; i++) shape[i] = bodyA.getPointMass(i).Position; } Vector2 point = localAnchorA; if(!useBaseShape) point = xform.TransformPoint(point); if(numPointsAffected == 1) { affectedIndicesA = JelloShapeTools.GetClosestIndices(point, shape, 1); scalarsA = new float[1]; scalarsA[0] = 1f; returnPosition = shape[affectedIndicesA[0]]; } else if(numPointsAffected == 2) { Vector2 hit; affectedIndicesA = JelloShapeTools.FindClosestEdgeOnShape(point, shape); scalarsA = new float[2]; JelloVectorTools.getClosestPointOnSegmentSquared (point, shape[affectedIndicesA[0]], shape[affectedIndicesA[1]], out hit, out scalarsA[1]); scalarsA[0] = 1 - scalarsA[1]; returnPosition = shape[affectedIndicesA[0]] * scalarsA[0] + shape[affectedIndicesA[1]] * scalarsA[1]; } else if(numPointsAffected == 3) { Vector2[] shapePerimeter = new Vector2[bodyA.EdgePointMassCount]; if(useBaseShape) { shapePerimeter = bodyA.Shape.EdgeVertices; } else { for(int i = 0; i < shapePerimeter.Length; i++) shapePerimeter[i] = bodyA.getEdgePointMass(i).Position; } affectedIndicesA = JelloShapeTools.FindContainingTriangle(point, shape, shapePerimeter, bodyA.Shape.Triangles, out scalarsA); returnPosition = shape[affectedIndicesA[0]] * scalarsA[0] + shape[affectedIndicesA[1]] * scalarsA[1] + shape[affectedIndicesA[2]] * scalarsA[2]; } if(!useBaseShape) returnPosition = mTransformA.InverseTransformPoint(returnPosition); } } else { localAnchorB = anchor; if(bodyB != null) { Vector2[] shape = new Vector2[bodyB.Shape.VertexCount]; if(useBaseShape) { for(int i = 0; i < shape.Length; i++) shape[i] = bodyB.Shape.getVertex(i); } else { for(int i = 0; i < bodyB.PointMassCount; i++) shape[i] = bodyB.getPointMass(i).Position; } Vector2 point = localAnchorB; if(!useBaseShape) point = xform.TransformPoint(point); if(numPointsAffected == 1) { affectedIndicesB = JelloShapeTools.GetClosestIndices(point, shape, 1); scalarsB = new float[1]; scalarsB[0] = 1f; returnPosition = shape[affectedIndicesB[0]] * scalarsB[0]; } else if(numPointsAffected == 2) { Vector2 hit; // affectedIndicesB = JelloShapeTools.GetClosestIndices(point, shape, 2); affectedIndicesB = JelloShapeTools.FindClosestEdgeOnShape(point, shape); scalarsB = new float[2]; JelloVectorTools.getClosestPointOnSegmentSquared (point, shape[affectedIndicesB[0]], shape[affectedIndicesB[1]], out hit, out scalarsB[1]); scalarsB[0] = 1 - scalarsB[1]; returnPosition = shape[affectedIndicesB[0]] * scalarsB[0] + shape[affectedIndicesB[1]] * scalarsB[1]; } else if(numPointsAffected == 3) { Vector2[] shapePerimeter = new Vector2[bodyB.EdgePointMassCount]; if(useBaseShape) { shapePerimeter = bodyB.Shape.EdgeVertices; } else { for(int i = 0; i < shapePerimeter.Length; i++) shapePerimeter[i] = bodyB.getEdgePointMass(i).Position; } affectedIndicesB = JelloShapeTools.FindContainingTriangle(point, shape, shapePerimeter, bodyB.Shape.Triangles, out scalarsB); returnPosition = shape[affectedIndicesB[0]] * scalarsB[0] + shape[affectedIndicesB[1]] * scalarsB[1] + shape[affectedIndicesB[2]] * scalarsB[2]; } if(!useBaseShape) returnPosition = mTransformB.InverseTransformPoint(returnPosition);} } return returnPosition; }
public Vector3 TransformDirection(Vector3 v) => TransformB.RotateToLocal(TransformA.RotateToWorld(v));
public Vector3 TransformPos(Vector3 v) => TransformB.ToLocalSpace(TransformA.ToWorldSpace(v));