/// <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; }
/// <summary> /// Rebuild this JelloAttachPoint. /// </summary> /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param> /// <param name="jelloBody">The JelloBody to to be attached to.</param> /// <param name="useBaseShape">Whether to use the JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param> /// <param name="numLegs">Number of JelloPointMass objects to use as "legs" (use 1, 2, or 3).</param> public void Rebuild(Vector2 attachPoint, JelloBody jelloBody, bool useBaseShape = true, int numLegs = 0) { body = jelloBody; transform = body.transform; if (numLegs != 0) { if (numLegs < 0) { numLegs = 1; } if (numLegs > 3) { numLegs = 3; } affectedIndices = new int[numLegs]; } else if (affectedIndices == null || affectedIndices.Length == 0 || affectedIndices.Length > 3) { affectedIndices = new int[2]; //default to 3? } Vector2[] shape = new Vector2[body.Shape.VertexCount]; if (useBaseShape) { for (int i = 0; i < shape.Length; i++) { shape[i] = body.Shape.getVertex(i); } } else { attachPoint = transform.TransformPoint(attachPoint); for (int i = 0; i < shape.Length; i++) { shape[i] = body.getPointMass(i).Position; } } if (affectedIndices.Length == 1) { affectedIndices = JelloShapeTools.GetClosestIndices(attachPoint, shape, 1); scalars = new float[1]; scalars[0] = 1f; } else if (affectedIndices.Length == 2) { Vector2 hit; affectedIndices = JelloShapeTools.FindClosestEdgeOnShape(attachPoint, shape); scalars = new float[2]; JelloVectorTools.getClosestPointOnSegmentSquared(attachPoint, shape[affectedIndices[0]], shape[affectedIndices[1]], out hit, out scalars[1]); scalars[0] = 1 - scalars[1]; } else if (affectedIndices.Length == 3) { Vector2[] shapePerimeter = new Vector2[body.EdgePointMassCount]; if (useBaseShape) { shapePerimeter = body.Shape.EdgeVertices; } else { for (int i = 0; i < shapePerimeter.Length; i++) { shapePerimeter[i] = body.getEdgePointMass(i).Position; } } affectedIndices = JelloShapeTools.FindContainingTriangle(attachPoint, shape, shapePerimeter, body.Shape.Triangles, out scalars); } point = Vector2.zero; for (int i = 0; i < affectedIndices.Length; i++) { point += shape[affectedIndices[i]] * scalars[i]; } if (!useBaseShape) { point = transform.InverseTransformPoint(point); } if (mAttachedTransform != null) { Vector3 newPos = transform.TransformPoint(point); newPos.z = mAttachedTransform.position.z; mAttachedTransform.position = newPos; } }