// private List<Vector3> allDeltaPositionOnes = new List<Vector3>();
//private List<Vector3> allDeltaPositionTwos = new List<Vector3>();
//private List<BSM.Quaternion> allDeltaOrientations = new List<BSM.Quaternion>();
//private List<BSM.Quaternion> allDeltaOrientationOnes = new List<BSM.Quaternion>();
// private List<BSM.Quaternion> allDeltaOrientationTwos = new List<BSM.Quaternion>();
floatstretchStiffness=0.1f;
floatbendStiffness=0.1f;
floatstretchStiffness=0.9f;
floatbendStiffness=0.9f;
[Tooltip("Whether to solve both constraints in bilateral interleaving order. Naive order is used when false.")]
[SerializeField]boolexecuteInBilateralOrder=false;//!< Whether to solve both constraints in bilateral interleaving order. Naive order is used when false.
...
...
@@ -36,6 +39,8 @@ public class ConstraintSolvingStep : MonoBehaviour
publicGameObjectspherePrefab;//This is for choosing a Prefab for the sphere element. One can directly gain this in Robins code from: Assets/Guidewire_Assets/Prefabs
publicGameObjectcylinderPrefab;//This is for choosing a Prefab for the cylinder element. One can directly gain this in Robins code from: Assets/Guidewire_Assets/Prefabs
privateintspheresCount;//This variable is used to store the number of spheres in the guidewire, so the script can keep knowledge on how many spheres were created
privateGameObject[]spheres;//This array is used to store references to the sphere game objects in the guidewire. //This array is used to store references to the sphere game objects in the guidewire.
privateGameObject[]cylinders;//-''-
//Declare several private variables (in order to later use the other script/ a path....)
//get several components/ scripts from a GameObject called Simulation. This GameObject holds all the relevant scripts, among others the SimulationLoop, that is responsible for organizing and calling all parts of the simulation.
//Find file path in order to be able to log information later when running it as a Unity standalone application and not being able to rely on the console in Unity anymore.
@@ -32,22 +47,29 @@ public class CreationScript : MonoBehaviour
voidFixedUpdate()
{
//SavePositionsToFile();
if(Time.time>initialCheckDelay)
{
//After an inital delay (in order to give the system enough time to actually realize the displacement and not kill the simulation before even applying the first displacement, the velocity is checked. (if the magntidude is below a treshhold, then another displacement is applied, or if all wanted displacements have been applied, the application is quit)
CheckVelocityDifference();
}
}
//This code segment is responsible for creating and positioning the spheres and cylinders
//this is the guidewire creation method, it calls the spheres and cylinders elements and creates them with an aquidistant spacing in a row.
//The starting position is chosen by the Vector in line 70, also the
publicvoidCreateGuidewire(intnumberElements)
{
spheres=newGameObject[numberElements];
cylinders=newGameObject[numberElements-1];
//Here we use GetComponent to recieve the value of the variable rodElementLength that is stored in the SimulationLoop script. As this variable needs to be private, we use a getter Method and therefore also call this instead of calling the variable directly.
@@ -55,16 +77,17 @@ public class CreationScript : MonoBehaviour
GameObjectcylinder=Instantiate(cylinderPrefab);
cylinder.layer=6;
cylinder.transform.parent=this.transform;
cylinders[i]=cylinder;
}
}
spheresCount=numberElements;
simulationLoop.SetSpheres(spheres);
simulationLoop.SetCylinders(cylinders);
}
//Here I save the positions of the spheres to a .txt file. The file path has to be adapted to the local network for the file one wants to save the positons to
publicvoidSavePositionsToFile()
{
...
...
@@ -83,9 +106,63 @@ public class CreationScript : MonoBehaviour
@@ -7,17 +8,19 @@ public class MeshImporter3 : MonoBehaviour
{
voidAwake()
{
//Path for the log file, in order to see if everything worked as expected. If e.g. no mesh can be seen in a GUI test, then check the log, if the path to the mesh was found and maybe the positioning is off (not in the view of the camera)...
//Here we initialize the mesh path variables, for this we need a way to parse the name from the command line environment that gets simulated by the python script.
//if run via the python loop, it should be like this
//If one runs via the python loop, it should be like this: (so here we initialize transformation vectors to zero), if the objective is to test it in the scene itself, set the position manually below by commenting it out and placing it correctly).
Vector3position=Vector3.zero;
Vector3scale=Vector3.one;
Vector3rotation=Vector3.zero;
...
...
@@ -27,9 +30,11 @@ public class MeshImporter3 : MonoBehaviour
//Vector3 scale = new Vector3(27.2f, 27.2f, 27.2f);
//Vector3 rotation = new Vector3(0f, -86.6f, 0f);
//Iterate through command line arguments to set the above initialized mesh paths and transformations for the positioning of the mesh.
//Adding a second .obj file is possible, as a second mesh if the goal is to not allow collisions from the outside and from the inside. Then the second mesh is the same mesh as the first but with its normals inverted.
for(inti=0;i<args.Length;i++)
{
if(args[i]=="-objPath")
if(args[i]=="-objPath")//This checks if the argument is for object path, so for the position, scale, paths... and everytime it finds the name, it takes the next values as the argument.
{
meshPath=args[i+1];
}
...
...
@@ -39,16 +44,19 @@ public class MeshImporter3 : MonoBehaviour
}
elseif(args[i]=="-position")
{
//Split the argument into components and create a vector
@@ -108,11 +116,14 @@ public class MeshImporter3 : MonoBehaviour
return;
}
//This creates a new GameObject and sets its transformation properties: (these are defined either above or parsed from the outside loop)
GameObjectobj=newGameObject(primaryMesh.name);
obj.transform.position=position;
obj.transform.localScale=scale;
obj.transform.eulerAngles=rotation;
//Add the MeshFilter component and assign the primary mesh, do the same below for the MeshRenderer component below. Then the material is loaded, in order for the artery to have the typical optic and seem realistic
MeshFilterfilter=obj.AddComponent<MeshFilter>();
filter.mesh=primaryMesh;
...
...
@@ -128,6 +139,7 @@ public class MeshImporter3 : MonoBehaviour
Debug.LogError("Failed to load material");
}
//Now add a MeshCollider and the primary mesh, in order to enable collision detection between guidewire and artery that can be resolved in the constraint solving.
@@ -137,10 +149,12 @@ public class MeshImporter3 : MonoBehaviour
secondaryCollider.sharedMesh=secondaryMesh;
}
//Rigidbody component needs to be added as well in order to enable the collision detection, use isKinematic on, for all colliding objects, then the collision data will be output and not corrected by the Unity engine itself
Rigidbodyrb=obj.AddComponent<Rigidbody>();
rb.useGravity=false;
rb.isKinematic=true;
//adding the correct layer for the layer matrix to have the correct effect