protected virtual void processSmartSetShape(List<int[]> indexPairs, JelloClosedShape shape, ShapeSettingOptions options = ShapeSettingOptions.None, SmartShapeSettingOptions smartOptions = SmartShapeSettingOptions.None) { bool rebuildJoints = (smartOptions & SmartShapeSettingOptions.RebuildInvalidatedJoints) == SmartShapeSettingOptions.RebuildInvalidatedJoints; bool rebuildAttachPoints = (smartOptions & SmartShapeSettingOptions.RebuildInvalidatedAttachPoints) == SmartShapeSettingOptions.RebuildInvalidatedAttachPoints; if(mJoints != null) { //work with joints first... for(int i = 0; i < mJoints.Length; i++) { JelloJoint joint = mJoints[i]; if(joint.bodyA == this) { for(int a = 0; a < joint.affectedIndicesA.Length; a++) { //Vector2 point = joint .GetAnchorPointA(true); bool found = false; for(int b = 0; b < indexPairs.Count; b++) { if(joint.affectedIndicesA[a] == indexPairs[b][1]) { joint.affectedIndicesA[a] = indexPairs[b][0]; found = true; break; } } if(!found) { if(rebuildJoints) { //rebuild the joint.. Vector2 pos = mBaseShape.getVertex(joint.affectedIndicesA[a]); Vector2[] fullShape = new Vector2[shape.VertexCount]; for(int c = 0; c < shape.VertexCount; c++) fullShape[c] = shape.getVertex(c); int[] closestIndices = JelloShapeTools.GetClosestIndices(pos, fullShape, joint.affectedIndicesA.Length); bool assignedClosest = false; //check if any of the indices are already in use for(int c = 0; c < closestIndices.Length; c++) { //joint.affectedindicesA[a] is the current one... //compare unchecked indices against their old position and compare checked indices against their new position. for(int d = 0; d < joint.affectedIndicesA.Length; d++) { //skip the index that we are currently working with. if(d == a) continue; if(d < a)//this index has been updated to the new shape so compare against indexPairs[index][0] { if(indexPairs[closestIndices[c]][0] == joint.affectedIndicesA[d])//in use continue; } else//d must be greater than a, so so this index is untouched and we should compare against indexPairs[index][1] { if(indexPairs[closestIndices[c]][1] == joint.affectedIndicesA[d])//in use continue; } //made it past the early continues, so the index must not be in use. joint.affectedIndicesA[a] = closestIndices[c]; assignedClosest = true; break; } if(assignedClosest) break; } //dont forget to rebuild the joint!!! Vector2[] affectedVertices = new Vector2[joint.affectedIndicesA.Length]; for(int q = 0; q < affectedVertices.Length; q++) affectedVertices[q] = shape.getVertex (joint.affectedIndicesA[q]); joint.RebuildAnchor(joint.localAnchorA, true, true, joint.affectedIndicesA, affectedVertices); } else { //this joint is invalid and will be removed in the clear invalid subcomponents method. mJoints[i] = null; break; } } } } else if(joint.bodyB == this) { for(int a = 0; a < joint.affectedIndicesB.Length; a++) { bool found = false; for(int b = 0; b < indexPairs.Count; b++) { if(joint.affectedIndicesB[a] == indexPairs[b][1]) { joint.affectedIndicesB[a] = indexPairs[b][0]; found = true; break; } } if(!found) { if(rebuildJoints) { //rebuild the joint.. Vector2 pos = mBaseShape.getVertex(joint.affectedIndicesB[a]); Vector2[] fullShape = new Vector2[shape.VertexCount]; for(int c = 0; c < shape.VertexCount; c++) fullShape[c] = shape.getVertex(c); int[] closestIndices = JelloShapeTools.GetClosestIndices(pos, fullShape, joint.affectedIndicesB.Length); bool assignedClosest = false; //check if any of the indices are already in use for(int c = 0; c < closestIndices.Length; c++) { //joint.affectedindicesA[a] is the current one... //compare unchecked indices against their old position and compare checked indices against their new position. for(int d = 0; d < joint.affectedIndicesB.Length; d++) { //skip the index that we are currently working with. if(d == a) continue; if(d < a)//this index has been updated to the new shape so compare against indexPairs[index][0] { if(indexPairs[closestIndices[c]][0] == joint.affectedIndicesB[d])//in use continue; } else//d must be greater than a, so so this index is untouched and we should compare against indexPairs[index][1] { if(indexPairs[closestIndices[c]][1] == joint.affectedIndicesB[d])//in use continue; } //made it past the early continues, so the index must not be in use. joint.affectedIndicesB[a] = closestIndices[c]; assignedClosest = true; break; } if(assignedClosest) break; } //dont forget to rebuild the joint!!! Vector2[] affectedVertices = new Vector2[joint.affectedIndicesB.Length]; for(int q = 0; q < affectedVertices.Length; q++) affectedVertices[q] = shape.getVertex(joint.affectedIndicesB[q]); joint.RebuildAnchor(joint.localAnchorB, false, true, joint.affectedIndicesB, affectedVertices); } else { //this joint is invalid and will be removed in the clear invalid subcomponents method. mJoints[i] = null; break; } } } } } } if(mAttachPoints != null) { //handle attach points now for(int i = 0; i < mAttachPoints.Length; i++) { JelloAttachPoint attachPoint = mAttachPoints[i]; for(int a = 0; a < attachPoint.affectedIndices.Length; a++) { bool found = false; for(int b = 0; b < indexPairs.Count; b++) { if(attachPoint.affectedIndices[a] == indexPairs[b][1]) { attachPoint.affectedIndices[a] = indexPairs[b][0]; found = true; break; } } if(!found) { if(rebuildAttachPoints) { //rebuild the attach point.. Vector2 pos = mBaseShape.getVertex(attachPoint.affectedIndices[a]); Vector2[] fullShape = new Vector2[shape.VertexCount]; for(int c = 0; c < shape.VertexCount; c++) fullShape[c] = shape.getVertex(c); int[] closestIndices = JelloShapeTools.GetClosestIndices(pos, fullShape, attachPoint.affectedIndices.Length); bool assignedClosest = false; //check if any of the indices are already in use for(int c = 0; c < closestIndices.Length; c++) { //joint.affectedindicesA[a] is the current one... //compare unchecked indices against their old position and compare checked indices against their new position. for(int d = 0; d < attachPoint.affectedIndices.Length; d++) { //skip the index that we are currently working with. if(d == a) continue; if(d < a)//this index has been updated to the new shape so compare against indexPairs[index][0] { if(indexPairs[closestIndices[c]][0] == attachPoint.affectedIndices[d])//in use continue; } else//d must be greater than a, so so this index is untouched and we should compare against indexPairs[index][1] { if(indexPairs[closestIndices[c]][1] == attachPoint.affectedIndices[d])//in use continue; } //made it past the early continues, so the index must not be in use. attachPoint.affectedIndices[a] = closestIndices[c]; assignedClosest = true; break; } if(assignedClosest) break; } //all legs have been updated, not rebuild the attach point. attachPoint.Rebuild(attachPoint.point, this, attachPoint.affectedIndices, true); } else { //this joint is invalid and will be removed in the clear invalid subcomponents method. mAttachPoints[i] = null; break; } } } } } }
/// <summary> /// At the given index, smartly remove the internal JelloPointMass from this JelloBody and the internal vertex from JelloBody.Shape.InternalVertices. /// Smartly means that most edits made to the JelloBody will be retained and is done via the JelloBody.smartSetShape() method. /// </summary> /// <param name="index">The index of internal JelloPointMass to be removed.</param> /// <param name="recenterBaseShape">Whether to recenter JelloBody.Shape.</param> /// <param name="options">ShapeSettingOptions on how Subcomponents should be modified as the JelloPointMass and JelloClosedShape vertex is removed.</param> /// <param name="smartOptions">SmartShapeSettingOptions on how Subcomponents should be modified as the JelloPointMass and JelloClosedShape vertex is removed.</param> public virtual void smartRemoveInternalPointMass(int index, bool recenterBaseShape, ShapeSettingOptions options = ShapeSettingOptions.None, SmartShapeSettingOptions smartOptions = SmartShapeSettingOptions.None) { if(index < 0 && index >= mInternalPointMasses.Length) return; Vector2[] tempItnernalVertices = new Vector2[mBaseShape.InternalVertexCount - 1]; int a = 0; for(int i = 0; i < mBaseShape.InternalVertexCount; i++) { if(i != index) { tempItnernalVertices[a] = mBaseShape.InternalVertices[i]; a++; } } JelloClosedShape newShape = new JelloClosedShape(mBaseShape.EdgeVertices, tempItnernalVertices, recenterBaseShape); smartSetShape(newShape, options, smartOptions); }
/// <summary> /// Smartly sets JelloBody.Shape to a new JelloClosedShape object. /// Make sure your JelloShape does not contain any duplicate points ( Use JelloShapeTools.RemoveDuplicates() ). /// This method will attemp to retain as much information as possible from the previous shape. /// The subcomponents that will be processed in order to try and retained are JelloPointMass, JelloJoint, JelloAttachPoint, and JelloSpring. /// </summary> /// <param name="shape">New JelloClosedShape.</param> /// <param name="options">ShapeSettingOptions for setting the JelloClosedShape.</param> /// <param name="smartOptions">SmartShapeSettingOptions for setting the JelloClosedShape.</param> public virtual void smartSetShape(JelloClosedShape shape, ShapeSettingOptions options = ShapeSettingOptions.None, SmartShapeSettingOptions smartOptions = SmartShapeSettingOptions.None) { //no need to run smart method if no shape yet assigned. if(mBaseShape == null) { setShape(shape, options); return; } setComponentReferences(); //find common points between the old shape and the new one. List<int[]> indexPairs = new List<int[]>(); //start with the edges...??? for(int a = 0; a < shape.EdgeVertexCount; a++) { bool found = false; for(int i = 0; i < mBaseShape.EdgeVertexCount; i++) { if(mBaseShape.EdgeVertices[i] == shape.EdgeVertices[a]) { indexPairs.Add (new int[2]{a, i}); found = true; break; } } if(!found) indexPairs.Add (new int[2]{a, -1}); } for(int a = 0; a < shape.InternalVertexCount; a++) { bool found = false; for(int i = 0; i < mBaseShape.InternalVertexCount; i++) { if(mBaseShape.InternalVertices[i] == shape.InternalVertices[a]) { indexPairs.Add (new int[2]{a, i}); found = true; break; } } if(!found) indexPairs.Add (new int[2]{a, -1}); } bool movePointMasses = (options & ShapeSettingOptions.MovePointMasses) == ShapeSettingOptions.MovePointMasses; //reconfigure point masses JelloPointMass[] tempPointMasses = new JelloPointMass[shape.EdgeVertexCount]; for(int i = 0; i < shape.EdgeVertexCount; i++) { //this is a new point, create a point mass here if(indexPairs[i][1] == -1) { Vector2 pos; if(movePointMasses) pos = myTransform.TransformPoint(shape.EdgeVertices[indexPairs[i][0]]); else pos = Position; tempPointMasses[i] = new JelloPointMass(Mass, pos, this, false); } else//this point exists from the old shape, move that point mass into this index. { tempPointMasses[i] = mEdgePointMasses[indexPairs[i][1]]; } } mEdgePointMasses = tempPointMasses; tempPointMasses = new JelloPointMass[shape.InternalVertexCount]; for(int i = 0; i < shape.InternalVertexCount; i++) { //this is a new point, create a point mass here if(indexPairs[i + shape.EdgeVertexCount][1] == -1) { Vector2 pos; if(movePointMasses) pos = myTransform.TransformPoint(shape.InternalVertices[indexPairs[i + shape.EdgeVertexCount][0]]); else pos = Position; tempPointMasses[i] = new JelloPointMass(Mass, pos, this, false); } else//this point exists from the old shape, move that point mass into this index. { tempPointMasses[i] = mInternalPointMasses[indexPairs[i + shape.EdgeVertexCount][1]]; } } mInternalPointMasses = tempPointMasses; pivotOffset = JelloShapeTools.FindCenter(shape.EdgeVertices); //offset index pairs for internal points for(int i = 0; i < shape.InternalVertexCount; i++) { indexPairs[shape.EdgeVertexCount + i][0] += shape.EdgeVertexCount; indexPairs[shape.EdgeVertexCount + i][1] += mBaseShape.EdgeVertexCount; } // //TODO remove this? it seems a bit redundant... // for(int i = 0; i < mEdgePointMasses.Length; i++) // mEdgePointMasses[i].body = this; // for(int i = 0; i < mInternalPointMasses.Length; i++) // mInternalPointMasses[i].body = this; processSmartSetShape(indexPairs, shape, options, smartOptions); ClearInvalidSubComponents(); //this is joints and attach points.... mBaseShape = shape; }
/// <summary> /// Add an internal JelloPointMass to this JelloBody. /// This will also add an internal vertex to JelloBody.Shape.InternalVertices. /// Smartly means that most edits made to the JelloBody will be retained and is done via the JelloBody.smartSetShape() method. /// </summary> /// <param name="pointMass">The new JelloPointMass to add.</param> /// <param name="recenterBaseShape">Whether to recenter JelloBody.Shape.</param> /// <param name="options">ShapeSettingOptions on how Subcomponents should be modified as the JelloPointMass and JelloClosedShape vertex is added .</param> /// <param name="smartOptions">SmartShapeSettingOptions options on how Subcomponents should be modified as the JelloPointMass and JelloClosedShape vertex is added.</param> public void smartAddInternalPointMass(JelloPointMass pointMass, bool recenterBaseShape, ShapeSettingOptions options = ShapeSettingOptions.None, SmartShapeSettingOptions smartOptions = SmartShapeSettingOptions.None) { if(mBaseShape == null) return; JelloClosedShape newShape = new JelloClosedShape(mBaseShape.EdgeVertices, mBaseShape.InternalVertices, false); if(!newShape.addInternalVertex(pointMass.LocalPosition)) return; newShape.finish(recenterBaseShape); smartSetShape(newShape, options, smartOptions); mInternalPointMasses[mInternalPointMasses.Length - 1] = pointMass; }
public override void smartSetShape (JelloClosedShape shape, ShapeSettingOptions options = ShapeSettingOptions.None, SmartShapeSettingOptions smartOptions = SmartShapeSettingOptions.None) { base.smartSetShape (shape, options, smartOptions); mNormalList = new Vector2[mEdgePointMasses.Length]; mEdgeLengthList = new float[mEdgePointMasses.Length]; }
protected override void processSmartSetShape(List<int[]> indexPairs, JelloClosedShape shape, ShapeSettingOptions options, SmartShapeSettingOptions smartOptions = SmartShapeSettingOptions.None) { base.processSmartSetShape (indexPairs, shape, options, smartOptions); List<int[]> indexPairsQueue = new List<int[]>(); List<JelloSpring> tempSprings = new List<JelloSpring>(); if((options & ShapeSettingOptions.RebuildEdgeSprings) == ShapeSettingOptions.RebuildEdgeSprings) { clearEdgeSprings(); buildEdgeSprings(); } else if((options & ShapeSettingOptions.ClearEdgeSprings) == ShapeSettingOptions.ClearEdgeSprings) { clearEdgeSprings(); } else { //find the first common point to the two shapes int index = -1; for(int i = 0; i < shape.EdgeVertexCount; i++) { if(indexPairs[i][1] != -1) { index = i; break; } } if(index == -1)//in this case, there are no common points to this shape at all. we can just create new edge springs... { clearEdgeSprings(); buildEdgeSprings(); } else { while(indexPairsQueue.Count < shape.EdgeVertexCount) { if(index >= shape.EdgeVertexCount) index = 0; indexPairsQueue.Add (indexPairs[index]); index++; } //see if edge is intact... for(int i = 0; i < shape.EdgeVertexCount; i++)//using edge point mass length, because we only want the edge indices { int next = i + 1 < shape.EdgeVertexCount ? i + 1 : 0; //check if this edge is the same as the last. if(indexPairsQueue[i][1] != -1) //old doesnt equal -1 { //then the next should equal this plus 1 or 0 if full wrap around? if(indexPairsQueue[next][1] == (indexPairsQueue[i][1] + 1 < mBaseShape.EdgeVertexCount ? indexPairsQueue[i][1] + 1 : 0)) //our edge is preserved from the old shape, lets move our old spring into place... { bool found = false; JelloSpring spring = null; //first check the expected position. if(indexPairsQueue[i][1] < mEdgeSprings.Length) spring = mEdgeSprings[indexPairsQueue[i][1]]; if(spring != null && spring.pointMassA == indexPairsQueue[i][1] && spring.pointMassB == indexPairsQueue[next][1]) found = true; //if not in the expected position, check the rest of the positions... if(!found) { for(int a = 0; a < mEdgeSprings.Length; a++) { spring = mEdgeSprings[a]; if(spring.pointMassA == indexPairsQueue[i][1] && spring.pointMassB == indexPairsQueue[next][1]) { found = true; break; } } } if(!found)//the spring could not be found, create a new one. { //float dist = Vector2.Distance(shape.EdgeVertices[indexPairsQueue[i][1]], shape.EdgeVertices[indexPairsQueue[next][1]]); spring = new JelloSpring(indexPairsQueue[i][1], indexPairsQueue[next][1], 0f, DefaultEdgeSpringStiffness, DefaultEdgeSpringDamping); } spring.pointMassA = indexPairsQueue[i][0]; spring.pointMassB = indexPairsQueue[next][0]; tempSprings.Add(spring); } else { if(indexPairsQueue[next][1] == -1)//this is a new point. { //lets check if there is a spring here... bool found = false; //first check the expected position. JelloSpring spring = null; if(indexPairsQueue[i][1] < mEdgeSprings.Length) spring = mEdgeSprings[indexPairsQueue[i][1]]; if(spring != null && (spring.pointMassA == indexPairsQueue[i][1] && spring.pointMassB == (spring.pointMassA == mBaseShape.EdgeVertexCount - 1 ? spring.pointMassA + 1 : 0))) { found = true; } //we didnt find the spring in the expected position, lets look through the rest of the springs. if(!found) { for(int a = 0; a < mEdgeSprings.Length; a++) { spring = mEdgeSprings[a]; if(spring.pointMassA == indexPairsQueue[i][1] && spring.pointMassB == (spring.pointMassA == mBaseShape.EdgeVertexCount - 1 ? spring.pointMassA + 1 : 0)) { found = true; break; } } } //no old spring found, lets create one... if(!found) { spring = new JelloSpring(indexPairsQueue[i][0], indexPairsQueue[next][0], 0f, DefaultEdgeSpringStiffness, DefaultEdgeSpringDamping); } spring.pointMassA = indexPairsQueue[i][0]; spring.pointMassB = indexPairsQueue[next][0]; //spring.length = Vector2.Distance(shape.EdgeVertices[spring.pointMassA], shape.EdgeVertices[spring.pointMassB]); float multiplier = spring.lengthMultiplier; //first assing spring to this one... tempSprings.Add (spring); //int nextnext = next + 1 < shape.EdgeVertexCount ? next + 1 : 0; //now look through the rest of the points until i find a common point and create those springs in the image of this one... for(int a = next; a < shape.EdgeVertexCount; a++) { int nextnext = a + 1 < shape.EdgeVertexCount ? a + 1 : 0; spring = new JelloSpring(indexPairsQueue[a][0], indexPairsQueue[nextnext][0], 0f, spring.stiffness, spring.damping); //spring.length = Vector2.Distance(shape.EdgeVertices[spring.pointMassA], shape.EdgeVertices[spring.pointMassB]); spring.lengthMultiplier = multiplier; tempSprings.Add (spring); i++; if(indexPairsQueue[nextnext][1] != -1) break; } } else//this is a vertex preserved from the old shape... in otherwords, there was a point mass deleted here. { //lets check if there is a spring here... bool found = false; //first check the expected position. JelloSpring spring = null; if(indexPairsQueue[i][1] < mEdgeSprings.Length) spring = mEdgeSprings[indexPairsQueue[i][1]]; if(spring != null && (spring.pointMassA == indexPairsQueue[i][1] && spring.pointMassB == (spring.pointMassA == mBaseShape.EdgeVertexCount - 1 ? spring.pointMassA + 1 : 0))) { found = true; } //we didnt find the spring in the expected position, lets look through the rest of the springs. if(!found) { for(int a = 0; a < mEdgeSprings.Length; a++) { spring = mEdgeSprings[a]; if(spring.pointMassA == indexPairsQueue[i][1] && spring.pointMassB == (spring.pointMassA == mBaseShape.EdgeVertexCount - 1 ? spring.pointMassA + 1 : 0)) { found = true; break; } } } //no old spring found, lets create one... if(!found) { spring = new JelloSpring(indexPairsQueue[i][0], indexPairsQueue[next][0], 0f, DefaultEdgeSpringStiffness, DefaultEdgeSpringDamping); } spring.pointMassA = indexPairsQueue[i][0]; spring.pointMassB = indexPairsQueue[next][0]; //spring.length = Vector2.Distance(shape.EdgeVertices[spring.pointMassA], shape.EdgeVertices[spring.pointMassB]); tempSprings.Add (spring); } } } else { JelloSpring spring = new JelloSpring(indexPairsQueue[i][0], indexPairsQueue[next][0], 0f, DefaultEdgeSpringStiffness, DefaultEdgeSpringDamping); //spring.length = Vector2.Distance(shape.EdgeVertices[spring.pointMassA], shape.EdgeVertices[spring.pointMassB]); tempSprings.Add (spring); } } mEdgeSprings = new JelloSpring[tempSprings.Count]; int indexOffset = 0; for(int i = 0; i < tempSprings.Count; i++) { if(tempSprings[i].pointMassA == 0) { indexOffset = i; break; } } JelloSpring[] tempArray = new JelloSpring[tempSprings.Count]; for(int i = 0; i < tempArray.Length; i++) { int a = i + indexOffset; if(a >= tempArray.Length) a -= tempArray.Length; tempArray[i] = tempSprings[a]; } clearEdgeSprings(); addSprings(tempArray, ref mEdgeSprings); } } if((options & ShapeSettingOptions.RebuildInternalSprings) == ShapeSettingOptions.RebuildInternalSprings) { clearInternalSprings(); BuildInternalSprings(); } else if((options & ShapeSettingOptions.ClearInternalSprings) == ShapeSettingOptions.ClearInternalSprings) { clearInternalSprings(); } else if(mInternalSprings.Length > 0) { //now handle internal springs int[] tris = shape.Triangles; tempSprings.Clear(); for(int i = 0; i < tris.Length; i+=3) { for(int t = 0; t < 3; t++) { int r = t + 1 < 3 ? t + 1 : 0; if(tris[ i + t ] < shape.EdgeVertexCount && tris[ i + r] < shape.EdgeVertexCount) //dont build edge springs { if(tris[ i + t ] != 0 && tris[ i + r ] != 0) { if(Mathf.Abs( tris[ i + t ] - tris[ i + r ] ) == 1) { continue; } } else if(tris[ i + t ] == shape.EdgeVertexCount - 1 || tris[ i + r ] == shape.EdgeVertexCount - 1 || tris[ i + t ] == 1 || tris[ i + t ] == 1) { continue; } } bool exists = false; for(int a = 0; a < tempSprings.Count; a++) { if((tris[i + t] == tempSprings[a].pointMassA && tris[i + r] == tempSprings[a].pointMassB) || (tris[i + t] == tempSprings[a].pointMassB && tris[i + r] == tempSprings[a].pointMassA)) { exists = true; break; } } if(exists) continue; else tempSprings.Add ( new JelloSpring ( tris[i + t], tris[i + r], 0f, mDefaultInternalSpringK, mDefaultInternalSpringDamp ) ); } } //now compare our new internal springs to our old internal springs... for(int i = 0; i < tempSprings.Count; i++) { JelloSpring spring = tempSprings[i]; int pairA = -1; int pairB = -1; for(int a = 0; a < indexPairs.Count; a++) { if(indexPairs[a][0] == spring.pointMassA) pairA = a; if(indexPairs[a][0] == spring.pointMassB) pairB = a; if(pairA != -1 && pairB != -1) break; } if(pairA == -1 || pairB == -1) { //this shouldnt be possible continue; } //check if there is an old point assosiated with each spring end point if(indexPairs[pairA][1] != -1 && indexPairs[pairB][1] != -1) { JelloSpring oldSpring; for(int a = 0; a < mInternalSprings.Length; a++) { oldSpring = mInternalSprings[a]; if((oldSpring.pointMassA == indexPairs[pairA][1] && oldSpring.pointMassB == indexPairs[pairB][1]) || (oldSpring.pointMassB == indexPairs[pairA][1] && oldSpring.pointMassA == indexPairs[pairB][1])) { spring.damping = oldSpring.damping; spring.lengthMultiplier = oldSpring.lengthMultiplier; spring.stiffness = oldSpring.stiffness; } } } } //now set our new internal springs. clearInternalSprings(); if(tempSprings.Count > 0) addSprings(tempSprings.ToArray(), ref mInternalSprings); } if((options & ShapeSettingOptions.ClearCustomSprings) == ShapeSettingOptions.ClearCustomSprings) { clearCustomSprings(); } else { tempSprings.Clear(); bool rebuildCustomSprings = (smartOptions & SmartShapeSettingOptions.RebuildInvalidatedCustomSprings) == SmartShapeSettingOptions.RebuildInvalidatedCustomSprings; //now handle custom springs for(int i = 0; i < mCustomSprings.Length; i++) { JelloSpring spring = mCustomSprings[i]; int indexA = -1; int indexB = -1; for(int a = 0; a < indexPairs.Count; a++) { if(spring.pointMassA == indexPairs[a][1]) indexA = indexPairs[a][0]; if(spring.pointMassB == indexPairs[a][1]) indexB = indexPairs[a][0]; if(indexA != -1 && indexB != -1) { break; } } //here if(indexA == -1 || indexB == -1) { if(rebuildCustomSprings) { Vector2[] fullShape = new Vector2[shape.VertexCount]; for(int c = 0; c < shape.VertexCount; c++) fullShape[c] = shape.getVertex(c); if(indexA == -1) { //rebuild the spring Vector2 pos = mBaseShape.getVertex(spring.pointMassA); int[] closestIndices = JelloShapeTools.GetClosestIndices(pos, fullShape, 2); //check if any of the indices are already in use for(int c = 0; c < closestIndices.Length; c++) { //already in use by index b if(indexB == closestIndices[c]) continue; indexA = closestIndices[c]; break; } } if(indexB == -1) { //rebuild the spring Vector2 pos = mBaseShape.getVertex(spring.pointMassB); int[] closestIndices = JelloShapeTools.GetClosestIndices(pos, fullShape, 2); //check if any of the indices are already in use for(int c = 0; c < closestIndices.Length; c++) { //already in use by index b if(indexA == closestIndices[c]) continue; indexB = closestIndices[c]; break; } } } else { continue; } } spring.pointMassA = indexA; spring.pointMassB = indexB; tempSprings.Add(spring); } clearCustomSprings(); if(tempSprings.Count > 0) addSprings(tempSprings.ToArray(), ref mCustomSprings); } }
public override void smartSetShape(JelloClosedShape shape, ShapeSettingOptions options, SmartShapeSettingOptions smartOptions = SmartShapeSettingOptions.None) { base.smartSetShape (shape, options, smartOptions); }
public override void smartSetShape(JelloClosedShape shape, ShapeSettingOptions options = ShapeSettingOptions.None, SmartShapeSettingOptions smartOptions = SmartShapeSettingOptions.None) { base.smartSetShape (shape, options, smartOptions); mNormalList = new Vector2[mEdgePointMasses.Length]; mEdgeLengthList = new float[mEdgePointMasses.Length]; }