public static bool hitTriangleAll(Vector3 rayOrigin, Vector3 rayDirection, Vector3[] vertices, int[] triangles, out HitRes minHit) { bool found = false; float minDist = Mathf.Infinity; minHit = default(HitRes); HitRes hit; for (int triOffset = 0; triOffset < triangles.Length; triOffset += 3) { if (hitTriangle(rayOrigin, rayDirection, vertices, triangles, triOffset, out hit) == 0) { continue; } hit.i = triOffset; if (hit.t < minDist) { minDist = hit.t; minHit = hit; found = true; } } return(found); }
public static int hitTriangle(Vector3 rayOrigin, Vector3 rayDirection, Vector3[] triVerts, int[] indices, int indicesOffset, out HitRes hit) { Vector3 edge1 = triVerts[indices[indicesOffset + 1]] - triVerts[indices[indicesOffset + 0]]; Vector3 edge2 = triVerts[indices[indicesOffset + 2]] - triVerts[indices[indicesOffset + 0]]; Vector3 p = Vector3.Cross(rayDirection, edge2); float det = Vector3.Dot(p, edge1); hit = default(HitRes); if (-Mathf.Epsilon < det && det < Mathf.Epsilon) return 0; float rDet = 1.0f / det; Vector3 vT = rayOrigin - triVerts[indices[indicesOffset + 0]]; float u = Vector3.Dot(p, vT) * rDet; if (u < 0f || 1f < u) return 0; Vector3 q = Vector3.Cross(vT, edge1); float v = Vector3.Dot (q, rayDirection) * rDet; if (v < 0f || 1f < (u + v)) return 0; float t = Vector3.Dot(q, edge2) * rDet; hit.u = u; hit.v = v; hit.t = t; return 1; }
/// <summary> /// Collects the data from a current hit session and creates a new ExpData object for the saved CSV /// </summary> /// <param name="hit"></param> private void CollectExpData(HitRes hit) { expResults.Add(new ExpData() { ParticipantId = nameField.text, BallNumber = _currBallNumber, BallType = _currBallType, BallSpeed = _currBallSpeed, BallResult = (int)hit, EventTime = globalClockString, TimerTime = clockString, GamePoints = gamePoints, Level = playerLevel }); }
/// <summary> /// Audio for a missed ball and starts a new ball /// </summary> /// <returns></returns> private IEnumerator NextBallMissed(HitRes hitRes) { prevHits[_currBallNumber % 6] = 0; //Randomly, 1/3 of the time, play a random lose voice sound effect if (UnityEngine.Random.Range(0, 2) == 0) { int rand = UnityEngine.Random.Range(9, 13); _audioSources[rand].Play(); yield return(new WaitForSeconds(_audioSources[rand].clip.length)); } if (IsCorrectionHints) { yield return(ReadHitCorrection(hitRes)); } yield return(NextBallComing()); }
/// <summary> /// Starts the next ball and adds to the total gamePoints /// </summary> /// <param name="hitres"></param> /// <param name="pointsToAdd"></param> private void StartNextBall(HitRes hitres) { if (playerReady && !canPressStartButton) { if (newBallOk) { newBallOk = false; Debug.Log("Sending Ball"); ExperimentLog.Log("Sending Ball"); if (_currBallNumber != -1) { if (GoalScript.ExpBallWin) { GoalScript.ExpBallWin = false; hitres = HitRes.goal; } gamePoints += hitres == HitRes.miss ? 0 : (int)hitres - 1;//The points correlate to the hitres CollectExpData(hitres); } Destroy(_currentBall); if (_currBallNumber != -1) { StartCoroutine((hitres != HitRes.miss && hitres != HitRes.tipped) ? NextBallHit() : NextBallMissed(hitres)); } else { StartCoroutine(NextBallComing()); } } } else { Debug.LogWarning("Exp Not Started"); ExperimentLog.Log("Exp Not Started", tag: "warn"); } }
public static int hitTriangle(Vector3 rayOrigin, Vector3 rayDirection, Vector3[] triVerts, int[] indices, int indicesOffset, ref HitRes hit) { Vector3 edge1 = triVerts[indices[indicesOffset + 1]] - triVerts[indices[indicesOffset + 0]]; Vector3 edge2 = triVerts[indices[indicesOffset + 2]] - triVerts[indices[indicesOffset + 0]]; Vector3 p = Vector3.Cross(rayDirection, edge2); float det = Vector3.Dot(p, edge1); if (-Mathf.Epsilon < det && det < Mathf.Epsilon) { return(0); } float rDet = 1.0f / det; Vector3 vT = rayOrigin - triVerts[indices[indicesOffset + 0]]; float u = Vector3.Dot(p, vT) * rDet; if (u < 0f || 1f < u) { return(0); } Vector3 q = Vector3.Cross(vT, edge1); float v = Vector3.Dot(q, rayDirection) * rDet; if (v < 0f || 1f < (u + v)) { return(0); } float t = Vector3.Dot(q, edge2) * rDet; hit.u = u; hit.v = v; hit.t = t; return(1); }
public static bool hitTriangleAll(Vector3 rayOrigin, Vector3 rayDirection, Vector3[] vertices, int[] triangles, out HitRes minHit) { bool found = false; float minDist = Mathf.Infinity; minHit = default(HitRes); HitRes hit; for (int triOffset = 0; triOffset < triangles.Length; triOffset+=3) { if (hitTriangle(rayOrigin, rayDirection, vertices, triangles, triOffset, out hit) == 0) continue; hit.i = triOffset; if (hit.t < minDist) { minDist = hit.t; minHit = hit; found = true; } } return found; }
/// <summary> /// Plays audio for a correction hint based on a hit result of the last ball /// This is a Coroutine menthod and by nature is async /// </summary> /// <param name="hitRes">The results of the last ball</param> /// <returns></returns> private IEnumerator ReadHitCorrection(HitRes hitRes) { var snapShotBatPos = endSnapshot.batPos; var snapShotBallPos = endSnapshot.ballPos; float absDist = Math.Abs(snapShotBatPos.x - snapShotBallPos.x); if (hitRes == HitRes.tipped) { if (CollisionSnapshot.ballPos.x < CollisionSnapshot.batPos.x - 5) { tippedAudio.Play(); yield return(new WaitForSeconds(tippedAudio.clip.length)); ExperimentLog.Log("Tipped to the left"); reachLeft.Play(); yield return(new WaitForSeconds(reachLeft.clip.length)); } else if (CollisionSnapshot.ballPos.x > CollisionSnapshot.batPos.x + 5) { tippedAudio.Play(); yield return(new WaitForSeconds(tippedAudio.clip.length)); reachRight.Play(); yield return(new WaitForSeconds(reachRight.clip.length)); ExperimentLog.Log("Tipped to the right"); } else if (CollisionSnapshot.ballPos.z < CollisionSnapshot.batPos.z) { ExperimentLog.Log("You hit the ball backward"); backwardAudio.Play(); yield return(new WaitForSeconds(backwardAudio.clip.length)); } } else if (absDist < 10) { if (snapShotBatPos.z > snapShotBallPos.z) { //Reached too far forward too soon. tooForward.Play(); yield return(new WaitForSeconds(tooForward.clip.length)); } else { //Reached too far back tooBack.Play(); yield return(new WaitForSeconds(tooBack.clip.length)); } } else if (snapShotBallPos.x > 0 && snapShotBallPos.x > snapShotBatPos.x) { //Reach further to the right float distOff = snapShotBallPos.x - snapShotBatPos.x; reachRight.Play(); yield return(new WaitForSeconds(reachRight.clip.length)); StartCoroutine(numberSpeech.PlayFancyNumberAudio((int)distOff)); yield return(new WaitForSeconds(2.5f)); } else if (snapShotBallPos.x > 0 && snapShotBallPos.x < snapShotBatPos.x) { //Too far to the right float distOff = snapShotBatPos.x - snapShotBallPos.x; tooRight.Play(); yield return(new WaitForSeconds(tooRight.clip.length)); StartCoroutine(numberSpeech.PlayFancyNumberAudio((int)distOff)); yield return(new WaitForSeconds(2.5f)); } else if (snapShotBallPos.x < 0 && snapShotBallPos.x > snapShotBatPos.x) { //Too far to the left float distOff = Math.Abs(snapShotBatPos.x - snapShotBallPos.x); tooLeft.Play(); yield return(new WaitForSeconds(tooLeft.clip.length)); StartCoroutine(numberSpeech.PlayFancyNumberAudio((int)distOff)); yield return(new WaitForSeconds(2.5f)); } else if (snapShotBallPos.x < 0 && snapShotBallPos.x < snapShotBatPos.x) { //Reach futher to the left float distOff = Math.Abs(snapShotBallPos.x - snapShotBatPos.x); reachLeft.Play(); yield return(new WaitForSeconds(reachLeft.clip.length)); StartCoroutine(numberSpeech.PlayFancyNumberAudio((int)distOff)); yield return(new WaitForSeconds(2.5f)); } else if (snapShotBallPos.x == 0) { //Put it right in the middle middleAudio.Play(); yield return(new WaitForSeconds(middleAudio.clip.length)); } yield break; }