/** * Stops the object's movement. */ public void StopObjMov(ManageObjs.Obj curObj, int i) { float endTime = (Time.time - trials[curTrial - 1].trialStart); ttcActualSim = (endTime - hideTime); if (config.debugging) { Debug.Log("TTC (simulator): " + ttcActualSim + " Valid when end is 0,0,0"); } // Hide the object if it hasn't been hidden already if (curObj.objVisible) { HideObj(movingObjs[i]); curObj.objVisible = false; if (config.feedbackType == 1) { pmVisible = false; } } // Set the object to inactive and decrement numObjs curObj.objActive = false; numObjs = numObjs - 1; }
public float rotationSpeedZ; // the speed at which the object should rotate around Z axis /** * The constructor for the ObjData object. */ public ObjData(ManageObjs.Obj obj) { this.objNum = obj.objNum; this.objType = obj.objType; this.objScale = obj.objScale; this.startPos = obj.startPos; this.endPos = obj.endPos; this.distTraveled = obj.dist; this.velocity = obj.velocity; this.timeVisible = obj.timeVisible; this.rotationSpeedX = obj.rotationSpeedX; this.rotationSpeedX = obj.rotationSpeedY; this.rotationSpeedX = obj.rotationSpeedZ; }
/** * Moves the object in a linear path. */ public void LinearMotionMov(ManageObjs.Obj curObj, int i) { float fracTraveled = curObj.stepCounter / curObj.finalStep; movingObjs[i].position = Vector3.Lerp(startPosArr[i], endPosArr[i], fracTraveled); movingObjs[i].Rotate(curObj.rotationSpeedX, curObj.rotationSpeedY, curObj.rotationSpeedZ); curObj.stepCounter++; // If the object has traveled the entire distance, it should no longer be moving if (fracTraveled >= 1) { StopObjMov(curObj, i); } }
/** * Move each object in the current trial based on the object's parameters. */ void MoveObjsByStep() { ManageObjs.Obj[] objs = trials[curTrial - 1].objects; for (int i = 0; i < objs.Length; i++) { ManageObjs.Obj curObj = objs[i]; // Once an object has become inactive we no longer need to move it if (curObj.objActive) { // Hide the object once it has been visible for its defined timeVisible if (curObj.stepCounter > curObj.stepHidden && curObj.objVisible) { hideTime = (Time.time - trials[curTrial - 1].trialStart); if (config.debugging) { Debug.Log("Time Hidden: " + hideTime); } HideObj(movingObjs[i]); curObj.objVisible = false; if (config.feedbackType == 1) { pmVisible = false; } } // Move the object forward another step if (curObj.customMot) { CustomMotionMov(curObj, i, cusMotArray[i], rotations[i]); } // Custom motion movement else { LinearMotionMov(curObj, i); } // Linear motion movement } } // Once numObjs reaches 0, all objects have finished moving and the repeating method can be canceled if (numObjs == 0) { CancelInvoke("MoveObjsByStep"); } }
/** * Moves the object in a custom motion path. */ public void CustomMotionMov(ManageObjs.Obj curObj, int i, List <Vector3> coordinateArray, List <Vector3> rotationArray) { float duration = curObj.customDur; // Be careful, cusMotArrayIndex refers to the positions array index. i refers to the trial object. float totalFrames = duration * rate; float framesPerPoint = totalFrames / (numCustomCoordinates[i] - 1); float fracTraveled = curObj.stepCounter / framesPerPoint; if (fracTraveled >= 1) // Move onto the next position in the array. { cusMotArrayIndex[i]++; curObj.stepCounter = 0; // Reset the counter to 0 for the next segment. fracTraveled = 0; } // Once we hit the second to last element of the array, it should no longer be moving if (cusMotArrayIndex[i] + 2 > numCustomCoordinates[i]) { StopObjMov(curObj, i); } else // Move the object forward another step { movingObjs[i].position = Vector3.Lerp(coordinateArray[cusMotArrayIndex[i]], coordinateArray[cusMotArrayIndex[i] + 1], fracTraveled); if (cusMotArrayIndex[i] + 1 < numCustomCoordinates[i]) { // Use the next rotation for current position's rotation. Vector3 currentAngle = new Vector3( Mathf.LerpAngle(rotationArray[cusMotArrayIndex[i]].x, rotationArray[cusMotArrayIndex[i] + 1].x, fracTraveled), Mathf.LerpAngle(rotationArray[cusMotArrayIndex[i]].y, rotationArray[cusMotArrayIndex[i] + 1].y, fracTraveled), Mathf.LerpAngle(rotationArray[cusMotArrayIndex[i]].z, rotationArray[cusMotArrayIndex[i] + 1].z, fracTraveled)); movingObjs[i].localEulerAngles = currentAngle; } curObj.stepCounter++; } }
/** * Initialize the current trial. */ public void InitializeTrial() { // Check that we still have more trials to run if (curTrial < this.trials.Length) { // Stop displaying the feedback text uiManager.ResetFeedbackMsg(); Debug.Log("Trial " + trials[curTrial].trialNum + ": " + trials[curTrial].trialName + " started"); // Get the current trial from the data array ManageTrials.Trial trial = trials[curTrial]; // Initialize all of the arrays for the objects in the trial numObjs = trial.objects.Length; objs = new Transform[numObjs]; startPosArr = new Vector3[numObjs]; endPosArr = new Vector3[numObjs]; movingObjs = new Transform[numObjs]; cusMotArray = new List <Vector3> [numObjs]; rotations = new List <Vector3> [numObjs]; cusMotArrayIndex = new int[numObjs]; numCustomCoordinates = new int[numObjs]; if (trial.playSound) { // Play sounds for the trial List <AudioClip> trialClips = audioClips[curTrial]; List <float> trialAudioTime = audioDelays[curTrial]; for (int tcIndex = 0; tcIndex < trialClips.Count; tcIndex++) { AudioSource audioSource = audioSourceObject.AddComponent <AudioSource>(); Debug.Log("current trial index: " + curTrial); audioSource.clip = trialClips[tcIndex]; StartCoroutine(PlaySoundAfterDelay(audioSource, trialAudioTime[tcIndex])); } } for (int i = 0; i < numObjs; i++) { ManageObjs.Obj curObj = trial.objects[i]; // Set current frame to 0. curFrame = 0; // Set custom motion array to empty. cusMotArray[i] = new List <Vector3>(); // Set custom rotations array to empty. rotations[i] = new List <Vector3>(); if (curObj.customMot) // Check for custom motion configurations. { // Set custom motion array index to 0. cusMotArrayIndex[i] = 0; // Set custom motion array (called positions) and custom rotations array (called rotations). ReadCustomPositions("Assets/Trials/Custom_Motion_Positions/" + curObj.customFile, i); } Debug.Log("custom motion array for index " + i + ": "); for (int y = 0; y < numCustomCoordinates[i]; y++) { Debug.Log(y + ": " + cusMotArray[i][y]); } // Set the object prefab that will be displayed GameObject newObj = Resources.Load("Objects\\" + curObj.objType) as GameObject; objs[i] = newObj.transform; // Set the scale of the object objs[i].localScale = new Vector3(curObj.objScale[0], curObj.objScale[1], curObj.objScale[2]); // Set the object rotation. if (curObj.customMot && (objs[i].localEulerAngles != rotations[i][0])) { Debug.Log("WARNING! Object rotation is not equal to initial rotation in custom motion file. Using the rotation of first frame in " + curObj.customFile); objs[i].localEulerAngles = rotations[i][0]; } if (!curObj.customMot) { objs[i].localEulerAngles = new Vector3(curObj.objRot[0], curObj.objRot[1], curObj.objRot[2]); } if (config.debugging) { Debug.Log("rotation: " + objs[i].localEulerAngles.x + " " + objs[i].localEulerAngles.y + " " + objs[i].localEulerAngles.z); } /** * Check that offsets are merely directions and don't have a magnitude. If so, correct them. */ if (Math.Abs(curObj.offsetX) > 1) { Debug.Log("WARNING! Magnitude of x offset direction should not be greater than 1!"); curObj.offsetX = curObj.offsetX / Math.Abs(curObj.offsetX); } if (Math.Abs(curObj.offsetY) > 1) { Debug.Log("WARNING! Magnitude of y offset direction should not be greater than 1!"); curObj.offsetY = curObj.offsetY / Math.Abs(curObj.offsetY); } if (Math.Abs(curObj.offsetZ) > 1) { Debug.Log("WARNING! Magnitude of z offset direction should not be greater than 1!"); curObj.offsetZ = curObj.offsetZ / Math.Abs(curObj.offsetZ); } // Set offset directions. Vector3 offsetDirections = new Vector3(curObj.offsetX, curObj.offsetY, curObj.offsetZ); // Set initial start and end vectors. Vector3 startVector = new Vector3(curObj.startPos[0], curObj.startPos[1], curObj.startPos[2]); Vector3 endVector = new Vector3(curObj.endPos[0], curObj.endPos[1], curObj.endPos[2]); if (curObj.customMot && (startVector != cusMotArray[i][0] || endVector != cusMotArray[i][numCustomCoordinates[i] - 1])) { Debug.Log("WARNING! Custom motion initial and final positions in " + curObj.customFile + " are not equal to startPos and endPos. Using initial and final positions in " + curObj.customFile); } // Get size of model Renderer render = objs[i].GetComponent <Renderer>(); Vector3 objSize = render.bounds.size; if (config.cameraLock) { startPosArr[i] = new Vector3(startVector.x, startVector.y, startVector.z); // Got rid of adding camera height because was doing it twice. endPosArr[i] = new Vector3(endVector.x, endVector.y, endVector.z); // Calculate camera lock offsets if (curObj.customMot) { CameraLockOffset(cusMotArray[i], objSize, offsetDirections); } else { List <Vector3> startEndList = new List <Vector3>(); startEndList.Add(startPosArr[i]); startEndList.Add(endPosArr[i]); List <Vector3> positions = CameraLockOffset(startEndList, objSize, offsetDirections); startPosArr[i] = positions[0]; endPosArr[i] = positions[1]; } } else { // Add offsets for non camera-locked trials. // Initialize startPosArr and endPosArr with a copy of the object's current start and end positions, respectively. startPosArr[i] = startVector; endPosArr[i] = endVector; // Calculate offsets if (curObj.customMot) { Offset(cusMotArray[i], objSize, offsetDirections); } else { List <Vector3> startEndList = new List <Vector3>(); startEndList.Add(startPosArr[i]); startEndList.Add(endPosArr[i]); List <Vector3> positions = Offset(startEndList, objSize, offsetDirections); startPosArr[i] = positions[0]; endPosArr[i] = positions[1]; } } // Calculate the distance that the object must travel curObj.dist = Vector3.Distance((Vector3)startPosArr[i], (Vector3)endPosArr[i]); if (config.debugging) { Debug.Log("Start Pos: " + startPosArr[i].x + " " + startPosArr[i].y + " " + startPosArr[i].z); } if (config.debugging) { Debug.Log("End Pos: " + endPosArr[i].x + " " + endPosArr[i].y + " " + endPosArr[i].z); } // Instantiate the object so that it's visible if (curObj.customMot) { movingObjs[i] = Instantiate(objs[i], cusMotArray[i][0], objs[i].localRotation); // Important to make sure these are correct variables. } else { movingObjs[i] = Instantiate(objs[i], startPosArr[i], objs[i].localRotation); // Important to make sure these are correct variables. } curObj.objVisible = true; curObj.objActive = true; if (config.feedbackType == 1) { pmVisible = true; } // Set the variables that need to be used in the repeating method to move the objects curObj.step = curObj.velocity * stepSize; curObj.finalStep = ((curObj.dist / curObj.velocity) * rate); //calculate theoretical ttcActual ttcActual = ((curObj.startPos[2] - (curObj.timeVisible * curObj.velocity)) / curObj.velocity); if (config.debugging) { Debug.Log("TTC: " + ttcActual); } // If timeVisible is negative, the object should never disappear if (curObj.timeVisible < 0) { curObj.stepHidden = -1; // set stepHidden to be a step value that can never occur so that HideObject will never be called } else { curObj.stepHidden = curObj.timeVisible * rate; } } // Set the start time of this trial so that it can be recorded by the data manager trial.trialStart = Time.time; curTrial++; // Call the repeating methods to move the objects and track head position float delay = (1.0f / rate); InvokeRepeating("MoveObjsByStep", 0.0f, delay); InvokeRepeating("Tracking", 0.0f, delay); // Set the trial as running isRunning = true; } else { // Do this check and then increment the trial num so data is only saved once if (curTrial == trials.Length) { expComplete = true; if (config.debugging) { Debug.Log("Experiment complete"); } uiManager.ShowMessage("Experiment complete"); dataManager.Save(false); curTrial++; } } }