public void Solve() { if (this.upperArm == null || this.forearm == null || this.hand == null || this.elbow == null || this.target == null) { return; } if (!Application.isPlaying && this.debug) { this.upperArm.localRotation = Quaternion.identity; this.forearm.localRotation = Quaternion.identity; this.hand.localRotation = Quaternion.identity; } float d = 1f; if (this.RightSide) { d = -1f; } Vector3 forward = Vector3.Lerp(this.upperArm.up * d, this.target.position - this.upperArm.position, this.BlendOn); Vector3 upwards = Vector3.Lerp(this.upperArm.forward * d, this.elbow.position - this.upperArm.position, this.BlendOn); this.upperArm.rotation = Quaternion.LookRotation(forward, upwards); this.upperArm.Rotate(this.uppperArm_OffsetRotation); Vector3 b = Vector3.Cross(this.elbow.position - this.upperArm.position, this.forearm.position - this.upperArm.position); this.upperArm_Length = Vector3.Distance(this.upperArm.position, this.forearm.position); this.forearm_Length = Vector3.Distance(this.forearm.position, this.hand.position); this.arm_Length = this.upperArm_Length + this.forearm_Length; this.targetDistance = Vector3.Distance(this.upperArm.position, this.target.position); this.targetDistance = Mathf.Min(this.targetDistance, this.arm_Length - this.arm_Length * 0.001f); this.adyacent = (this.upperArm_Length * this.upperArm_Length - this.forearm_Length * this.forearm_Length + this.targetDistance * this.targetDistance) / (2f * this.targetDistance); this.angle = Mathf.Acos(Mathf.Clamp(this.adyacent / this.upperArm_Length, -1f, 1f)) * 57.29578f; Vector3 axis = Vector3.Lerp(this.forearm.position - this.upperArm.position, b, this.BlendOn); this.upperArm.RotateAround(this.upperArm.position, axis, -this.angle * this.BlendOn); if (this.debug) { Debug.DrawRay(this.forearm.position, this.forearm.up * d, Color.blue); Debug.DrawRay(this.forearm.position, -this.forearm.right, Color.green); } Vector3 forward2 = Vector3.Lerp(this.forearm.up * d, this.target.position - this.forearm.position, this.BlendOn); Vector3 upwards2 = Vector3.Lerp(-this.forearm.right, b, this.BlendOn); this.forearm.rotation = Quaternion.LookRotation(forward2, upwards2); this.forearm.Rotate(this.forearm_OffsetRotation); if (this.handMatchesTargetRotation) { Quaternion rotation = Quaternion.Lerp(this.hand.rotation, this.target.rotation, this.BlendOn); this.hand.rotation = rotation; this.hand.Rotate(this.hand_OffsetRotation * this.BlendOn); if (this.applyHandRotationLimits) { this.ApplyRotationLimits(); } } if (this.handMatchesTargetTransform) { this.hand.position = this.target.position; } if (this.debug) { this.debugForearmEuler = this.forearm.localEulerAngles; this.debugForearmQuat = this.forearm.rotation; if (!(this.forearm != null) || this.elbow != null) { } if (!(this.upperArm != null) || this.target != null) { } } }
public static Mesh GenerateIcoSphereMesh(int recursionLevel, float radius) { Mesh mesh = new Mesh(); List <Vector3> vertList = new List <Vector3>(); Dictionary <long, int> middlePointIndexCache = new Dictionary <long, int>(); // create 12 vertices of a icosahedron float t = (1f + Mathf.Sqrt(5f)) / 2f; vertList.Add(new Vector3(-1f, t, 0f).normalized *radius); vertList.Add(new Vector3(1f, t, 0f).normalized *radius); vertList.Add(new Vector3(-1f, -t, 0f).normalized *radius); vertList.Add(new Vector3(1f, -t, 0f).normalized *radius); vertList.Add(new Vector3(0f, -1f, t).normalized *radius); vertList.Add(new Vector3(0f, 1f, t).normalized *radius); vertList.Add(new Vector3(0f, -1f, -t).normalized *radius); vertList.Add(new Vector3(0f, 1f, -t).normalized *radius); vertList.Add(new Vector3(t, 0f, -1f).normalized *radius); vertList.Add(new Vector3(t, 0f, 1f).normalized *radius); vertList.Add(new Vector3(-t, 0f, -1f).normalized *radius); vertList.Add(new Vector3(-t, 0f, 1f).normalized *radius); // create 20 triangles of the icosahedron List <TriangleIndices> faces = new List <TriangleIndices>(); // 5 faces around point 0 faces.Add(new TriangleIndices(0, 11, 5)); faces.Add(new TriangleIndices(0, 5, 1)); faces.Add(new TriangleIndices(0, 1, 7)); faces.Add(new TriangleIndices(0, 7, 10)); faces.Add(new TriangleIndices(0, 10, 11)); // 5 adjacent faces faces.Add(new TriangleIndices(1, 5, 9)); faces.Add(new TriangleIndices(5, 11, 4)); faces.Add(new TriangleIndices(11, 10, 2)); faces.Add(new TriangleIndices(10, 7, 6)); faces.Add(new TriangleIndices(7, 1, 8)); // 5 faces around point 3 faces.Add(new TriangleIndices(3, 9, 4)); faces.Add(new TriangleIndices(3, 4, 2)); faces.Add(new TriangleIndices(3, 2, 6)); faces.Add(new TriangleIndices(3, 6, 8)); faces.Add(new TriangleIndices(3, 8, 9)); // 5 adjacent faces faces.Add(new TriangleIndices(4, 9, 5)); faces.Add(new TriangleIndices(2, 4, 11)); faces.Add(new TriangleIndices(6, 2, 10)); faces.Add(new TriangleIndices(8, 6, 7)); faces.Add(new TriangleIndices(9, 8, 1)); // refine triangles for (int i = 0; i < recursionLevel; i++) { List <TriangleIndices> faces2 = new List <TriangleIndices>(); foreach (var tri in faces) { // replace triangle by 4 triangles int a = GetMiddlePoint(tri.v1, tri.v2, ref vertList, ref middlePointIndexCache, radius); int b = GetMiddlePoint(tri.v2, tri.v3, ref vertList, ref middlePointIndexCache, radius); int c = GetMiddlePoint(tri.v3, tri.v1, ref vertList, ref middlePointIndexCache, radius); faces2.Add(new TriangleIndices(tri.v1, a, c)); faces2.Add(new TriangleIndices(tri.v2, b, a)); faces2.Add(new TriangleIndices(tri.v3, c, b)); faces2.Add(new TriangleIndices(a, b, c)); } faces = faces2; } mesh.vertices = vertList.ToArray(); List <int> triList = new List <int>(); for (int i = 0; i < faces.Count; i++) { triList.Add(faces[i].v1); triList.Add(faces[i].v2); triList.Add(faces[i].v3); } mesh.triangles = triList.ToArray(); var nVertices = mesh.vertices; Vector2[] UVs = new Vector2[nVertices.Length]; for (var i = 0; i < nVertices.Length; i++) { var unitVector = nVertices[i].normalized; Vector2 ICOuv = new Vector2(0, 0); ICOuv.x = (Mathf.Atan2(unitVector.x, unitVector.z) + Mathf.PI) / Mathf.PI / 2; ICOuv.y = (Mathf.Acos(unitVector.y) + Mathf.PI) / Mathf.PI - 1; UVs[i] = new Vector2(ICOuv.x, ICOuv.y); } mesh.uv = UVs; Vector3[] normales = new Vector3[vertList.Count]; for (int i = 0; i < normales.Length; i++) { normales[i] = vertList[i].normalized; } mesh.normals = normales; mesh.RecalculateBounds(); mesh.Optimize(); return(mesh); }
protected override void OnInput(Input input, Collider collider, Camera camera) { if (this.previousHitVector == InvalidVector && input.InputState == InputState.Pressed) { RaycastHit hit; if (collider.Raycast(camera.ScreenPointToRay(input.CurrentPosition), out hit, float.MaxValue)) { this.previousHitVector = (hit.point - collider.transform.position).normalized; return; } } else if (this.previousHitVector == InvalidVector || Time.deltaTime == 0.0f) { return; } Transform colliderTransform = collider.transform; Vector3 colliderPosition = colliderTransform.position; Plane interactablePlane; if (this.rotationalAxis == Axis.X) { interactablePlane = new Plane(colliderPosition, colliderPosition + colliderTransform.up, colliderPosition + colliderTransform.forward); } else if (this.rotationalAxis == Axis.Y) { interactablePlane = new Plane(colliderPosition, colliderPosition + colliderTransform.forward, colliderPosition + colliderTransform.right); } else if (this.rotationalAxis == Axis.Z) { interactablePlane = new Plane(colliderPosition, colliderPosition + colliderTransform.up, colliderPosition + colliderTransform.right); } else { Debug.LogErrorFormat("CircleInteractable found unknown rotationalAxis {0}", this.rotationalAxis); interactablePlane = default(Plane); } Ray inputRay = camera.ScreenPointToRay(input.CurrentPosition); float enter; if (interactablePlane.Raycast(inputRay, out enter) == false) { // if we didnt' hit the plane this.rotationalVelocity = this.useRotationalVelocity ? this.previousVelocity : 0.0f; this.previousHitVector = InvalidVector; this.previousVelocity = 0.0f; return; } // calculating the current hit vector Vector3 hitPoint = inputRay.GetPoint(enter); Vector3 currentHitVector = (hitPoint - collider.transform.position).normalized; float cosTheta = Vector3.Dot(currentHitVector, this.previousHitVector); Vector3 cross = Vector3.Cross(this.previousHitVector, currentHitVector); float theta = 0.0f; // NOTE [bgish]: Sometimes, if cosTheta is too close to 1, but slightly off (by 1 bit), it turns costTheta into a NaN and breaks every // 00111111 10000000 00000000 00000000 - C# thinks it's 1.00000000 and this is fine (0x3F800000) // 00111111 10000000 00000000 00000001 - C# thinks it's 1.00000000 and this is bad (0x3F800001) // Debug.Log("0x3F800000 = " + Mathf.Acos(BitConverter.ToSingle(BitConverter.GetBytes(0x3F800000), 0))); // 0x3F800000 = 1 // Debug.Log("0x3F800001 = " + Mathf.Acos(BitConverter.ToSingle(BitConverter.GetBytes(0x3F800001), 0))); // 0x3F800001 = NaN if (cosTheta < 0.999999f) { bool didFingerMove = (input.PreviousPosition - input.CurrentPosition).sqrMagnitude > minimumPixelMovementSquared; if (didFingerMove) { Vector3 crossVector; if (this.rotationalAxis == Axis.X) { crossVector = collider.transform.right; } else if (this.rotationalAxis == Axis.Y) { crossVector = collider.transform.up; } else if (this.rotationalAxis == Axis.Z) { crossVector = collider.transform.forward; } else { Debug.LogErrorFormat("CircleInteractable found unknown rotationalAxis {0}", this.rotationalAxis); crossVector = Vector3.zero; } theta = Mathf.Acos(cosTheta) * 180.0f / Mathf.PI * (Vector3.Dot(cross, crossVector) > 0 ? 1 : -1); } } this.Rotation += theta; if (input.InputState == InputState.Released) { this.rotationalVelocity = this.useRotationalVelocity ? Mathf.Clamp(this.previousVelocity, -this.maxRotationalVelocity, this.maxRotationalVelocity) : 0.0f; this.previousVelocity = 0.0f; } else { this.rotationalVelocity = 0.0f; this.previousVelocity = theta / Time.deltaTime; } this.previousHitVector = input.InputState == InputState.Released ? InvalidVector : currentHitVector; }
void OnWizardCreate() { GameObject sphere = new GameObject(); if (!string.IsNullOrEmpty(optionalName)) { sphere.name = optionalName; } else { sphere.name = "IcoSphere"; } if (!createAtOrigin && cam) { sphere.transform.position = cam.transform.position + cam.transform.forward * 5.0f; } else { sphere.transform.position = Vector3.zero; } MeshFilter filter = (MeshFilter)sphere.AddComponent(typeof(MeshFilter)); sphere.AddComponent(typeof(MeshRenderer)); string anchorId; switch (anchor) { case AnchorPoint.Center: default: anchorId = "C"; break; } string sphereAssetName = sphere.name + recursionLevel + anchorId + ".asset"; Mesh mesh = (Mesh)AssetDatabase.LoadAssetAtPath("Assets/Editor/" + sphereAssetName, typeof(Mesh)); if (mesh == null) { mesh = new Mesh(); mesh.name = sphere.name; List <Vector3> vertList = new List <Vector3>(); Dictionary <long, int> middlePointIndexCache = new Dictionary <long, int>(); // create 12 vertices of a icosahedron float t = (1f + Mathf.Sqrt(5f)) / 2f; vertList.Add(new Vector3(-1f, t, 0f).normalized *radius); vertList.Add(new Vector3(1f, t, 0f).normalized *radius); vertList.Add(new Vector3(-1f, -t, 0f).normalized *radius); vertList.Add(new Vector3(1f, -t, 0f).normalized *radius); vertList.Add(new Vector3(0f, -1f, t).normalized *radius); vertList.Add(new Vector3(0f, 1f, t).normalized *radius); vertList.Add(new Vector3(0f, -1f, -t).normalized *radius); vertList.Add(new Vector3(0f, 1f, -t).normalized *radius); vertList.Add(new Vector3(t, 0f, -1f).normalized *radius); vertList.Add(new Vector3(t, 0f, 1f).normalized *radius); vertList.Add(new Vector3(-t, 0f, -1f).normalized *radius); vertList.Add(new Vector3(-t, 0f, 1f).normalized *radius); // create 20 triangles of the icosahedron List <TriangleIndices> faces = new List <TriangleIndices>(); // 5 faces around point 0 faces.Add(new TriangleIndices(0, 11, 5)); faces.Add(new TriangleIndices(0, 5, 1)); faces.Add(new TriangleIndices(0, 1, 7)); faces.Add(new TriangleIndices(0, 7, 10)); faces.Add(new TriangleIndices(0, 10, 11)); // 5 adjacent faces faces.Add(new TriangleIndices(1, 5, 9)); faces.Add(new TriangleIndices(5, 11, 4)); faces.Add(new TriangleIndices(11, 10, 2)); faces.Add(new TriangleIndices(10, 7, 6)); faces.Add(new TriangleIndices(7, 1, 8)); // 5 faces around point 3 faces.Add(new TriangleIndices(3, 9, 4)); faces.Add(new TriangleIndices(3, 4, 2)); faces.Add(new TriangleIndices(3, 2, 6)); faces.Add(new TriangleIndices(3, 6, 8)); faces.Add(new TriangleIndices(3, 8, 9)); // 5 adjacent faces faces.Add(new TriangleIndices(4, 9, 5)); faces.Add(new TriangleIndices(2, 4, 11)); faces.Add(new TriangleIndices(6, 2, 10)); faces.Add(new TriangleIndices(8, 6, 7)); faces.Add(new TriangleIndices(9, 8, 1)); // refine triangles for (int i = 0; i < recursionLevel; i++) { List <TriangleIndices> faces2 = new List <TriangleIndices>(); foreach (var tri in faces) { // replace triangle by 4 triangles int a = getMiddlePoint(tri.v1, tri.v2, ref vertList, ref middlePointIndexCache, radius); int b = getMiddlePoint(tri.v2, tri.v3, ref vertList, ref middlePointIndexCache, radius); int c = getMiddlePoint(tri.v3, tri.v1, ref vertList, ref middlePointIndexCache, radius); faces2.Add(new TriangleIndices(tri.v1, a, c)); faces2.Add(new TriangleIndices(tri.v2, b, a)); faces2.Add(new TriangleIndices(tri.v3, c, b)); faces2.Add(new TriangleIndices(a, b, c)); } faces = faces2; } mesh.vertices = vertList.ToArray(); List <int> triList = new List <int>(); for (int i = 0; i < faces.Count; i++) { triList.Add(faces[i].v1); triList.Add(faces[i].v2); triList.Add(faces[i].v3); } mesh.triangles = triList.ToArray(); var nVertices = mesh.vertices; Vector2[] UVs = new Vector2[nVertices.Length]; for (var i = 0; i < nVertices.Length; i++) { var unitVector = nVertices[i].normalized; Vector2 ICOuv = new Vector2(0, 0); ICOuv.x = (Mathf.Atan2(unitVector.x, unitVector.z) + Mathf.PI) / Mathf.PI / 2; ICOuv.y = (Mathf.Acos(unitVector.y) + Mathf.PI) / Mathf.PI - 1; UVs[i] = new Vector2(ICOuv.x, ICOuv.y); } mesh.uv = UVs; Vector3[] normales = new Vector3[vertList.Count]; for (int i = 0; i < normales.Length; i++) { normales[i] = vertList[i].normalized; } mesh.normals = normales; mesh.RecalculateBounds(); //mesh.Optimize(); AssetDatabase.CreateAsset(mesh, "Assets/Editor/" + sphereAssetName); AssetDatabase.SaveAssets(); } filter.sharedMesh = mesh; mesh.RecalculateBounds(); if (addCollider) { sphere.AddComponent(typeof(BoxCollider)); } Selection.activeObject = sphere; }
void FixedUpdate() { //gravity if (isCarGrounded()) { if (gravityFlag) { StartCoroutine("AdjustGravity"); } if (ignoreGravityDirection) { carRigidbody.AddForce(-carUp.normalized * gravity * carRigidbody.mass / 2.5f); } else { carRigidbody.AddForce(-carUp.normalized * gravity * carRigidbody.mass); } gravityDirection = -carUp; } else { if (ignoreGravityDirection) { carRigidbody.AddForce(-carUp.normalized * gravity * carRigidbody.mass / 2.5f); } else { carRigidbody.AddForce(Vector3.down * gravity * carRigidbody.mass); } } float angleBetween = Mathf.Acos(Vector3.Dot(Vector3.up, transform.up)) * 180 / Mathf.PI; if (currentSpeed < maxSpeed + boostSpeed + boostPadSpeed && (isCarGrounded() || angleBetween < 20)) { // apply the engine force to the rigidbody carRigidbody.AddForce(engineForce * Time.deltaTime); } else { cheatPhysics(); } // turn car float tempMaxTurnSpeed = maxTurnAngle; if (drift) { tempMaxTurnSpeed *= driftStrength; } if (currentTurnSpeed < tempMaxTurnSpeed || relativeAngularVel.y * horizontal < 0f) { if (!isCarGrounded()) { turnVec = turnVec * inAirTurnMultiplier; } if (relativeAngularVel.y * horizontal < 0f) { carRigidbody.AddTorque(turnBackMultiplier * turnVec * Time.deltaTime); } else { carRigidbody.AddTorque(turnVec * Time.deltaTime); } } if (Mathf.Abs(horizontal) >= deadZone && isCarGrounded()) { carRigidbody.angularDrag = 0f; } else { carRigidbody.angularDrag = 10f; } if ((Mathf.Abs(throttle) >= deadZone && Mathf.Abs(reverse) <= deadZone || Mathf.Abs(reverse) >= deadZone && Mathf.Abs(throttle) <= deadZone) || !isCarGrounded() || isBoosting) { carRigidbody.drag = 0f; } else { carRigidbody.drag = deceleration; } // apply forces to our rigidbody for grip carRigidbody.AddForce(imp * Time.deltaTime); if (GetComponent <VehicleInput>()) { if (onCorkscrew) { if (cineCamera.GetCinemachineComponent <CinemachineOrbitalTransposer>().m_XDamping != .5f) { cineCamera.GetCinemachineComponent <CinemachineOrbitalTransposer>().m_XDamping = Mathf.Lerp(cineCamera.GetCinemachineComponent <CinemachineOrbitalTransposer>().m_XDamping, .5f, Time.deltaTime); } } } if (Physics.Raycast(transform.position, carUp, out hit, 5f, LayerMask.GetMask("Ground"))) { GetComponent <CarHealthBehavior>().Kill(); } }
// Running the solver - all the joints are iterated through once every frame void Update() { if (ready) { if (!offsetComputed) { Qoffset = Quaternion.Inverse(joints[joints.Length - 1].transform.rotation) * target.transform.rotation; Quaternion Qjoint = joints[joints.Length - 1].transform.rotation; //Quaternion Qtarget = Qjoint * Qoffset; QoffsetINV = Quaternion.Inverse(Qoffset); offsetComputed = true; } joints[joints.Length - 1].transform.rotation = target.transform.rotation * QoffsetINV; // if the target hasn't been reached if (!done) { // if the Max number of tries hasn't been reached if (tries <= Mtries && Vector3.Distance(joints[joints.Length - 1].transform.position, target.transform.position) > epsilon) { // starting from the second last joint (the last being the end effector) // going back up to the root for (int i = joints.Length - 2; i >= 0; i--) { // The vector from the ith joint to the end effector Vector3 r1 = joints[joints.Length - 1].transform.position - joints[i].transform.position; // The vector from the ith joint to the target Vector3 r2 = target.transform.position - joints[i].transform.position; // to avoid dividing by tiny numbers if (r1.magnitude * r2.magnitude <= 0.001f) { // cos component will be 1 and sin will be 0 cos[i] = 1; sin[i] = 0; } else { // find the components using dot and cross product cos[i] = Vector3.Dot(r1, r2) / (r1.magnitude * r2.magnitude); sin[i] = (Vector3.Cross(r1, r2)).magnitude / (r1.magnitude * r2.magnitude); } // The axis of rotation is basically the // unit vector along the cross product Vector3 axis = (Vector3.Cross(r1, r2)) / (r1.magnitude * r2.magnitude); // find the angle between r1 and r2 (and clamp values of cos to avoid errors) theta[i] = Mathf.Acos(Mathf.Max(-1, Mathf.Min(1, cos[i]))); // invert angle if sin component is negative if (sin[i] < 0.0f) { theta[i] = -theta[i]; } // obtain an angle value between -pi and pi, and then convert to degrees theta[i] = (float)SimpleAngle(theta[i]) * Mathf.Rad2Deg; // rotate the ith joint along the axis by theta degrees in the world space. joints[i].transform.Rotate(axis, theta[i], Space.World); } // increment tries tries++; } } // find the difference in the positions of the end effector and the target float dist = Vector3.Distance(joints[joints.Length - 1].transform.position, target.transform.position); // if target is within reach (within epsilon) then the process is done done = dist < epsilon; // the target has moved, reset tries to 0 and change tpos if (target.transform.position != tpos) { tries = 0; tpos = target.transform.position; } } }
protected void UpdateDeltaSpeed(ref float frontDeltaSpeed, ref float straffDeltaSpeed, ref bool frontControlled, ref bool straffControlled) { velocity = transform.InverseTransformDirection(characterController.velocity); if (DestPositionActive) { destDirection.x = destPosition.x - transform.position.x; destDirection.z = destPosition.z - transform.position.z; destDistance = destDirection.magnitude; destDirection.Normalize(); destPan = Mathf.Acos(destDirection.z) * Mathf.Rad2Deg; if (destDirection.x < 0) { destPan = -destPan; } destDirection = transform.InverseTransformDirection(destDirection); if (destDistance < playerWidth * 2) { DestPositionActive = false; } else { frontDeltaSpeed += acceleration * (destDirection.z * characterSpeedKPH * 0.2777777f - FrontSpeed) * Time.deltaTime; straffDeltaSpeed += acceleration * (destDirection.x * characterSpeedKPH * 0.2777777f - StraffSpeed) * Time.deltaTime; frontControlled = true; straffControlled = true; UpdateHeadBobber(destDirection.z, 0.0f); } float speed = velocity.magnitude; if (speed < 0.3f) { if (!IsStuck) { if (destPositionActiveStuckTime < 0) { destPositionActiveStuckTime = Time.time; } else if (Time.time - destPositionActiveStuckTime > timeBeforeStuckDetection) { IsStuck = true; } } } else { destPositionActiveStuckTime = -1; if (IsStuck) { IsStuck = false; } } } else { destPanActive = false; } }
// move agent towards destination void MoveTowardsDestination() { // if there are no more path nodes, stop moving if (!HasDestination()) { _animator.SetBool("IsRunning", false); m_agent.StopAngularVelocity(); return; } _animator.SetBool("IsRunning", true); // calculate all movement and speeds angles etc for moving towards destination Vector3 destination = m_pathList[0]; if (_currentBallTarget) { if (_currentBallTarget.GetComponent <BallProjectile>().GetIsHeld()) { ResetDestinations(); return; } destination = _currentBallTarget.transform.position; } // check if destination is on correct side of court if (_isBlue) { if (destination.z < 0) { _currentBallTarget = null; m_pathList.Clear(); /*destination = GenerateRandomLocation(_isBlue); * m_pathList.Add(destination);*/ ScanForObjects(); destination = m_pathList[0]; } } else { if (destination.z > 0) { _currentBallTarget = null; m_pathList.Clear(); /*destination = GenerateRandomLocation(_isBlue); * m_pathList.Add(destination);*/ ScanForObjects(); destination = m_pathList[0]; } } Vector3 toDestination = destination - m_agent.transform.position; float distanceToDestination = toDestination.magnitude; toDestination.Normalize(); float lookAtToDestinationDot = Vector3.Dot(m_agent.transform.forward, toDestination); float rightToDestinationDot = Vector3.Dot(m_agent.transform.right, toDestination); float toDestinationAngle = Mathf.Rad2Deg * Mathf.Acos(lookAtToDestinationDot); // generate list of speed considerations to pass to calculate functions List <float> speedConsiderations = new List <float>(); float distanceConsideration = CalculateConsiderationValue(distanceToDestination, m_destinationBuffer, m_maxSpeedDistance); float angleConsideration = CalculateConsiderationValue(toDestinationAngle, m_minAngularSpeedAngle, m_maxAngularSpeedAngle); float speedAngleConsideration = 1.0f - angleConsideration; speedConsiderations.Add(distanceConsideration); speedConsiderations.Add(speedAngleConsideration); // set the agents speed and angular speed based on list of considerations generated earlier float speed = CalculateConsiderationUtil(speedConsiderations) * m_agent.m_linearMaxSpeed; m_agent.linearSpeed = speed; float angularSpeed = angleConsideration * m_agent.m_angularMaxSpeed; m_agent.angularSpeed = angularSpeed; //how do we face our destination bool shouldTurnRight = rightToDestinationDot > Mathf.Epsilon; if (shouldTurnRight) { m_agent.TurnRight(); } else { m_agent.TurnLeft(); } if (distanceToDestination > m_destinationBuffer) { m_agent.MoveForwards(); } else if (_currentBallTarget) { PickUpBall(); } }
void Start() { //Vector3.Angle() [0,180] //两个向量的夹角 Vector3 a0 = new Vector3(0, 1, 1); Vector3 a1 = new Vector3(2, 1, 0); float angle0 = Vector3.Angle(a0, a1); Debug.Log(a0 + " " + a1 + " 以原点为夹角的角度 " + angle0); //计算以b0为原点,b0a0,b0a1的夹角 Vector3 b0 = new Vector3(2, 2, 2); float angle1 = Vector3.Angle(b0 - a0, b0 - a1); Debug.Log(a0 + " " + a1 + " 以b0为夹角的角度 " + angle1); //叉积Vector3.Cross() //得到同时垂直于两个这两个向量的法向量 Vector3 cross = Vector3.Cross(a0.normalized, a1.normalized); Debug.DrawLine(Vector3.zero, a0, Color.red, 10000); Debug.DrawLine(Vector3.zero, a1, Color.red, 10000); Debug.DrawLine(Vector3.zero, cross, Color.red, 10000); Debug.Log("cross = " + cross); //弧度 float radians = Mathf.Asin(Vector3.Distance(Vector3.zero, Vector3.Cross(a0.normalized, a1.normalized))); //夹角 float angle2 = radians * Mathf.Rad2Deg; Debug.Log(a0 + " " + a1 + " 以原点为夹角的角度 " + angle2 + " 弧度 " + radians + " 叉积 " + cross); if (cross.y > 0) { //a1在a0顺时针右边 } else if (cross.y < 0) { //a1在a0逆时针左边 } else { //a1和a0平行 } //点积Vector3.Dot() float dot = Vector3.Dot(a0.normalized, a1.normalized); float angle3 = Mathf.Acos(Vector3.Dot(a0.normalized, a1.normalized)) * Mathf.Rad2Deg; Debug.Log(a0 + " " + a1 + " " + "以原点为夹角的角度 " + angle3 + " 弧度 " + radians + " 点积 " + dot); if (dot > 0) { //a1在a0前方 } else if (dot < 0) { //a1在a0后方 } else { //1正前方-1正后方 } //Vector3.BetweenAngle //返回一个向量的拷贝,并限制最大长度 Vector3 v0 = new Vector3(0, 5, 0); Vector3 clampMagnitude = Vector3.ClampMagnitude(v0, 3); Debug.Log("clampMagnitude = " + clampMagnitude); //Vector3.Magnitude //返回向量的长度 float magnitude = Vector3.Magnitude(new Vector3(1, 5, 0)); Debug.Log("magnitude = " + magnitude); //Vector3.SqrMagnitude //返回向量长度的平方 float sqrMagnitude = Vector3.SqrMagnitude(new Vector3(1, 5, 0)); Debug.Log("sqrMagnitude = " + sqrMagnitude); //Vector3.Max //返回两个向量的最大组成 Vector3 max = Vector3.Max(new Vector3(10, 3, 5), new Vector3(1, 4, 100)); Debug.Log("max = " + max); //Vector3.Min //返回两个向量的最小组成 Vector3 min = Vector3.Min(new Vector3(10, 3, 5), new Vector3(1, 4, 100)); Debug.Log("min = " + min); //Vector3.Normalized //归一化,只比较方向不比较长度 Vector3 normalized = (new Vector3(10, 2, 3)).normalized; Debug.Log("normalized = " + normalized); //Vector3.OrthoNormalize //归一化并彼此相互垂直对第二个第三个参照第一个进行正交化处理 Vector3 ort0 = new Vector3(1, 2, 3); Vector3 ort1 = new Vector3(4, 5, 6); Debug.DrawLine(Vector3.zero, ort0, Color.green, 1000); Debug.DrawLine(Vector3.zero, ort1, Color.green, 1000); Debug.Log("ort0.normalize = " + ort0.normalized + " ort1.normalize = " + ort1.normalized); Vector3.OrthoNormalize(ref ort0, ref ort1); Debug.Log("ort0 = " + ort0 + " ort1 = " + ort1); Debug.DrawLine(Vector3.zero, ort0, Color.blue, 1000); Debug.DrawLine(Vector3.zero, ort1, Color.blue, 1000); //Vector3.Project //返回p0在p1上的投影向量 Vector3 p0 = new Vector3(1, 5, 7); Vector3 p1 = new Vector3(2, 8, 8); Vector3 project = Vector3.Project(p0, p1); Debug.Log("Project = " + project); //Debug.DrawLine(Vector3.zero, p0, Color.black, 1000); //Debug.DrawLine(Vector3.zero, p1, Color.black, 1000); //Debug.DrawLine(Vector3.zero, project, Color.blue, 1000); //Vector3.Reflect //反射向量,沿着reflect1的法线(垂直于reflect1)的反射向量 Vector3 reflect0 = new Vector3(0, 3, 2); Vector3 reflect1 = Vector3.Reflect(reflect0, Vector3.up); Debug.DrawLine(Vector3.zero, reflect0, Color.gray, 1000); Debug.DrawLine(Vector3.zero, Vector3.up, Color.yellow, 1000); Debug.DrawLine(Vector3.zero, reflect1, Color.black, 1000); //Vector3.Scale //返回向量a和b的乘积 Vector3 scale = Vector3.Scale(new Vector3(1, 2, 3), new Vector3(4, 5, 6)); Debug.Log(" scale = " + scale); }
/// Detection Center should be in Global Space. protected void UpdateSolitaryBrushDetection(Vector3 vDetectionCenter_GS) { if (m_CurrentCanvas == null) { m_CurrentCanvas = App.ActiveCanvas; } TrTransform canvasPose = m_CurrentCanvas.Pose; Vector3 vDetectionCenter_CS = canvasPose.inverse * vDetectionCenter_GS; Transform rCanvas = m_CurrentCanvas.transform; int iNumCanvasChildren = rCanvas.childCount; m_TimesUp = false; //reset detection if we've moved or adjusted our size float fDetectionRadius = GetSize(); float fDetectionRadiusSq = fDetectionRadius * fDetectionRadius; m_DetectionStopwatch.Reset(); m_DetectionStopwatch.Start(); //early out if there's nothing to look at if (iNumCanvasChildren > 0 && m_DetectionObjectIndex < iNumCanvasChildren) { Plane rTestPlane = new Plane(); m_ResetDetection = false; //spin until we've taken up too much time while (!m_TimesUp) { //check child bounds Transform rChild = rCanvas.GetChild(m_DetectionObjectIndex); if (rChild.gameObject.activeSelf) { MeshFilter rMeshFilter = rChild.GetComponent <MeshFilter>(); if (rMeshFilter) { Bounds rMeshBounds = rMeshFilter.mesh.bounds; rMeshBounds.Expand(fDetectionRadius); Vector3 vTransformedCenter = rChild.InverseTransformPoint(vDetectionCenter_CS); if (rMeshBounds.Contains(vTransformedCenter)) { //bounds valid, check triangle intersections with sphere int iMeshVertCount = rMeshFilter.mesh.vertexCount; Vector3[] aVerts = rMeshFilter.mesh.vertices; Vector3[] aNorms = rMeshFilter.mesh.normals; while (m_DetectionVertIndex < iMeshVertCount - 2) { //check to see if we're within the sphere radius to the plane of this triangle Vector3 vVert = aVerts[m_DetectionVertIndex]; Vector3 vNorm = aNorms[m_DetectionVertIndex]; rTestPlane.SetNormalAndPosition(vNorm, vVert); float fDistToPlane = rTestPlane.GetDistanceToPoint(vTransformedCenter); if (Mathf.Abs(fDistToPlane) < fDetectionRadius) { //we're within the radius to this triangle's plane, find the point projected on to the plane fDistToPlane *= -1.0f; Vector3 vPlaneOffsetVector = vNorm * fDistToPlane; Vector3 vPlaneIntersection = vTransformedCenter - vPlaneOffsetVector; Vector3 vVert2 = aVerts[m_DetectionVertIndex + 1]; Vector3 vVert3 = aVerts[m_DetectionVertIndex + 2]; //walk the projected point toward the triangle center to find the triangle test position Vector3 vTriCenter = (vVert + vVert2 + vVert3) * 0.33333f; bool bIntersecting = false; Vector3 vPointToTriCenter = vTriCenter - vTransformedCenter; if (vPointToTriCenter.sqrMagnitude < fDetectionRadiusSq) { //if the triangle center is within the detection distance, we're definitely intersecting bIntersecting = true; } else { //figure out how far we have left to move toward the tri-center float fNormAngle = Mathf.Acos(Mathf.Abs(fDistToPlane) / fDetectionRadius); float fDistLeft = Mathf.Sin(fNormAngle) * fDetectionRadius; Vector3 vToTriCenter = vTriCenter - vPlaneIntersection; vToTriCenter.Normalize(); vToTriCenter *= fDistLeft; vPlaneIntersection += vToTriCenter; //see if this projected point is in the triangle if (PointInTriangle(ref vPlaneIntersection, ref vVert, ref vVert2, ref vVert3)) { bIntersecting = true; } } if (bIntersecting) { if (HandleIntersectionWithSolitaryObject(rChild.gameObject)) { DoIntersectionResets(); break; } } } //after each triangle, check our time m_DetectionVertIndex += 3; m_TimesUp = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks; if (m_TimesUp) { break; } } } } } //if we're not flagged as done, we just finished this object, so move on to the next if (!m_TimesUp) { //move to the next object ++m_DetectionObjectIndex; m_DetectionVertIndex = 0; if (m_DetectionObjectIndex >= iNumCanvasChildren) { //if we reached the end of the line, we're done break; } //might as well check our clock per object m_TimesUp = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks; } } } m_DetectionStopwatch.Stop(); }
/// Detection Center should be in Global Space. protected void UpdateBatchedBrushDetection(Vector3 vDetectionCenter_GS) { // The CPU intersection code still needs to be updated to iterate over multiple canvases. // // TODO: Update CPU intersection checking to work on multiple canvases, // then get rid of automatic defaulting to ActiveCanvas. // Possibly let m_CurrentCanvas be null to represent a desire to intersect // with all canvases. if (m_CurrentCanvas == null) { m_CurrentCanvas = App.ActiveCanvas; } // If we changed canvases, abandon any progress we made on checking for // intersections in the previous canvas. if (m_CurrentCanvas != m_PreviousCanvas) { ResetDetection(); m_PreviousCanvas = m_CurrentCanvas; } TrTransform canvasPose = m_CurrentCanvas.Pose; Vector3 vDetectionCenter_CS = canvasPose.inverse * vDetectionCenter_GS; m_TimesUp = false; // Reset detection if we've moved or adjusted our size float fDetectionRadius_CS = GetSize() / canvasPose.scale; float fDetectionRadiusSq_CS = fDetectionRadius_CS * fDetectionRadius_CS; // Start the timer! m_DetectionStopwatch.Reset(); m_DetectionStopwatch.Start(); int iSanityCheck = 10000; bool bNothingChecked = true; if (App.Config.m_GpuIntersectionEnabled) { // Run GPU intersection if enabled; will update m_TimesUp. if (UpdateGpuIntersection(vDetectionCenter_GS, GetSize())) { IntersectionHappenedThisFrame(); m_DetectionStopwatch.Stop(); DoIntersectionResets(); return; } } m_TimesUp = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks; //check batch pools first int iNumBatchPools = m_CurrentCanvas.BatchManager.GetNumBatchPools(); if (!App.Config.m_GpuIntersectionEnabled && iNumBatchPools > 0 && m_BatchPoolIndex < iNumBatchPools) { bNothingChecked = false; m_ResetDetection = false; Plane rTestPlane = new Plane(); BatchPool rPool = m_CurrentCanvas.BatchManager.GetBatchPool(m_BatchPoolIndex); //spin until we've taken up too much time while (!m_TimesUp) { --iSanityCheck; if (iSanityCheck == 0) { Batch tmpBatch = rPool.m_Batches[m_BatchObjectIndex]; Debug.LogErrorFormat("Stroke while loop error. NumPools({0}) BatchPoolIndex({1}) NumBatchStrokes({2}) BatchStrokeIndex({3}) NumStrokeGroups({4})", iNumBatchPools, m_BatchPoolIndex, rPool.m_Batches.Count, m_BatchObjectIndex, tmpBatch.m_Groups.Count); } Batch batch = rPool.m_Batches[m_BatchObjectIndex]; if (m_BatchVertGroupIndex < batch.m_Groups.Count) { var subset = batch.m_Groups[m_BatchVertGroupIndex]; Bounds rMeshBounds = subset.m_Bounds; rMeshBounds.Expand(2.0f * fDetectionRadius_CS); if (subset.m_Active && rMeshBounds.Contains(vDetectionCenter_CS)) { //bounds valid, check triangle intersections with sphere int nTriIndices = subset.m_nTriIndex; Vector3[] aVerts; int nVerts; int[] aTris; int nTris; batch.GetTriangles(out aVerts, out nVerts, out aTris, out nTris); while (m_BatchTriIndexIndex < nTriIndices - 2) { //check to see if we're within the brush size (plus some) radius to this triangle int iTriIndex = subset.m_iTriIndex + m_BatchTriIndexIndex; Vector3 v0 = aVerts[aTris[iTriIndex]]; Vector3 v1 = aVerts[aTris[iTriIndex + 1]]; Vector3 v2 = aVerts[aTris[iTriIndex + 2]]; Vector3 vTriCenter = (v0 + v1 + v2) * 0.33333f; Vector3 vToTestCenter = vDetectionCenter_CS - vTriCenter; float fTestSphereRadius_CS = Vector3.Distance(v1, v2) + fDetectionRadius_CS; if (vToTestCenter.sqrMagnitude < fTestSphereRadius_CS * fTestSphereRadius_CS) { //check to see if we're within the sphere radius to the plane of this triangle Vector3 vNorm = Vector3.Cross(v1 - v0, v2 - v0).normalized; rTestPlane.SetNormalAndPosition(vNorm, v0); float fDistToPlane = rTestPlane.GetDistanceToPoint(vDetectionCenter_CS); if (Mathf.Abs(fDistToPlane) < fDetectionRadius_CS) { //we're within the radius to this triangle's plane, find the point projected on to the plane fDistToPlane *= -1.0f; Vector3 vPlaneOffsetVector = vNorm * fDistToPlane; Vector3 vPlaneIntersection = vDetectionCenter_CS - vPlaneOffsetVector; //walk the projected point toward the triangle center to find the triangle test position bool bIntersecting = false; Vector3 vPointToTriCenter = vTriCenter - vDetectionCenter_CS; if (vPointToTriCenter.sqrMagnitude < fDetectionRadiusSq_CS) { //if the triangle center is within the detection distance, we're definitely intersecting bIntersecting = true; } //check against triangle segments else if (SegmentSphereIntersection(v0, v1, vDetectionCenter_CS, fDetectionRadiusSq_CS)) { bIntersecting = true; } else if (SegmentSphereIntersection(v1, v2, vDetectionCenter_CS, fDetectionRadiusSq_CS)) { bIntersecting = true; } else if (SegmentSphereIntersection(v2, v0, vDetectionCenter_CS, fDetectionRadiusSq_CS)) { bIntersecting = true; } else { //figure out how far we have left to move toward the tri-center float fNormAngle = Mathf.Acos(Mathf.Abs(fDistToPlane) / fDetectionRadius_CS); float fDistLeft = Mathf.Sin(fNormAngle) * fDetectionRadius_CS; Vector3 vToTriCenter = vTriCenter - vPlaneIntersection; vToTriCenter.Normalize(); vToTriCenter *= fDistLeft; vPlaneIntersection += vToTriCenter; //see if this projected point is in the triangle if (PointInTriangle(ref vPlaneIntersection, ref v0, ref v1, ref v2)) { bIntersecting = true; } } if (bIntersecting) { if (HandleIntersectionWithBatchedStroke(subset)) { DoIntersectionResets(); break; } } } } //after each triangle, check our time m_BatchTriIndexIndex += 3; m_TimesUp = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks; if (m_TimesUp) { break; } } } } //if we're not flagged as done, we just finished this group, so move on to the next group if (!m_TimesUp) { m_BatchTriIndexIndex = 0; ++m_BatchVertGroupIndex; //if we're done with groups, go to the next object if (m_BatchVertGroupIndex >= batch.m_Groups.Count) { m_BatchVertGroupIndex = 0; ++m_BatchObjectIndex; //aaaand if we're done with objects, go on to the next pool if (m_BatchObjectIndex >= rPool.m_Batches.Count) { m_BatchObjectIndex = 0; ++m_BatchPoolIndex; if (m_BatchPoolIndex >= iNumBatchPools) { //get out if we've traversed the last pool break; } rPool = m_CurrentCanvas.BatchManager.GetBatchPool(m_BatchPoolIndex); } } //we check again here in case the early checks fail m_TimesUp = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks; } } } if (App.Config.m_GpuIntersectionEnabled && m_GpuFutureResult != null) { // We have an intersection test in flight, make sure we don't reset detection. // This ensures consistency between collision tests and avoids strobing of the result (e.g. // without this, one test will return "no result" and the next may return some result and this // oscillation will continue). bNothingChecked = false; m_ResetDetection = false; return; } // If our scene doesn't have anything in it, reset our detection. if (bNothingChecked) { m_ResetDetection = true; } m_DetectionStopwatch.Stop(); }
public static float Radius3DHandle(Quaternion rotation, Vector3 position, float radius, float minRadius = 0, float maxRadius = float.PositiveInfinity) { minRadius = Mathf.Abs(minRadius); maxRadius = Mathf.Abs(maxRadius); if (maxRadius < minRadius) { maxRadius = minRadius; } const float kEpsilon = 0.000001F; var camera = Camera.current; var cameraLocalPos = SceneHandles.inverseMatrix.MultiplyPoint(camera.transform.position); var cameraLocalForward = SceneHandles.inverseMatrix.MultiplyVector(camera.transform.forward); var isCameraInsideSphere = (cameraLocalPos - position).magnitude < radius; var isCameraOrthographic = camera.orthographic; var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevDisabled = SceneHandles.disabled; var prevColor = SceneHandles.color; var forward = rotation * Vector3.forward; var up = rotation * Vector3.up; var right = rotation * Vector3.right; bool guiHasChanged = GUI.changed; GUI.changed = false; Vector3 positiveXDir = right; Vector3 negativeXDir = -right; Vector3 positiveYDir = up; Vector3 negativeYDir = -up; Vector3 positiveZDir = forward; Vector3 negativeZDir = -forward; Vector3 positiveXHandle = position + positiveXDir * radius; Vector3 negativeXHandle = position + negativeXDir * radius; Vector3 positiveYHandle = position + positiveYDir * radius; Vector3 negativeYHandle = position + negativeYDir * radius; Vector3 positiveZHandle = position + positiveZDir * radius; Vector3 negativeZHandle = position + negativeZDir * radius; bool positiveXBackfaced = false; bool negativeXBackfaced = false; bool positiveYBackfaced = false; bool negativeYBackfaced = false; bool positiveZBackfaced = false; bool negativeZBackfaced = false; if (!isCameraInsideSphere) { float cosV; cosV = isCameraOrthographic ? Vector3.Dot(positiveXDir, -cameraLocalForward) : Vector3.Dot(positiveXDir, (cameraLocalPos - positiveXHandle)); positiveXBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(negativeXDir, -cameraLocalForward) : Vector3.Dot(negativeXDir, (cameraLocalPos - negativeXHandle)); negativeXBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(positiveYDir, -cameraLocalForward) : Vector3.Dot(positiveYDir, (cameraLocalPos - positiveYHandle)); positiveYBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(negativeYDir, -cameraLocalForward) : Vector3.Dot(negativeYDir, (cameraLocalPos - negativeYHandle)); negativeYBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(positiveZDir, -cameraLocalForward) : Vector3.Dot(positiveZDir, (cameraLocalPos - positiveZHandle)); positiveZBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(negativeZDir, -cameraLocalForward) : Vector3.Dot(negativeZDir, (cameraLocalPos - negativeZHandle)); negativeZBackfaced = (cosV < -0.0001f); } float positiveXSize = UnityEditor.HandleUtility.GetHandleSize(positiveXHandle) * 0.05f * (positiveXBackfaced ? backfaceSizeMultiplier : 1); float negativeXSize = UnityEditor.HandleUtility.GetHandleSize(negativeXHandle) * 0.05f * (negativeXBackfaced ? backfaceSizeMultiplier : 1); float positiveYSize = UnityEditor.HandleUtility.GetHandleSize(positiveYHandle) * 0.05f * (positiveYBackfaced ? backfaceSizeMultiplier : 1); float negativeYSize = UnityEditor.HandleUtility.GetHandleSize(negativeYHandle) * 0.05f * (negativeYBackfaced ? backfaceSizeMultiplier : 1); float positiveZSize = UnityEditor.HandleUtility.GetHandleSize(positiveZHandle) * 0.05f * (positiveZBackfaced ? backfaceSizeMultiplier : 1); float negativeZSize = UnityEditor.HandleUtility.GetHandleSize(negativeZHandle) * 0.05f * (negativeZBackfaced ? backfaceSizeMultiplier : 1); var isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[0]; var color = SceneHandles.StateColor(prevColor, isDisabled, false); var backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier); GUI.changed = false; SceneHandles.color = positiveXBackfaced ? backfacedColor : color; positiveXHandle = Slider2DHandle(positiveXHandle, Vector3.zero, forward, up, right, positiveXSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(positiveXHandle - position, positiveXDir); guiHasChanged = true; } GUI.changed = false; SceneHandles.color = negativeXBackfaced ? backfacedColor : color; negativeXHandle = Slider2DHandle(negativeXHandle, Vector3.zero, forward, up, right, negativeXSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(negativeXHandle - position, negativeXDir); guiHasChanged = true; } isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[1]; color = SceneHandles.StateColor(prevColor, isDisabled, false); backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier); GUI.changed = false; SceneHandles.color = positiveYBackfaced ? backfacedColor : color; positiveYHandle = Slider2DHandle(positiveYHandle, Vector3.zero, forward, up, right, positiveYSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(positiveYHandle - position, positiveYDir); guiHasChanged = true; } GUI.changed = false; SceneHandles.color = negativeYBackfaced ? backfacedColor : color; negativeYHandle = Slider2DHandle(negativeYHandle, Vector3.zero, forward, up, right, negativeYSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(negativeYHandle - position, negativeYDir); guiHasChanged = true; } isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[2]; color = SceneHandles.StateColor(prevColor, isDisabled, false); backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier); GUI.changed = false; SceneHandles.color = positiveZBackfaced ? backfacedColor : color; positiveZHandle = Slider2DHandle(positiveZHandle, Vector3.zero, up, forward, right, positiveZSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(positiveZHandle - position, positiveZDir); guiHasChanged = true; } GUI.changed = false; SceneHandles.color = negativeZBackfaced ? backfacedColor : color; negativeZHandle = Slider2DHandle(negativeZHandle, Vector3.zero, up, forward, right, negativeZSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(negativeZHandle - position, negativeZDir); guiHasChanged = true; } radius = Mathf.Max(minRadius, Mathf.Min(Mathf.Abs(radius), maxRadius)); GUI.changed |= guiHasChanged; if (radius > 0) { isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); color = SceneHandles.StateColor(prevColor, isDisabled, false); backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier); var discOrientations = new Vector3[] { rotation *Vector3.right, rotation *Vector3.up, rotation *Vector3.forward }; var currentCamera = Camera.current; var cameraTransform = currentCamera.transform; if (currentCamera.orthographic) { var planeNormal = cameraTransform.forward; SceneHandles.DrawWireDisc(position, planeNormal, radius); planeNormal.Normalize(); for (int i = 0; i < 3; i++) { var discOrientation = discOrientations[i]; var discTangent = Vector3.Cross(discOrientation, planeNormal); // we may have view dir locked to one axis if (discTangent.sqrMagnitude > kEpsilon) { SceneHandles.color = color; SceneHandles.DrawWireArc(position, discOrientation, discTangent, 180, radius); SceneHandles.color = backfacedColor; SceneHandles.DrawWireArc(position, discOrientation, discTangent, -180, radius); } } } else { // Since the geometry is transformed by Handles.matrix during rendering, we transform the camera position // by the inverse matrix so that the two-shaded wireframe will have the proper orientation. var invMatrix = SceneHandles.inverseMatrix; var cameraCenter = cameraTransform.position; var cameraToCenter = position - invMatrix.MultiplyPoint(cameraCenter); // vector from camera to center var sqrDistCameraToCenter = cameraToCenter.sqrMagnitude; var sqrRadius = radius * radius; // squared radius var sqrOffset = sqrRadius * sqrRadius / sqrDistCameraToCenter; // squared distance from actual center to drawn disc center var insideAmount = sqrOffset / sqrRadius; if (insideAmount < 1) { if (Mathf.Abs(sqrDistCameraToCenter) < kEpsilon) { return(radius); } var horizonRadius = Mathf.Sqrt(sqrRadius - sqrOffset); var horizonCenter = position - sqrRadius * cameraToCenter / sqrDistCameraToCenter; SceneHandles.color = color; SceneHandles.DrawWireDisc(horizonCenter, cameraToCenter, horizonRadius); var planeNormal = cameraToCenter.normalized; for (int i = 0; i < 3; i++) { var discOrientation = discOrientations[i]; var angleBetweenDiscAndNormal = Mathf.Acos(Vector3.Dot(discOrientation, planeNormal)); angleBetweenDiscAndNormal = (Mathf.PI * 0.5f) - Mathf.Min(angleBetweenDiscAndNormal, Mathf.PI - angleBetweenDiscAndNormal); float f = Mathf.Tan(angleBetweenDiscAndNormal); float g = Mathf.Sqrt(sqrOffset + f * f * sqrOffset) / radius; if (g < 1) { var angleToHorizon = Mathf.Asin(g) * Mathf.Rad2Deg; var discTangent = Vector3.Cross(discOrientation, planeNormal); var vectorToPointOnHorizon = Quaternion.AngleAxis(angleToHorizon, discOrientation) * discTangent; var horizonArcLength = (90 - angleToHorizon) * 2.0f; SceneHandles.color = color; SceneHandles.DrawWireArc(position, discOrientation, vectorToPointOnHorizon, horizonArcLength, radius); SceneHandles.color = backfacedColor; SceneHandles.DrawWireArc(position, discOrientation, vectorToPointOnHorizon, horizonArcLength - 360, radius); } else { SceneHandles.color = backfacedColor; SceneHandles.DrawWireDisc(position, discOrientation, radius); } } } else { SceneHandles.color = backfacedColor; for (int i = 0; i < 3; i++) { var discOrientation = discOrientations[i]; SceneHandles.DrawWireDisc(position, discOrientation, radius); } } } } SceneHandles.disabled = prevDisabled; SceneHandles.color = prevColor; return(radius); }
// TODO Negative m's are missing private float AssociatedLegendrePolynomials() { int l = m_QuantumNumberL; int m = m_QuantumNumberM; float x = this.transform.position.x; float y = this.transform.position.y; float z = this.transform.position.z; float r = Mathf.Sqrt(x * x + y * y + z * z); // Compute spherical coordinates float theta = Mathf.Acos(z / r); float arg = Mathf.Cos(theta); // The argument to the polynomial float result = 1.0f; // l=0 gives 1 if (l == 1) { if (m == 1) { result = -Mathf.Sqrt(1f - arg * arg); } else if (m == 0) { result = arg; } } else if (l == 2) { if (m == 2) { result = 3f * (1f - arg * arg); } else if (m == 1) { result = -3f * arg * Mathf.Sqrt(1f - arg * arg); } else if (m == 0) { result = 0.5f * (3f * arg * arg - 1f); } } else if (l == 3) { if (m == 3) { result = -15f * Mathf.Pow(Mathf.Sqrt(1f - arg * arg), 3.0f); } else if (m == 2) { result = 15f * arg * (1f - arg * arg); } else if (m == 1) { result = -3f / 2f * (5f * arg * arg - 1f) * Mathf.Sqrt(1f - arg * arg); } else if (m == 0) { result = 0.5f * (5f * arg * arg * arg - 3f * arg); } } else { Debug.LogError("AssociatedLegendrePolynomials() does not take so large aguments"); } return(result); }
void Update() { character.Move(); #if UNITY_STANDALONE_WIN if (Input.GetKeyDown(KeyCode.Space)) { //character.Jump(); if (!(transform.position.y > 0.25f)) { character.isJump = true; } } float moveDir = Input.GetAxis("Horizontal"); character.ManualMove(moveDir); if (Input.GetKeyDown(KeyCode.J)) { character.RotateLeft(); } else if (Input.GetKeyDown(KeyCode.L)) { character.RotateRight(); } if (Input.GetKeyDown(KeyCode.K)) { character.Slide(); } if (Input.GetKeyDown(KeyCode.Escape)) { if (exitUI != null) { exitUI.SetActive(true); } else { exitUI = Instantiate(Resources.Load("UiPreFeb/Img_Exit"), GameObject.Find("Canvas").transform) as GameObject; } GameMode.Instance.gameState = false; } #region //PC测试 //if (Input.GetKeyDown(KeyCode.Mouse0)) //{ // startPos = Camera.main.ViewportToScreenPoint(Input.mousePosition); //} //if (Input.GetKeyDown(KeyCode.Mouse1)) //{ // EndPos = Camera.main.ViewportToScreenPoint(Input.mousePosition); // isInput = true; //} #endregion #endif #region //手机代码 #if UNITY_ANDROID character.ManualMove(Input.acceleration.x); if (Input.touchCount == 1) { if (Input.touches[0].phase == TouchPhase.Began) { startPos = Input.touches[0].position; } if (Input.touches[0].phase == TouchPhase.Ended && Input.touches[0].phase != TouchPhase.Canceled) { EndPos = Input.touches[0].position; isInput = true; } } if (Application.platform == RuntimePlatform.Android && (Input.GetKeyDown(KeyCode.Escape))) { if (exitUI != null) { exitUI.SetActive(true); } else { exitUI = Instantiate(Resources.Load("UiPreFeb/Img_Exit"), GameObject.Find("Canvas").transform) as GameObject; } GameMode.Instance.gameState = false; } if (isInput && GameMode.Instance.gameState) { Vector2 nowDir = EndPos - startPos; //计算手指滑动之间的向量 float cosValueX = Vector3.Dot(nowDir, ScreenAixX) / nowDir.magnitude * ScreenAixX.magnitude; //与屏幕坐标的X轴的余弦值 float cosValueY = Vector3.Dot(nowDir, ScreenAixY) / nowDir.magnitude * ScreenAixY.magnitude; //与屏幕坐标的Y轴余弦值 angle = Mathf.Acos(cosValueY) * Mathf.Rad2Deg; Debug.Log(angle + " === " + cosValueX + " === " + cosValueY + " === "); if (cosValueX < 0) { if (angle > 45 && angle < 135) { character.RotateLeft(); Debug.Log("左转" + " " + angle); } else if (angle > 0 && angle < 45) { character.isJump = true; Debug.Log("跳跃" + " " + angle); } else if (angle > 135 && angle < 180) { character.Slide(); Debug.Log("下蹲" + " " + angle); } } else if (cosValueX == 0) { if (angle > 0) { character.isJump = true; Debug.Log("跳跃" + " " + angle); } else { character.Slide(); Debug.Log("下蹲" + " " + angle); } } else { if (angle > 45 && angle < 135) { character.RotateRight(); Debug.Log("右转" + " " + angle); } else if (angle > 0 && angle < 45) { character.isJump = true; Debug.Log("跳跃" + " " + angle); } else if (angle > 135 && angle < 180) { character.Slide(); Debug.Log("下蹲" + " " + angle); } } isInput = false; } #endif }
private void Render() { MeshRenderer render = gameObject.GetComponent <MeshRenderer>(); render.sharedMaterial = new Material(Shader.Find("Standard")); render.sharedMaterial.SetInt("_Metallic", 1); render.sharedMaterial.SetInt("_Glossiness", 0); MeshFilter filter = gameObject.GetComponent <MeshFilter>(); Mesh mesh = new Mesh(); filter.sharedMesh = mesh; mesh.Clear(); mesh.name = gameObject.name; #region Vertices List <Vector3> vertList = new List <Vector3>(); Dictionary <long, int> middlePointIndexCache = new Dictionary <long, int>(); // create 12 vertices of a icosahedron float t = (1f + Mathf.Sqrt(5f)) / 2f; vertList.Add(new Vector3(-1f, t, 0f).normalized *radius); vertList.Add(new Vector3(1f, t, 0f).normalized *radius); vertList.Add(new Vector3(-1f, -t, 0f).normalized *radius); vertList.Add(new Vector3(1f, -t, 0f).normalized *radius); vertList.Add(new Vector3(0f, -1f, t).normalized *radius); vertList.Add(new Vector3(0f, 1f, t).normalized *radius); vertList.Add(new Vector3(0f, -1f, -t).normalized *radius); vertList.Add(new Vector3(0f, 1f, -t).normalized *radius); vertList.Add(new Vector3(t, 0f, -1f).normalized *radius); vertList.Add(new Vector3(t, 0f, 1f).normalized *radius); vertList.Add(new Vector3(-t, 0f, -1f).normalized *radius); vertList.Add(new Vector3(-t, 0f, 1f).normalized *radius); #endregion #region Face // create 20 triangles of the icosahedron List <TriangleIndices> faces = new List <TriangleIndices>(); // 5 faces around point 0 faces.Add(new TriangleIndices(0, 11, 5)); faces.Add(new TriangleIndices(0, 5, 1)); faces.Add(new TriangleIndices(0, 1, 7)); faces.Add(new TriangleIndices(0, 7, 10)); faces.Add(new TriangleIndices(0, 10, 11)); // 5 adjacent faces faces.Add(new TriangleIndices(1, 5, 9)); faces.Add(new TriangleIndices(5, 11, 4)); faces.Add(new TriangleIndices(11, 10, 2)); faces.Add(new TriangleIndices(10, 7, 6)); faces.Add(new TriangleIndices(7, 1, 8)); // 5 faces around point 3 faces.Add(new TriangleIndices(3, 9, 4)); faces.Add(new TriangleIndices(3, 4, 2)); faces.Add(new TriangleIndices(3, 2, 6)); faces.Add(new TriangleIndices(3, 6, 8)); faces.Add(new TriangleIndices(3, 8, 9)); // 5 adjacent faces faces.Add(new TriangleIndices(4, 9, 5)); faces.Add(new TriangleIndices(2, 4, 11)); faces.Add(new TriangleIndices(6, 2, 10)); faces.Add(new TriangleIndices(8, 6, 7)); faces.Add(new TriangleIndices(9, 8, 1)); #region Refine // refine triangles for (int i = 0; i < recursionLevel; i++) { List <TriangleIndices> faces2 = new List <TriangleIndices>(); foreach (var tri in faces) { // 每個三角形再切成4個三角形 int a = getMiddlePoint(tri.v1, tri.v2, ref vertList, ref middlePointIndexCache, radius); int b = getMiddlePoint(tri.v2, tri.v3, ref vertList, ref middlePointIndexCache, radius); int c = getMiddlePoint(tri.v3, tri.v1, ref vertList, ref middlePointIndexCache, radius); faces2.Add(new TriangleIndices(tri.v1, a, c)); faces2.Add(new TriangleIndices(tri.v2, b, a)); faces2.Add(new TriangleIndices(tri.v3, c, b)); faces2.Add(new TriangleIndices(a, b, c)); } faces = faces2; } #endregion mesh.vertices = vertList.ToArray(); List <int> triList = new List <int>(); for (int i = 0; i < faces.Count; i++) { triList.Add(faces[i].v1); triList.Add(faces[i].v2); triList.Add(faces[i].v3); } mesh.triangles = triList.ToArray(); #endregion #region UVs var nVertices = mesh.vertices; Vector2[] UVs = new Vector2[nVertices.Length]; for (var i = 0; i < nVertices.Length; i++) { var unitVector = nVertices[i].normalized; Vector2 ICOuv = new Vector2(0, 0); ICOuv.x = (Mathf.Atan2(unitVector.x, unitVector.z) + Mathf.PI) / Mathf.PI / 2; ICOuv.y = (Mathf.Acos(unitVector.y) + Mathf.PI) / Mathf.PI - 1; UVs[i] = new Vector2(ICOuv.x, ICOuv.y); } mesh.uv = UVs; #endregion Vector3[] normales = new Vector3[vertList.Count]; for (int i = 0; i < normales.Length; i++) { normales[i] = vertList[i].normalized; } mesh.normals = normales; mesh.RecalculateBounds(); filter.sharedMesh = mesh; mesh.RecalculateBounds(); }
public static float CosLaw(float a, float b, float c) { return(Mathf.Acos(Mathf.Clamp((Mathf.Pow(a, 2) + Mathf.Pow(b, 2.0f) - Mathf.Pow(c, 2.0f)) / (2.0f * a * b), -1.0f, 1.0f)) * Mathf.Rad2Deg); }
// Update is called once per frame void Update() { switch (KeyCheck()) { case 'w': endX += 0.1f; if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) || Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2))) { Debug.Log("Out of range!"); endX -= 0.1f; } break; case 's': endX -= 0.1f; if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) || Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2))) { Debug.Log("Out of range!"); endX += 0.1f; } break; case 'a': endZ += 0.1f; if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) || Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2))) { Debug.Log("Out of range!"); endZ -= 0.1f; } break; case 'd': endZ -= 0.1f; if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) || Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2))) { Debug.Log("Out of range!"); endZ += 0.1f; } break; case 'r': endY += 0.1f; if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) || Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2))) { Debug.Log("Out of range!"); endY -= 0.1f; } break; case 'f': endY -= 0.1f; if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) || Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) || endY - 0.5f <= 0) { Debug.Log("Out of range!"); endY += 0.1f; } break; } EC.transform.localPosition = new Vector3(endX, endY, endZ); /* 逆運動学による姿勢(角度)の計算 */ LenA = Mathf.Sqrt(endX * endX + endZ * endZ) /*endX / Mathf.Cos(Mathf.Atan2(endZ, endX))*/; LenB = (endY - Link1 * 0.5f) * (-1); DegA = Mathf.Acos((LenA * LenA + LenB * LenB - Link2 * Link2 - Link3 * Link3) / (2.0f * Link2 * Link3)); DegB = Mathf.Atan2(Link3 * Mathf.Sin(DegA), Link2 + Link3 * Mathf.Cos(DegA)); DegJ1 = Mathf.Atan2(endZ, endX) * Mathf.Rad2Deg; DegJ2 = Mathf.Asin(LenB / Mathf.Sqrt(LenA * LenA + LenB * LenB) /*(LenA / Mathf.Cos(Mathf.Atan2(LenB, LenA)))*/) * Mathf.Rad2Deg - DegB * Mathf.Rad2Deg; DegJ3 = DegA * Mathf.Rad2Deg; //Debug.Log("J1 = " + DegJ1); //Debug.Log("J2 = " + DegJ2); //Debug.Log("J3 = " + DegJ3); /* 位置 */ RadJ1 = DegJ1 * Mathf.Deg2Rad; RadJ2 = DegJ2 * Mathf.Deg2Rad; PosJ3.x = (Link2 * Mathf.Cos(RadJ2)) * Mathf.Cos(RadJ1); PosJ3.y = (Link2 * Mathf.Sin(RadJ2 * (-1))) + Link1 * 0.5f; PosJ3.z = (Link2 * Mathf.Cos(RadJ2)) * Mathf.Sin(RadJ1); J3.transform.localPosition = PosJ3; /* 姿勢 */ J1.transform.eulerAngles = new Vector3(0, DegJ1 * (-1), 0); J2.transform.eulerAngles = new Vector3(DegJ2 * (-1), DegJ1 * (-1) + (-90), 90); J3.transform.eulerAngles = new Vector3((DegJ2 + DegJ3) * (-1), DegJ1 * (-1) + (-90), 90); EC.transform.eulerAngles = new Vector3(0, DegJ1 * (-1), (DegJ2 + DegJ3) * (-1)); }
void Update() { //Change nolovrmanager's rotation //Double controller press the grip button at the same time if (NoloVR_Controller.GetDevice(NoloDeviceType.LeftController).GetNoloButtonPressed(NoloButtonID.Grip) && NoloVR_Controller.GetDevice(NoloDeviceType.RightController).GetNoloButtonPressed(NoloButtonID.Grip)) { //Record the middle of the two controller controllerCenter.transform.position = new Vector3((rightController.position.x + leftController.position.x) / 2, (rightController.position.y + leftController.position.y) / 2, (rightController.position.z + leftController.position.z) / 2); //Set the parent of the sence object objectParents.SetParent(controllerCenter.transform); //Change scale if (isChangeScale) { distance = Vector3.Distance(leftController.position, rightController.position); if (originDistance < 0) { originDistance = distance; } scaling = preScaling + distance - originDistance; //Min scale 0.1 if (scaling < 0.1f) { scaling = 0.1f; } controllerCenter.transform.localScale = new Vector3(scaling, scaling, scaling); } //Change rotation if (isChangeRotation) { vetor = new Vector3(rightController.localPosition.x - leftController.localPosition.x, 0, rightController.localPosition.z - leftController.localPosition.z); if (preVetor == Vector3.zero) { preVetor = vetor; } float angle = Mathf.Acos(Vector3.Dot(preVetor.normalized, vetor.normalized)) * Mathf.Rad2Deg; //Max rotation angle if (angle > maxAngel) { return; } //Filter illegal numbers if (float.IsNaN(angle)) { return; } if (rightController.localPosition.z - leftController.localPosition.z - preVetor.z > 0) { angle = -angle; } controllerCenter.transform.rotation = Quaternion.Euler(prerotation + new Vector3(0, angle, 0)); } } else { objectParents.SetParent(null); originDistance = -1; preScaling = controllerCenter.transform.localScale.x; preVetor = Vector3.zero; prerotation = controllerCenter.transform.localRotation.eulerAngles; } }
Mesh _CreateMesh() { Mesh mesh = new Mesh(); int hvCount2 = this.segments + 1; int hvCount2Half = hvCount2 / 2; int numVertices = hvCount2 * hvCount2; int numTriangles = this.segments * this.segments * 6; Vector3[] vertices = new Vector3[numVertices]; Vector2[] uvs = new Vector2[numVertices]; int[] triangles = new int[numTriangles]; float scaleFactor = 2.0f / (float)this.segments; float uvFactor = 1.0f / (float)this.segments; if (this.segments <= 1 || this.shape == Shape.Cube) { float ty = 0.0f, py = -1.0f; int index = 0; for (int y = 0; y < hvCount2; ++y, ty += uvFactor, py += scaleFactor) { float tx = 0.0f, px = -1.0f; for (int x = 0; x < hvCount2; ++x, ++index, tx += uvFactor, px += scaleFactor) { vertices[index] = new Vector3(px, py, 1.0f); uvs[index] = new Vector2(tx, ty); } } } else { float ty = 0.0f, py = -1.0f; int index = 0, indexY = 0; for (int y = 0; y <= hvCount2Half; ++y, indexY += hvCount2, ty += uvFactor, py += scaleFactor) { float tx = 0.0f, px = -1.0f, py2 = py * py; int x = 0; for ( ; x <= hvCount2Half; ++x, ++index, tx += uvFactor, px += scaleFactor) { float d = Mathf.Sqrt(px * px + py2 + 1.0f); float theta = Mathf.Acos(1.0f / d); float phi = Mathf.Atan2(py, px); float sinTheta = Mathf.Sin(theta); vertices[index] = new Vector3( sinTheta * Mathf.Cos(phi), sinTheta * Mathf.Sin(phi), Mathf.Cos(theta)); uvs[index] = new Vector2(tx, ty); } int indexX = hvCount2Half - 1; for ( ; x < hvCount2; ++x, ++index, --indexX, tx += uvFactor, px += scaleFactor) { Vector3 v = vertices[indexY + indexX]; vertices[index] = new Vector3(-v.x, v.y, v.z); uvs[index] = new Vector2(tx, ty); } } indexY = (hvCount2Half - 1) * hvCount2; for (int y = hvCount2Half + 1; y < hvCount2; ++y, indexY -= hvCount2, ty += uvFactor, py += scaleFactor) { float tx = 0.0f, px = -1.0f; int x = 0; for ( ; x <= hvCount2Half; ++x, ++index, tx += uvFactor, px += scaleFactor) { Vector3 v = vertices[indexY + x]; vertices[index] = new Vector3(v.x, -v.y, v.z); uvs[index] = new Vector2(tx, ty); } int indexX = hvCount2Half - 1; for ( ; x < hvCount2; ++x, ++index, --indexX, tx += uvFactor, px += scaleFactor) { Vector3 v = vertices[indexY + indexX]; vertices[index] = new Vector3(-v.x, -v.y, v.z); uvs[index] = new Vector2(tx, ty); } } } { for (int y = 0, index = 0, ofst = 0; y < this.segments; ++y, ofst += hvCount2) { int y0 = ofst, y1 = ofst + hvCount2; for (int x = 0; x < this.segments; ++x, index += 6) { triangles[index + 0] = y0 + x; triangles[index + 1] = y1 + x; triangles[index + 2] = y0 + x + 1; triangles[index + 3] = y1 + x; triangles[index + 4] = y1 + x + 1; triangles[index + 5] = y0 + x + 1; } } } mesh.vertices = vertices; mesh.uv = uvs; mesh.triangles = triangles; return(mesh); }
protected void OwnerToTargetAngle() { var diff = owner.position - target.position; Debug.LogFormat("XY Angle is {0}", Mathf.Acos(diff.y / diff.x) * Mathf.Rad2Deg); }
public static float AngleBetween(Vector3 a, Vector3 b) { return(Mathf.Acos(Vector3.Dot(a, b) / (a.magnitude * b.magnitude)) * MathUtil.RAD_TO_DEG); }
public static void makeTacticUpdate() { if (b > 1) { mainStatic.regiment_stat[0].countTypes(); mainStatic.regiment_stat[0].typeSpecification = 0; mainStatic.regiment_stat[0].rebuilding(2); mainStatic.updateRegimentPosition(0); b = 0; } else { for (int i = 0; i < mainStatic.regiment_stat.Count; i++) { for (int r = 0; r < mainStatic.regiment_stat[i].officers.Count; r++) { OfficerStatement.MakeOfficerStatement(i, r); } } } // Очищаем массив со смертями на всяк пожарный DeadBuff.Delete(); ArrowBuff.Delete(); // счетчик смерти на 0 mainStatic.deathcount = 0; // Удаляем пустые места от убитых солдат + проверка на стойкость for (int i = 0; i < mainStatic.regiment_stat.Count; i++) { int t = 0; while (t < mainStatic.regiment_stat[i].soldiers.Count) { if (mainStatic.regiment_stat[i].soldiers[t] == null) { mainStatic.regiment_stat[i].soldiers.RemoveAt(t); } else { t++; } } for (int j = 0; j < mainStatic.regiment_stat[i].soldiers.Count; j++) { mainStatic.regiment_stat[i].soldiers[j].numSoldier = j; } //// Все драки прекращаются. //mainStatic.regiment_stat[i].stateFighting = false; /* Debug.Log("ST"); * Debug.Log(mainStatic.regiment_stat[i].soldier_count); * Debug.Log(mainStatic.regiment_stat[i].prim_soldier_count); */ /// Прохождение теста на панику if (mainStatic.regiment_stat[i].soldier_count < (mainStatic.regiment_stat[i].prim_soldier_count / 2)) { mainStatic.regiment_stat[i].statePanic = true; mainStatic.regiment_stat[i].stateFighting = false; Debug.Log("PANIC"); // В какую сторону побежит? // Направление в которое побежит Vector3 PanicTarget = new Vector3(0, 0, 0); for (int s = 0; s < mainStatic.regiment_stat[i].figthMas.Count; s++) { if (mainStatic.regiment_stat[mainStatic.regiment_stat[i].figthMas[s]].command != mainStatic.regiment_stat[i].command) { //Debug.Log(PanicTarget); PanicTarget += (mainStatic.regiment_stat[i].regPosition - mainStatic.regiment_stat[mainStatic.regiment_stat[i].figthMas[s]].regPosition).normalized; } } PanicTarget = PanicTarget.normalized; //Debug.Log(PanicTarget); float x = PanicTarget.x; float y = PanicTarget.y; float z = PanicTarget.z; // Считаем угол между двумя векторами if (x >= 0 && z >= 0) { mainStatic.regiment_stat[i].angle = Mathf.Acos(z) + 3.1415f / 2; } if (x > 0 && z < 0) { mainStatic.regiment_stat[i].angle = -Mathf.Acos(z) + 3.1415f + 3.1415f / 2; } if (x <= 0 && z <= 0) { mainStatic.regiment_stat[i].angle = Mathf.Acos(z) + 3.1415f + 3.1415f / 2; } if (x < 0 && z > 0) { mainStatic.regiment_stat[i].angle = -Mathf.Acos(-z) + 3.1415f * 2 + 3.1415f / 2; } } if (mainStatic.regiment_stat[i].statePanic == true) { mainStatic.makeRegimentMove(i, 6.0f); mainStatic.updateRegimentPosition(i); } for (int h = 0; h < mainStatic.regiment_stat.Count; h++) { mainStatic.regiment_stat[h].figthMas.Clear(); } //mainStatic.regiment_stat[i].figthMas.Clear(); } UpdateEnReg(); mainStatic.addMeshForBattle(); mainStatic.dellMeshForBattle(); // Формируем в каждом полку fightMas в котором содержатся номера полков, которые участвуют с ним в одной схватке // Для кажого списка for (int y = 0; y < mainStatic.regiment_stat.Count; y++) { mainStatic.regiment_stat[y].figthMas.Clear(); } for (int y = 0; y < mainStatic.listFigReg.Count; y++) { // Для каждого элемента в списке одной схватке for (int r = 0; r < mainStatic.listFigReg[y].M.Count; r++) { // Сравнить с каждым другим for (int w = 0; w < mainStatic.listFigReg[y].M.Count; w++) { if (r != w) { mainStatic.regiment_stat[mainStatic.listFigReg[y].M[r]]. figthMas.Add(mainStatic.listFigReg[y].M[w]); } } } } /// Раздел в котором добавляем точки для навигации солдат во время боя /// Каждый период если полк сражается for (int t = 0; t < mainStatic.regiment_stat.Count; t++) { if (mainStatic.regiment_stat[t].stateFighting == true) { for (int i = 0; i < mainStatic.regiment_stat[t].figthMas.Count; i++) { if (mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].command != mainStatic.regiment_stat[t].command) { mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].make_position(); mainStatic.regiment_stat[t].targPos.Clear(); Vector3 v3 = new Vector3(0, 0, 0); /// Для клина и каре отдельно! if (mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regFirstLine < 6 && mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regLastLine < 8) { v3 = mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[0] + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[1] + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[2] + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[3]; v3 = v3 / 4; if (mainStatic.regiment_stat[t].command == 1) { Debug.Log("HUD"); } mainStatic.regiment_stat[t].targPos.Add(v3); } else { Vector3 v5 = mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[0] + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[1] + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[2] + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[3]; v5 /= 4; mainStatic.regiment_stat[t].targPos.Add(v5); /// Сдвигаемся на 6 в сторону, если там есть солдат, bool fl = true; float j = 6; while (fl == true) { if (j < mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regFirstLine / 2) { v3 = v5 + j * mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regDistanseLine * (mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[1] - mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[0]).normalized; mainStatic.regiment_stat[t].targPos.Add(v3); v3 = v5 - j * mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regDistanseLine * (mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[1] - mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[0]).normalized; mainStatic.regiment_stat[t].targPos.Add(v3); if (mainStatic.regiment_stat[t].command == 1) { Debug.Log("HUD2"); } j += 6; } else { fl = false; } } } } } } } // Найти сражающиеся полки и для каждого солдата участника вызвать атаку for (int t = 0; t < mainStatic.regiment_stat.Count; t++) { if (mainStatic.regiment_stat[t].stateFighting == true) { for (int r = 0; r < mainStatic.regiment_stat[t].soldiers.Count; r++) { mainStatic.regiment_stat[t].soldiers[r].at(); } } } // Сортируем смерти по времени исполения DeadBuff.mySort(); // Сортируем стрелы по времени ArrowBuff.mySort(); // Удалим повторяющиеся mainStatic.t0 = Time.time; for (int t = 0; t < mainStatic.regiment_stat.Count; t++) { if (mainStatic.regiment_stat[t].stateFighting == false) { if (mainStatic.regiment_stat[t].orderForw == true) { mainStatic.makeRegimentMove(t, 1.0f); mainStatic.updateRegimentPosition(t); mainStatic.regiment_stat[t].orderForw = false; } if (mainStatic.regiment_stat[t].orderBack == true) { mainStatic.makeRegimentMove(t, -1.0f); mainStatic.updateRegimentPosition(t); mainStatic.regiment_stat[t].orderBack = false; } if (mainStatic.regiment_stat[t].orderRotW == true) { mainStatic.makeRegimentRotation(t, +.3f); mainStatic.updateRegimentPosition(t); mainStatic.regiment_stat[t].orderRotW = false; mainStatic.regiment_stat[t].delta_angle = 0; } if (mainStatic.regiment_stat[t].orderRotL == true) { mainStatic.makeRegimentRotation(t, -.3f); mainStatic.updateRegimentPosition(t); mainStatic.regiment_stat[t].orderRotL = false; mainStatic.regiment_stat[t].delta_angle = 0; } if (mainStatic.regiment_stat[t].archTotewer == true) { mainStatic.regiment_stat[t].archerAt(t, TactUpdate.nearestReg(t), true); mainStatic.regiment_stat[t].archTotewer = false; } if (mainStatic.regiment_stat[t].archAlone == true) { mainStatic.regiment_stat[t].archerAt(t, TactUpdate.nearestReg(t), false); mainStatic.regiment_stat[t].archAlone = false; } } } }
public void UpdateBoneTransform(int index) { var image = BoneImages[index]; image.TotalRotation = image.MorphRotation * image.Rotation; image.TotalTranslation = image.MorphTranslation + image.Translation; if (image.HasAppend) { if (image.AppendRotate) { image.TotalRotation = image.TotalRotation * Quaternion.Slerp(Quaternion.identity, BoneImages[image.AppendParent].TotalRotation, image.AppendRatio); } if (image.AppendTranslate) { image.TotalTranslation = image.TotalTranslation + image.AppendRatio * BoneImages[image.AppendParent].TotalTranslation; } } if (image.IkLink) { image.PreIkRotation = image.TotalRotation; image.TotalRotation = image.IkRotation * image.TotalRotation; } image.LocalMatrix = MathUtil.QuaternionToMatrix4X4(image.TotalRotation); MathUtil.SetTransToMatrix4X4(image.TotalTranslation + image.LocalOffset, ref image.LocalMatrix); if (image.HasParent) { image.LocalMatrix = BoneImages[image.Parent].LocalMatrix * image.LocalMatrix; } if (!image.HasIk) { return; } var ikLinkNum = image.IkLinks.Length; for (var i = 0; i < ikLinkNum; ++i) { BoneImages[image.IkLinks[i]].IkRotation = Quaternion.identity; } var ikPosition = MathUtil.GetTransFromMatrix4X4(image.LocalMatrix); for (var i = 0; i < ikLinkNum; ++i) { UpdateBoneTransform(image.IkTarget); } var targetPosition = MathUtil.GetTransFromMatrix4X4(BoneImages[image.IkTarget].LocalMatrix); var ikError = ikPosition - targetPosition; if (Vector3.Dot(ikError, ikError) < Tools.MmdMathConstEps) { return; } var ikt = image.CcdIterateLimit / 2; for (var i = 0; i < image.CcdIterateLimit; ++i) { for (var j = 0; j < ikLinkNum; ++j) { if (image.IkFixTypes[j] == BoneImage.AxisFixType.FixAll) { continue; } var ikImage = BoneImages[image.IkLinks[j]]; var ikLinkPosition = MathUtil.GetTransFromMatrix4X4(ikImage.LocalMatrix); var targetDirection = ikLinkPosition - targetPosition; var ikDirection = ikLinkPosition - ikPosition; targetDirection.Normalize(); ikDirection.Normalize(); var ikRotateAxis = Vector3.Cross(targetDirection, ikDirection); for (var k = 0; k < 3; ++k) { if (Math.Abs(ikRotateAxis[k]) < Tools.MmdMathConstEps) { ikRotateAxis[k] = Tools.MmdMathConstEps; } } var localizationMatrix = ikImage.HasParent ? BoneImages[ikImage.Parent].LocalMatrix : Matrix4x4.identity; if (image.IkLinkLimited[j] && image.IkFixTypes[j] != BoneImage.AxisFixType.FixNone && i < ikt) { switch (image.IkFixTypes[j]) { case BoneImage.AxisFixType.FixX: ikRotateAxis.x = Nabs(Vector3.Dot(ikRotateAxis, MathUtil.Matrix4x4ColDowngrade(localizationMatrix, 0))); ikRotateAxis.y = ikRotateAxis.z = 0.0f; break; case BoneImage.AxisFixType.FixY: ikRotateAxis.y = Nabs(Vector3.Dot(ikRotateAxis, MathUtil.Matrix4x4ColDowngrade(localizationMatrix, 1))); ikRotateAxis.x = ikRotateAxis.z = 0.0f; break; case BoneImage.AxisFixType.FixZ: ikRotateAxis.z = Nabs(Vector3.Dot(ikRotateAxis, MathUtil.Matrix4x4ColDowngrade(localizationMatrix, 2))); ikRotateAxis.x = ikRotateAxis.y = 0.0f; break; } } else { ikRotateAxis = Matrix4x4.Transpose(localizationMatrix).MultiplyVector(ikRotateAxis); ikRotateAxis.Normalize(); } var ikRotateAngle = Mathf.Min(Mathf.Acos(Mathf.Clamp(Vector3.Dot(targetDirection, ikDirection), -1.0f, 1.0f)), image.CcdAngleLimit * (j + 1)); ikImage.IkRotation = Quaternion.AngleAxis((float)(ikRotateAngle / Math.PI * 180.0), ikRotateAxis) * ikImage.IkRotation; if (image.IkLinkLimited[j]) { var localRotation = ikImage.IkRotation * ikImage.PreIkRotation; switch (image.IkTransformOrders[j]) { case BoneImage.AxisTransformOrder.OrderZxy: { var eularAngle = MathUtil.QuaternionToZxy(localRotation); eularAngle = LimitEularAngle(eularAngle, image.IkLinkLimitsMin[j], image.IkLinkLimitsMax[j], i < ikt); localRotation = MathUtil.ZxyToQuaternion(eularAngle); break; } case BoneImage.AxisTransformOrder.OrderXyz: { var eularAngle = MathUtil.QuaternionToXyz(localRotation); eularAngle = LimitEularAngle(eularAngle, image.IkLinkLimitsMin[j], image.IkLinkLimitsMax[j], i < ikt); localRotation = MathUtil.XyzToQuaternion(eularAngle); break; } case BoneImage.AxisTransformOrder.OrderYzx: { var eularAngle = MathUtil.QuaternionToYzx(localRotation); eularAngle = LimitEularAngle(eularAngle, image.IkLinkLimitsMin[j], image.IkLinkLimitsMax[j], i < ikt); localRotation = MathUtil.YzxToQuaternion(eularAngle); break; } default: throw new ArgumentOutOfRangeException(); } ikImage.IkRotation = localRotation * Quaternion.Inverse(image.PreIkRotation); } for (var k = 0; k <= j; ++k) { var linkImage = BoneImages[image.IkLinks[j - k]]; linkImage.TotalRotation = linkImage.IkRotation * linkImage.PreIkRotation; linkImage.LocalMatrix = MathUtil.QuaternionToMatrix4X4(linkImage.TotalRotation); MathUtil.SetTransToMatrix4X4(linkImage.TotalTranslation + linkImage.LocalOffset, ref linkImage.LocalMatrix); if (linkImage.HasParent) { linkImage.LocalMatrix = BoneImages[linkImage.Parent].LocalMatrix * linkImage.LocalMatrix; } } UpdateBoneTransform(image.IkTarget); targetPosition = MathUtil.Matrix4x4ColDowngrade(BoneImages[image.IkTarget].LocalMatrix, 3); } ikError = ikPosition - targetPosition; if (Vector3.Dot(ikError, ikError) < Tools.MmdMathConstEps) { return; } } }
void WaitRaycast() { if (Physics.Raycast(ray, out hit, rayLength, sunMask)) { Debug.Log("검출하였습니다."); //시계UI 고정 if (transform != null) { transform.parent = transform.parent.parent; // 부모로부터 상속해제 후 부모와 동일 //transform.rotation = Quaternion.Euler(0, target., 0); //transform.rotation = Quaternion.identity; // 로테이션값 초기화 transform.eulerAngles = new Vector3(-93, transform.eulerAngles.y, transform.eulerAngles.z); //태양 방향의 값으로 평면화 /*rb.constraints = RigidbodyConstraints.FreezeRotationX; * rb.constraints = RigidbodyConstraints.FreezeRotationY; * rb.constraints = RigidbodyConstraints.FreezeRotationZ; * rb.constraints = RigidbodyConstraints.FreezePositionY;*/ } target.GetComponent <Collider>().enabled = false; SN = SliderNumber.Slider_R; //빨간색화살표 생성 m_ArrowSlider[1].gameObject.SetActive(true); currTime = 0; m_ArrowSlider[2].gameObject.SetActive(true); //SN = SliderNumber.Slider_B; //emptyPivot.localRotation = Quaternion.LookRotation(mid); //ok = true; float Dot = Vector3.Dot(handPivot.up, bigWatch.forward); float angle2 = Mathf.Acos(Dot) * Mathf.Rad2Deg; //6시 일 때 남쪽은 6시 if (angle == 6 || angle == 12) { emptyPivot.localEulerAngles = handPivot.localEulerAngles; } /*//12시 일 때 남쪽은 12시 * else if(angle == 12) * { * emptyPivot.localEulerAngles = Vector3.back; * }*/ else if (angle > 6 && angle < 12) { emptyPivot.localEulerAngles = new Vector3(0, 0, -angle2 / 2); } else { emptyPivot.localEulerAngles = new Vector3(0, 0, angle2 / 2); } Destroy(gameObject, 3f); //finalCanvas.SetActive(true); } }
public void CreateIcosphere() { // create 12 vertices of a icosahedron var t = (1.0f + Mathf.Sqrt(5.0f)) / 2.0f; AddVertex(new Vector3(-1, t, 0)); AddVertex(new Vector3(1, t, 0)); AddVertex(new Vector3(-1, -t, 0)); AddVertex(new Vector3(1, -t, 0)); AddVertex(new Vector3(0, -1, t)); AddVertex(new Vector3(0, 1, t)); AddVertex(new Vector3(0, -1, -t)); AddVertex(new Vector3(0, 1, -t)); AddVertex(new Vector3(t, 0, -1)); AddVertex(new Vector3(t, 0, 1)); AddVertex(new Vector3(-t, 0, -1)); AddVertex(new Vector3(-t, 0, 1)); // create 20 triangles of the icosahedron faces = new List <TriangleIndices>(); // 5 faces around point 0 faces.Add(new TriangleIndices(0, 11, 5)); faces.Add(new TriangleIndices(0, 5, 1)); faces.Add(new TriangleIndices(0, 1, 7)); faces.Add(new TriangleIndices(0, 7, 10)); faces.Add(new TriangleIndices(0, 10, 11)); // 5 adjacent faces faces.Add(new TriangleIndices(1, 5, 9)); faces.Add(new TriangleIndices(5, 11, 4)); faces.Add(new TriangleIndices(11, 10, 2)); faces.Add(new TriangleIndices(10, 7, 6)); faces.Add(new TriangleIndices(7, 1, 8)); // 5 faces around point 3 faces.Add(new TriangleIndices(3, 9, 4)); faces.Add(new TriangleIndices(3, 4, 2)); faces.Add(new TriangleIndices(3, 2, 6)); faces.Add(new TriangleIndices(3, 6, 8)); faces.Add(new TriangleIndices(3, 8, 9)); // 5 adjacent faces faces.Add(new TriangleIndices(4, 9, 5)); faces.Add(new TriangleIndices(2, 4, 11)); faces.Add(new TriangleIndices(6, 2, 10)); faces.Add(new TriangleIndices(8, 6, 7)); faces.Add(new TriangleIndices(9, 8, 1)); Subdivide(Subdivisions); // done, now add triangles to mesh foreach (var tri in faces) { indices.Add(tri.v3); indices.Add(tri.v2); indices.Add(tri.v1); } List <Vector2> UVs = new List <Vector2>(); foreach (var v in verts) { var unitVector = v.Normalized(); var ICOuv = Vector2.Zero; ICOuv.x = (Mathf.Atan2(unitVector.x, unitVector.z) + Mathf.Pi) / Mathf.Pi / 2; ICOuv.y = (Mathf.Acos(unitVector.y) + Mathf.Pi) / Mathf.Pi - 1; UVs.Add(new Vector2(ICOuv.x, ICOuv.y)); } uvs = UVs; }
public static int[] Triangulate(Vector2z[] points) { int numberOfPoints = points.Length; List <int> usePoints = new List <int>(); for (int p = 0; p < numberOfPoints; p++) { usePoints.Add(p); } int numberOfUsablePoints = usePoints.Count; List <int> indices = new List <int>(); if (numberOfPoints < 3) { return(indices.ToArray()); } int it = 100; while (numberOfUsablePoints > 3) { for (int i = 0; i < numberOfUsablePoints; i++) { int a, b, c; a = usePoints[i]; if (i >= numberOfUsablePoints - 1) { b = usePoints[0]; } else { b = usePoints[i + 1]; } if (i >= numberOfUsablePoints - 2) { c = usePoints[(i + 2) - numberOfUsablePoints]; } else { c = usePoints[i + 2]; } Vector2 pA = points[b].vector2; Vector2 pB = points[a].vector2; Vector2 pC = points[c].vector2; float dA = Vector2.Distance(pA, pB); float dB = Vector2.Distance(pB, pC); float dC = Vector2.Distance(pC, pA); float angle = Mathf.Acos((Mathf.Pow(dB, 2) - Mathf.Pow(dA, 2) - Mathf.Pow(dC, 2)) / (2 * dA * dC)) * Mathf.Rad2Deg * Mathf.Sign(Sign(points[a], points[b], points[c])); if (angle < 0) { continue;//angle is not reflex } bool freeOfIntersections = true; for (int p = 0; p < numberOfUsablePoints; p++) { int pu = usePoints[p]; if (pu == a || pu == b || pu == c) { continue; } if (IntersectsTriangle2(points[a], points[b], points[c], points[pu])) { freeOfIntersections = false; break; } } if (freeOfIntersections) { indices.Add(a); indices.Add(b); indices.Add(c); usePoints.Remove(b); it = 100; numberOfUsablePoints = usePoints.Count; i--; break; } } it--; if (it < 0) { break; } } indices.Add(usePoints[0]); indices.Add(usePoints[1]); indices.Add(usePoints[2]); indices.Reverse(); return(indices.ToArray()); }
public override void Fill() { if (scatterTexture == null && texturecollider == null) { return; } if (layers.Count == 0) { return; } if (update) { objcount = 0; vertcount = 0; scattercount = 0; Init(); update = false; float totalweight = 0.0f; for (int i = 0; i < layers.Count; i++) { if (layers[i].Enabled) { totalweight = layers[i].Init(totalweight); } } instances.Clear(); // May not be right place totalarea = scatterLength * scatterWidth; int fullcount = (int)(totalarea * Density); if (countmode == MegaScatterMode.Count) { fullcount = forcecount; } for (int m = 0; m < layers.Count; m++) { if (layers[m].Enabled) { int meshcount = (int)(fullcount * (layers[m].weight / totalweight)); if (!layers[m].perCurveCount) { if (layers[m].forcecount != 0) { meshcount = layers[m].forcecount; } if (layers[m].maxcount != 0 && meshcount > layers[m].maxcount) { meshcount = layers[m].maxcount; } } float val = 0.0f; //Random.seed = layers[m].seed + m; if (!meshPerShape) { ClearMesh(layers[m].subcount); } // Do this if want overlap only for each mesh if (layers[m].clearOverlap) { instances.Clear(); // May not be right place } #if UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_6 Random.InitState(seed + layers[m].seed + m); #else Random.seed = seed + layers[m].seed + m; #endif for (int s = 0; s < layers[m].scattercols.Count; s++) { if (meshPerShape) { ClearMesh(layers[m].subcount); } int count = meshcount / layers[m].scattercols.Count; // * (curves[s].area / totalarea)); if (layers[m].perCurveCount) { if (layers[m].forcecount != 0) { count = layers[m].forcecount; } if (layers[m].maxcount != 0 && count > layers[m].maxcount) { count = layers[m].maxcount; } } Vector3 p = Vector3.zero; int failcount = FailCount; for (int i = 0; i < count; i++) { float r1 = Random.value; float r2 = Random.value; float r3 = Random.value; float r4 = Random.value; float r5 = Random.value; float r6 = Random.value; float r7 = Random.value; float r8 = Random.value; float r9 = Random.value; float rc = Random.value; float alpha = Mathf.Clamp01(layers[m].distCrv.Evaluate(r1)); float alpha1 = 0.0f; float alpha2 = 0.0f; Vector3 scl = Vector3.one; if (layers[m].uniformScaling) { Vector3 low = globalScale * layers[m].uniscaleLow; Vector3 high = globalScale * layers[m].uniscaleHigh; //scl = (low + (alpha * (high - low))) * 1.0f * (layers[m].scale); switch (layers[m].uniscalemode) { case MegaScatterScaleMode.XYZ: scl = (low + (alpha * (high - low))) * 1.0f * (layers[m].scale); break; case MegaScatterScaleMode.XY: scl.y = scl.x = (low.x + (alpha * (high.x - low.x))) * 1.0f * (layers[m].scale); scl.z = (low.z + (alpha1 * (high.z - low.z))) * 1.0f * (layers[m].scale); break; case MegaScatterScaleMode.XZ: scl.z = scl.x = (low.x + (alpha * (high.x - low.x))) * 1.0f * (layers[m].scale); scl.y = (low.y + (alpha1 * (high.y - low.y))) * 1.0f * (layers[m].scale); break; case MegaScatterScaleMode.YZ: scl.y = scl.z = (low.x + (alpha * (high.x - low.x))) * 1.0f * (layers[m].scale); scl.x = (low.x + (alpha1 * (high.x - low.x))) * 1.0f * (layers[m].scale); break; } } else { alpha1 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r2)); alpha2 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r3)); Vector3 low = Vector3.Scale(globalScale, layers[m].scaleLow); Vector3 high = Vector3.Scale(globalScale, layers[m].scaleHigh); scl.x = (low.x + (alpha * (high.x - low.x))) * 1.0f * (layers[m].scale); scl.y = (low.y + (alpha1 * (high.y - low.y))) * 1.0f * (layers[m].scale); scl.z = (low.z + (alpha2 * (high.z - low.z))) * 1.0f * (layers[m].scale); } alpha = Mathf.Clamp01(layers[m].distCrv.Evaluate(r4)); alpha1 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r5)); alpha2 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r6)); Vector3 rot = Vector3.zero; rot.x = (layers[m].rotLow.x + (alpha * (layers[m].rotHigh.x - layers[m].rotLow.x))); rot.y = (layers[m].rotLow.y + (alpha * (layers[m].rotHigh.y - layers[m].rotLow.y))); rot.z = (layers[m].rotLow.z + (alpha * (layers[m].rotHigh.z - layers[m].rotLow.z))); rot = Snap(rot, layers[m].snapRot); float distalpha = 0.0f; float maxscale = Mathf.Abs(scl.x); if (Mathf.Abs(scl.z) > maxscale) { maxscale = Mathf.Abs(scl.z); } float rad = layers[m].radius * maxscale; float texscale = 0.0f; if (layers[m].colorTexture != null) { rc = -1.0f; } if (FindPos(m, s, ref p, scl, ref val, rad, ref texscale)) { bool addedmesh = false; alpha = Mathf.Clamp01(layers[m].distCrv.Evaluate(r7)); alpha1 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r8)); alpha2 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r9)); p.x += (layers[m].offsetLow.x + (alpha * (layers[m].offsetHigh.x - layers[m].offsetLow.x))); p.y += (layers[m].offsetLow.y + (alpha1 * (layers[m].offsetHigh.y - layers[m].offsetLow.y))); p.z += (layers[m].offsetLow.z + (alpha2 * (layers[m].offsetHigh.z - layers[m].offsetLow.z))); Vector3 wp = transform.localToWorldMatrix.MultiplyPoint3x4(p); Vector3 lp = transform.worldToLocalMatrix.MultiplyPoint3x4(wp); float texscaleval = Mathf.Lerp(mintexscale, maxtexscale, texscale); if (texscaleval > minsizetoadd) { scl *= layers[m].scaleOnDist.Evaluate(distalpha) * texscaleval; rad *= texscaleval; if (raycast) { //wp.y += 100.0f; if (MultiRayCast(wp, rad * layers[m].colradiusadj, layers[m].raycount)) { RaycastHit hit; Vector3 o = wp; o.y += collisionOffset; if (Physics.Raycast(o, Vector3.down, out hit, raycastheight)) { float ang = Mathf.Acos(Vector3.Dot(hit.normal, Vector3.up)) * Mathf.Rad2Deg; p = hit.point; if (!layers[m].useheight || (p.y <layers[m].maxheight && p.y> layers[m].minheight)) { if (ang >= layers[m].minslope && ang <= layers[m].maxslope) { //p.y += layers[m].collisionOffset * scl.y; p = transform.worldToLocalMatrix.MultiplyPoint3x4(p); Vector3 hn = transform.worldToLocalMatrix.MultiplyVector(hit.normal); Vector3 newup = Vector3.Lerp(Vector3.up, hn, layers[m].align).normalized; p += newup * (layers[m].collisionOffset * scl.y); Quaternion align = Quaternion.FromToRotation(Vector3.up, newup); layers[m].AddSM(this, p, scl, rot, align, rc, texturecol); addedmesh = true; } } } } else { if (!NeedsGround) { layers[m].AddSM(this, lp, scl, rot, Quaternion.identity, rc, texturecol); addedmesh = true; } } } else { layers[m].AddSM(this, lp, scl, rot, Quaternion.identity, rc, texturecol); addedmesh = true; } } if (!addedmesh) { i--; failcount--; if (failcount < 0) { break; } } } } if (meshPerShape) { BuildMeshNew(layers[m]); } } if (!meshPerShape) { BuildMeshNew(layers[m]); } } } RestoreColliders(); if (dostaticbatching) { StaticBatchingUtility.Combine(gameObject); } } }
// For computing of Frenet frames, exposing the tangents, normals and binormals the spline public FrenetFrames(Curve path, int segments, bool closed) { //Vector3 tangent = new Vector3 (); Vector3 normal = new Vector3(); //Vector3 binormal = new Vector3 (); Vector3 vec = new Vector3(); //Matrix4x4 mat = new Matrix4x4 (); int numpoints = segments + 1; float theta; float epsilon = THREE.Setting.EPSILON_S; float smallest; float tx, ty, tz; float u; //float v; List <Vector3> tangents = new List <Vector3> (new Vector3[numpoints]); List <Vector3> normals = new List <Vector3> (new Vector3[numpoints]); List <Vector3> binormals = new List <Vector3> (new Vector3[numpoints]); //vecs = new List<Vector3>(new Vector3[numpoints]); // expose internals this.tangents = tangents; this.normals = normals; this.binormals = binormals; // compute the tangent vectors for each segment on the path for (int i = 0; i < numpoints; i++) { u = (float)i / (numpoints - 1); // tangents [i] = path.getTangentAt(u); // tangents [i].Normalize (); Vector3 t_vec = path.getTangentAt(u); t_vec.Normalize(); //tangents.Add( t_vec ); tangents[i] = (t_vec); } //initialNormal3(); //void initialNormal3() { // select an initial normal vector perpenicular to the first tangent vector, // and in the direction of the smallest tangent xyz component normals.Add(new Vector3()); binormals.Add(new Vector3()); smallest = Mathf.Infinity; tx = Mathf.Abs(tangents [0].x); ty = Mathf.Abs(tangents [0].y); tz = Mathf.Abs(tangents [0].z); if (tx <= smallest) { smallest = tx; normal = new Vector3(1, 0, 0); } if (ty <= smallest) { smallest = ty; normal = new Vector3(0, 1, 0); } if (tz <= smallest) { normal = new Vector3(0, 0, 1); } vec = Vector3.Cross(tangents [0], normal).normalized; //vec.crossVectors( tangents[ 0 ], normal ).normalize(); // normals[ 0 ].crossVectors( tangents[ 0 ], vec ); // binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] ); //normals.Add( Vector3.Cross (tangents [0], vec) ); //binormals.Add(Vector3.Cross (tangents [0], normals [0])); normals[0] = (Vector3.Cross(tangents [0], vec)); binormals[0] = (Vector3.Cross(tangents [0], normals [0])); //} // compute the slowly-varying normal and binormal vectors for each segment on the path // js233 for (int i = 1; i < numpoints; i++) { // normals.Add( clone (normals [i - 1]) ); // binormals.Add( clone (binormals [i - 1]) ); normals[i] = clone(normals [i - 1]); binormals[i] = clone(binormals [i - 1]); //vec.crossVectors( tangents[ i-1 ], tangents[ i ] ); vec = Vector3.Cross(tangents [i - 1], tangents [i]); if (vec.magnitude > epsilon) { vec.Normalize(); //theta = Mathf.Acos( Mathf.Clamp( tangents[ i-1 ].dot( tangents[ i ] ), -1, 1 ) ); // clamp for floating pt errors float dot = Vector3.Dot(tangents [i - 1], tangents [i]); theta = Mathf.Acos(Mathf.Clamp(dot, -1, 1)); // clamp for floating pt errors //normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); Quaternion rot = Quaternion.AngleAxis(Mathf.Rad2Deg * (theta), vec); normals [i] = rot * normals [i]; //vecs[i] = vec; } //binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); binormals [i] = Vector3.Cross(tangents [i], normals [i]); } // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same if (closed) { Debug.LogWarning("close---------"); float dot = Vector3.Dot(normals [0], normals [numpoints - 1]); theta = Mathf.Acos(Mathf.Clamp(dot, -1, 1)); theta /= (float)(numpoints - 1); Vector3 vec0 = Vector3.Cross(normals [0], normals [numpoints - 1]); float dot0 = Vector3.Dot(tangents [0], vec0); if (dot0 > 0) { //if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ numpoints-1 ] ) ) > 0 ) { theta = -theta; } for (int i = 1; i < numpoints; i++) { // twist a little... //normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) ); //binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); Quaternion rot = Quaternion.AngleAxis(Mathf.Rad2Deg * (theta * i), tangents [i]); normals [i] = rot * normals [i]; binormals [i] = Vector3.Cross(tangents [i], normals [i]); } } }